売春処女プアプアが家庭的アイウエオを行う

完全参照リスト管理とUNDOシステムが共存する体勢を確立することは,参照リスト管理を恒常的なシステムの一部として仕様化するための第一歩だ.「UNDOで参照リスト管理と参照カウントの不一致が発生する」という問題が起きているが,いよいよ大詰めの段階に差し掛かった.これを解決できればZTは「超クリーンなシステム」に変容するための準備が整ったことになる.「超クリーンなシステム」とは「グラスクリーンな世界」であり,ZTが追求する誰にも踏まれていない純白な処女雪に覆われた「スノーホワイトの世界」である.

プログラミングの世界には「オリジナルバージョンに戻る」ことを意味するvirginize(処女化/童貞化)という用語が存在する(わたしも知らなかった).virginizeとは具体的にはバックアップに戻ること,ないし条件コンパイルマクロをオフにして修正前の状態に戻すことに相当するが,基本的には「修正が取り返しが付かない程度に間違った方向に進んでいるとき,それまでの経緯をすべて捨てて振り出しに戻ること」と解釈するのが妥当である.実際,プログラミングでは「これを修正してすべてのバグを取り除くより一から作り直した方が早い」という局面があることは広く認知されている(最初にそれを言い出したのはIBMだ).

いま出ている障害の一因としてTRASHCAN::ReuseWasteで廃棄オブジェクトをリサイクルするときの初期化が不十分というより,まったく実行されていないという問題が出てきた.これを解決するために,新規メモリブロックを使い始めるときと同様に固有データ部を完全にゼロクリアし,すべてのスロットを空にすることにした.これは言ってみればrevirginize(処女膜再生)の施術に相当する.プログラマというのは言ってみれば白雪姫に仕える七人のこびとであったのかもしれない…

ZTシステム構成図7.ZELの全体図を#1 couplingで開き,この基準カードを削除すると,UNDONODE #115359の持っているNODEREFLIST #115361がMARGLINK #311に乗り移るという事象が起きている.これは,カード削除コマンド実行後のUNDOBASE::CommandEndで起きている.何が起きているのか?実に興味深いところだ.

障害はUNDOBASE::SetUndoList→ UNDOBASE::SetUndoList→ ReferenceControlで起きている.UNDONODE #115245の枝2にUNDONODE #115359への参照を設定しようとしているところだ.#115359は参照リストを持っていないので,新たに生成された参照リストがNODEREFLIST #11536だ.このオブジェクトは再生品だ.⇒しかし,NODEREFLISTがリサイクルに回っているということ自体おかしい.NODEREFLISTはENDOFAPPLICATIONフェーズ以外では削除されないことになっているからだ.この時点ではMARGLINK #311はPROLONG状態でNring上に存在する.参照リストは持っていない.

いや,ちょっと間違えていた.SWO(SearchWrongObject)の条件設定でANDとすべきところがORになっていた.⇒障害はやはり,UNDOBASE::UndoCopyで起きている.ここではShadowから実ノードにオブジェクトイメージをコピーしているので,確かにそのようなことは起こり得る.実ノードが参照リストを持たないとしても,イメージにはそれが残っている可能性はある.というか,実際そのような動作になっている.しかし,上記のようにNODEREFLIST #11536はリサイクルされているので,ダブリが生じたということだろう.

問題はNODEREFLISTがゴミ箱に入っているという点だ.#11536はリサイクル時に付番されているので,それ以前の通番は上書きされてしまっている.⇒#2726だったようだ.⇒nodule::~noduleの末尾に「countゼロの参照リストを削除する@20201214」というのが入っている.countゼロの参照リストは保持していても意味がないので始末するという趣旨と思われるが,PROLONGされたノードの場合は除外されなくてはならない.⇒対処した.これですべてのエラーは解消した.つまり,完全参照リスト管理とUNDOシステムの共存は実現された.

ただし,UNDO/REDOを実行したとき,~noduleで参照リストカウントが残っているという現象がある.~noduleの段階ではすべての参照はクリアされていることになっていたはずだ… ⇒現状ではCLEARTABLEフェーズでは参照管理を放棄した状態になっている.CLEARTABLEを含むすべてのフェーズで完全な参照管理を実現するのはまだ先の話だ.

UNDOでは参照カウント不一致のエラーはまったく表示されないのに,REDOではかなりのエラーが出ている.UNDO/REDOには直接関係しない描画要素(NAMEBOX, MARBOXなど)なので放置でも実害はないが… カウント差はほとんど1なので押さえることも可能ではないか?

REDOではMARGLINK:#311とCARDLINK:#689が削除されている.これらからの参照が処理されていないのではないか?⇒どうもそういうことのようだ.⇒この問題を解決するには,やはり参照管理を徹底する以外ない.まず,~noduleで参照リストカウントゼロの場合に(UNDO保全オブジェクト以外では)参照リストを削除するとしていたのを廃止し,参照リストは原則として「死んでも付いて回る」ものとした.

ただし,ゴミ箱に入っている参照リストの親オブジェクトがリサイクルされる場合には削除される.~NODEREFLISTでは参照リストカウントが残っている場合には停止するようにした.この結果,CARDLINK #689[6]→ NAMEBOX #690の参照が残っていることが判明した.

しかし,CARDLINK #689[6]にはNAMEBOX:#243582が入っている.NAMEBOX #690はすでにゴミ箱に入っているが,CARDLINK #689は生きている.というか,UNDOで復活したものと思われる.これは何が悪いのか?CARDLINK #689が削除されたとき,NAMEBOX #690が参照解除されていなかったものと思われる.いや,かなりおかしい.CARDLINK[6]というのは参照ではなく,接続のはずだ.

image

!解けた!一日一個の禁令を破ってここぞとばかり,全量投下の勝負を賭けてみた.有り金を賭ける賭博師の心境だ.チョコレートパワーの威力だね.いや,最初の一個で解けたよ!エラーは全部きれいに消えた!

UNDONODE::UndoCopyでは参照カウントと参照リストカウントの差分を調整するため,復元されたオブジェクトの全参照スロットを対象にReferenceControlで参照リスト登録を実施している.問題はこのとき,「接続」と「参照」を切り分けなくてはならないという点だ.

通常はリンクされているオブジェクトを見れば判定できるのだが,いまの場合,NAMEBOX #690はすでに死亡しているため,接続モードを確認することができない.このような場合にはそのノードの存否をチェックするようにして解決した.このスロットはこの後,UNDOBASE:RestoreShadowでアクティブな現物ノードによって置き換えられている.漏れを防ぐために~noduleでNODEREFLISTの参照リストカウントがゼロになっていることを確認するようにしておこう.

上記と同様の操作(#1削除→UNDO→REDO)でNODEREFLISTのデストラクタで参照リストカウントの残留により停止した.親オブジェクトはすでに死亡しているNAMEBOX #322244でCARDLINK #689からの参照が残っている.#689[6]は空になっている.

CARDLINK[6]は接続スロットだから,参照リストに入っていることがそもそもの間違いだ.⇒どうもかなり難しい話になってきた.NAMEBOX #322244はリサイクルされた再生品という以外は特に問題のないオブジェクトだ.DELETEDはEXISTINGになっているので,弾くこともできない.いや,確かにおかしいところはある.このノードの親はNAMEBOXになっている.確かに,NAMEBOXはリスト構造で保持されているので,親がNAMEBOXというのは当たり前だが,CARDLINK[6]にリンクするためには接続しなくてはならないはずだ.

UndoCopyではそうなっていないのは仕方ないとしても,事後の調整というのがあるはずだ.本当は,その事後調整を実施したあとで,ReferenceControlの調整を行うべきなのではないだろうか?多分それしかないような気はするが,問題はUNDONODE::UndoCopyを呼び出しているUndoRestoreはUNDOSYSTEMの関数だという点だ.つまり,アプリ依存コードなので,UNDOBASEでできる範囲がより狭まってしまうということになる.⇒UNDONODE::SetNodeRefListという関数を作ってUndoRestoreから呼び出すようにしてみよう.

いや,もっといい場所がある.CountupReferenceという関数がある.ここでは参照カウントのインクリメントを実施している.それと同時にReferenceControlをやればよい.というか,ここではSansyoの取り直しを実施するというのが一番適切なのではないか?⇒完璧だ!傷跡も残らないくらいの完璧なサージェリィ,これ以上付け加えるものも引き去るものもないという感じになってきた.バックアップを取っておこう.

以下のブロックを選択して最初のカードを削除してエラーが発生した

image

@4 treeviewを削除で再現できる.PAIRBOX::CalcPairBoxでエラーが起きている.「NOCOMMONPAIRノード対は端点共有束で唯一でなくてはならない@20180915」というエラーだ.NOCOMMONPAIRは「終点がgoodsonのノード対は最大区間を除き端点共有不可@2018-09-04」とされている.このトラブルは既出だが,もう少し整理する必要がある.エラーを無視して描画は可能.出口検査はパスしているので,ここでは停止しないようにしておこう.

▲NOCOMMONPAIRノード対の論理を整理する.端点共有ノード対の場合は,NOCOMMONPAIRをつねにリスト先頭に配置するというのがわかり易いのではないか?

複数回のカード削除の後,UNDOで「フェーズのイレギュラーな遷移」が起きた.TOPOLOGICALSORTからINITIALIZEDに遷移しようとしている.⇒COUPLING::TopologicalSortの冒頭でSetPhase(TOPOLOGICALSORT)の後にTREEVIEW::SetDispParmを実行している.これはAUTOCHANNELのときの既定チャンネル数を設定するためだが,SetDispParmの中でフェーズの切り替えが発生している.これを避けるために,この操作はRESTOREDCIRCULATIONの前に移動する.

同様の動作テスト中,Bobject::setparentでエラーを表示しようとして例外が発生した.bprintfの引数に修正ミスがあった.

仮修正をフィックスしておこう.3件ある.

  1. UndoCopyでSansyo動作を実行@20201222 → 廃止
  2. オブジェクト削除で参照カウントゼロを確認@20201223 2箇所
  3. Bobject:initializeでCleanSlotする@20201223 → 廃止

仮修正17箇所,#ifdef ,#ifndefも一掃した.

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA