われ 男の子 意気の子 名の子 剣の子

昨日はプチ宴会でお休み.今日が仕事始めだ.通常なら100本くらい入ってくるメールが今日はたったの2本しかなかった.昨日はそれでもまだ30本くらいはあったのだが… 昨日は飲み会(と言っても飲めるのはほとんどわたしだけ)から帰ったあと,Your Daily Epsilon of Math を投稿した.三日坊主で終わるのか,365本まで投稿して皆勤賞をもらえるかどうかは今のところ分からないが.まぁ,続けられるだけやってみよう.高校の卒業アルバムを弟が発掘してくれていたので,持ち帰った.わたしにも「少年時代」というのがあったのだ!アルバムの余白の寄せ書きの中にわたしの手で書いたこんな短歌が挿入されていた.

われ 男の子 意気の子 名の子 剣の子
詩の子 恋の子 ああ,もだえの子

誰の歌だろう?わたしが書いたのだろうか?確かに,この気分はわたしのものだが,わたしのボキャブラリの中には「剣の子」というのはなかったような気もする.気になって部屋に戻ってから調べたら,与謝野鉄幹の歌だった.確かに,これを読むとわたし自身の中に(父親から引き継いだ)「明治」のフレーバーが残っているのを感じる.

https://www.facebook.com/age.baba.5/posts/pfbid02RVMSuXJXTro94cRXvQ2j6NRJqVW8Nwtmf3Kurm8UnAgAD89xVu89jLk6vAYuBhA6l

▲極小反例307.ZELを開いて,再現リストの項目5の手順でUndoProcess→ UndoRestore→ UNDONODE::UndoCopy→ UNDOBASE::UndoCopyを実行後に置いたCheckDataLinkでカード参照番号の重複エラーが検出される.⇒動作確認のために動作をアレンジしている箇所があったが,外しても同じ.UndoRestoreはループ中の動作なので,一時的な不整合が生じる可能性は考えられるが,UndoProcessの出口でも同じエラーが発生する.

この2つのカードリンクはオブジェクトとしては別物で,PDB[48]に入っているのは「47」というカード,PDB[7937]に入っているのは「16129」というカードだ.参照番号はいずれも48.しかし,ファイルを開いたときのカード数は307点しかないのだから,7937などという場所に有効なカードが存在すること自体間違っているのではないだろうか?⇒いや,名前でハッシングしているので,リンクはテーブル上では離散的な配置になっているから,あり得ないことではない.⇒実際「16129」というカードは存在する.

ファイルオープン時にはこのカードは一覧表の先頭にある.参照番号は7937だ.「47」というカードの参照番号は48で,テーブルの末尾にある.ここまでは問題ないようだ.⇒いや,これは一度基準ソートした結果の場合だ.起動時では「16129」はテーブル先頭から5番目の位置にある.また,「47」は下から5番目だ.⇒基準ソートでは,この順序が逆転しているだけで,位置的には正しい.つまり,「47」が上から5番目,「16129」は下から5番目だ.

Undoでこの順序は元に戻るが,参照番号が変化してしまっている.「47」は7937に,「16129」は48に入れ替わっている.どうも,この最初のUndoがデタラメな動作になっているような感じだ.参照番号は確かにソート→Undoになっているが,中身の順序がバラバラに壊れている.Renumberというのは必須の動作だったのだろうか?⇒いや,ちょっと混乱しているかも.参照番号は離散値ではあるが,整列している(起動時は降順)が,名前順にはなっていない.頭の方を拾い出すと,

8113, 24421, 8021, 32561, 16129, 7811, 7793

のようになっている.末尾の並びは,下から,

23, 31, 35, 41, 47, 61, 71, 83, 16469

だ.ソートは問題なく動作している.Undoも正しく動作している.従って,ここまでの動作には問題はない.カードの一括削除の対象に入っているのかどうかが問題だ.「47」は残っている.参照番号は7937.「16129」は削除されている.どうも,このカード削除の動作がおかしい.カード削除によって参照番号の入れ替えが発生しているように思われる.元々の状態は,「47」が#48,「16129」が#7937だ.

別の不良が見つかった.最初にソート→Undoという手順を省いて,いきなり一括削除→ Undoでは順序の問題は発生しないが,「被参照カウント不一致」が大量発生する.こちらのバグの方が易しそうに思われるので,先にこちらを片付けておくことにしよう.このエラーはEraseTreeView→ ~NAMEBOX→ CleanSlot→ clearSlotで発生する.

NODULE::slottypeという関数は少し書き換えているので動作確認が必要だ.nodule::CheckSansyoCountという検査関数はNリング上のすべてのノードの参照カウントをチェックする.この関数の中で参照ではないと判断されたリンクが参照リストに記載されている可能性があるので検出できるようにしたところ,TRIBEBOXの参照リストにTRIBELIST→ TRIBEBOXという接続リンクが入っているのが見つかった.

TRIBEBOX *starttribeは「基準ノードの属する始系列への参照」となっている.TRIBELISTはNLISTの派生クラスであり,LISTNODEクラスのオブジェクトのリストということになっている.NLIST→ LIST→ DATALISTの継承関係があるが,listtopは「リスト先頭ノード接続用スロット」となっている.つまり,TRIBELSITの先頭TRIBEBOXはlisttopに接続しているはずだ.いや,starttribeというのはこれとはまた別のスロットだろう.これは結局,TRIBELISTでは先頭TRIBEBOXが接続され,かつ,そのオブジェクトへの参照も保持している,つまり,同じ値を持つ複数のスロットがあるということではないだろうか?

このような重複リンクは合法であり,それを禁止するとかなり窮屈な仕様になってしまうような気もするが,DATALIST::listtopが接続であるとすれば,むしろ,アンカー接続として地の部分にスロットを設けた方がよかったのではないだろうか?これはかなり厄介な外科手術になってしまう可能性があるので,ここではパスするしかない.ベタ参照にしてしまうと管理上いろいろと厄介な話も持ち上がってきそうな気がする…

参照リストのリストノードは参照元リンクと参照元のスロット位置が入っている.従って,重複リンクのいずれかを誤認しているという訳ではないが,スロット番号だけでは接続用であるか参照用であるのかを判定することはできない.いや,そんなことはない.やはり,今の場合「スロットタイプ不整合」が成立しているのではないか?DATALISTsTOPLIST=1であり,TRIBELISTsSTARTTRIBE=2のはずだから,TRIBELIST[2]は参照でなくてはならないはずだ…

スロット2というのは,LIST::LISTsBOTTOMに相当する.従って,スロット2は接続ではなく,参照でなくてはならない.slottypeが間違っているのだろうか?⇒@20221229で「枝番号と親番号が一致しない場合を許容する」という仕様変更を行っているので,参照を接続と誤認する事態が発生しているように思われる.⇒この変更は,「参照カウント不一致」を伴う「UndoCopyで参照元ノードリスト不記載」に対処したものと思われるが,やはり問題がありそうだ.

slottypeの変更を破棄し,オリジナルに復帰することにした.これで,このエラーは発生しなくなったが,slottypeの変更が必要になった時点まで巻き戻さなくてはならない.その前に,また別のエラーが出ているのでそちらを先に片付けることにする.

▲ブロック削除→ Undo→ Redoで「被参照カウントの残留」が発生する.⇒UndoProcess→ ~CARDLINK→~noduleで起きている.#1612のCARDLINKだ.おそらく,削除範囲に含まれるカードだろう.残留カウントは2.nodule::TakeSansyoでは,参照カウントが残っている場合には,nodule::takeSansyoで除去できるようになっているのだが,補修できなかったようだ.

それ以前に最初のUndoを実行した時点でnodule:ReferenceControlの参照リストx参照カウント 不一致が発生している.これはまずいのではないか?⇒UndoProcessの出口でTopologicalSortを実行する直前ですでに被参照カウント不一致が量産されている.すべてMARGLINKだ.⇒参照リストの長さの方が,参照カウントより2以上小さいという状態になっている.これらはおそらくUndoによって復活したリンクだろう.参照カウントは強制的に調整していたのではないだろうか?いや,そもそも,この値は一致しないということもあるのではないか?

コメントを残す

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

CAPTCHA