「参照カウント不一致」エラーは一応解決

UNDOにからんで「参照カウント不一致」という不良が出ている.参照とは,オブジェクトへのリンクを格納したスロットを言う.ゼルコバの木では処理効率の観点からリンクには生ポインタを使っているので,リンク先のオブジェクトの削除などで無効になったリンクにアクセスしようとすると,致命的な事故が発生することになるので,システムを安定運用するためには超厳密な参照管理が必須である.このために参照カウントというパラメータを保持しているが,現行システムにはそれを管理するためのREFERENCECONTROLという機構が組み込まれている.従って,このエラーの発生は決して許されない極めて深刻な障害と言える.

動作確認のために入れた仮修正によって別の障害が発生している.基準ソートを実行して,TOPOLOGY::ClearTableで結婚リンクの参照番号と親番号の不一致が起きている.⇒仕様的には結婚リンクの参照番号と親番号が一致するというのは仕様ではないはずだが,事実上そうなっていることは確かだろう.⇒暫定的にエラーで停止しないようにした.

スロットの接続種別を取り出すNODULE::slottypeで,親番号とスロット番号が一致しない場合でも,親参照が一致していればSLOT_LINKを返すように暫定修正して,参照カウント不一致は発生しないようになったが,いろいろ問題がある.

  1. ほとんどの場合はこれで問題なかったとしても,同じオブジェクトが接続しながら参照されているような場合を排除できない
  2. リンクテーブル内のリンクはすべて接続であるとして処理されるべきではないか?つまり,対象オブジェクトごとに個別対応する必要があるのではないか?
  3. 親番号とスロット番号の不一致は不良とみなされるべきであり,イメージをリストアした時点で対処されなくてはならないのでは?処理する場所はCountupReferenceでもよいのかもしれないが…
  4. カードリンクと結婚リンクはUNDOSYSTEM::RestoreShadowでInsertLinkされる.ただし,これは現物オブジェクトがEXISTINGでない場合に限られる.つまり,Nring上で延命している場合にのみ適用される
  5. UNDONODE::CountupReferenceとUndoCopyの2箇所で参照の復元を実施している.これは必要なのか?これらはいずれもUNDOSYSTEM:UndoRestoreの内部で呼ばれている.どちらかのみでよいような気もする.UNDOBASE:UndoRestoreでも同様処理になっている.⇒いや,やっていることは真逆だ.UndoCopyでは対象オブジェクトのすべての参照を解除している.逆にCountupReferenceは参照設定を実施している.この動作は正しいと思われる.

▲基準ソート→Undo→Redoの後,まとめて全削除→UndoしてUNDOSYSTEM::UndoProcessでRebuildCardListしたとき,(previous != treeview->selectcardlist->count)になった.previousは1で実カウントは77.⇒これはエラーではなくむしろノーマルな動作のように思われる.カード削除の前に戻ったとき,削除対象カードが選択状態になっているという方が正しい.従って,ここでは不一致をエラーとしないというのでよいと思われる.⇒いや,このエラーのタイミングでは選択リストはすでに復元されているはずなので,それと一致しないというのはおかしいのではないか?

全削除コマンドが実行されたとき,どのタイミングで選択カードリストが保全されたかが問題だ.コマンド実行後に更新されたオブジェクトがあれば上書き保全するということもやっているのではないか?カードの全削除は単点削除の反復として実装されているはずだから,削除完了時に1点選択の状態になっていてもおかしくない.⇒これはそれほど大きな問題ではないので保留とし,エラーで停止しないようにしておこう.

さて,これで一応「参照カウント不一致」エラーは発生しないようになったが,まだ,もう少し問題が残っている.対象リンクが参照でない場合(接続の場合),CountupReferenceでは何もしていないが,「親番号とスロット番号の不一致」が起こっているのではないか?⇒UNDONODE::CountupReferenceで「親番と枝番の不一致」が起きた場合には強制的に調整するようにした.

まだ,「参照カウント不一致」が収まっていない.UndoRedo→ TopologicalSort→ EraseTreeViewで起きている.基準ソート→Undo→Redo→Undoで起きる.⇒親ノードに接続している場合は,つねに接続リンクとして扱う以外ないということになった.

「オブジェクトが接続している親ノードからは参照されない」

というルールを公理化することができれば,これでもよいのだが… 果たしてそう断言できるだろうか?実質的にはこれに反するケースというのはおそらく存在しないのではないかとは思われるのだが… 安全のためには,やはり,オブジェクトの種別を特定して対応を変えるしかないような気がする.⇒人名テーブルと結婚テーブルについては,IsReferenceを使わないよう対処した.それ以外は既存論理で対応する.

ここで一度バックアップを取っておこう.レコード番号には,①リンクテーブルのレコード番号,②lookupテーブルのレコード番号の二種がある.これらを峻別しなくてはならない.特に①はprivateとし,外部からアクセスできないようにする必要がある.⇒maxrecnumとmaxrefnumは元々privateになっている.一旦破棄された一昨日の修正をログに従って復旧してみよう.⇒ZELKOVA 2022-12-27 BADというバックアップがあるので,参照しながら進めよう.

  1. maxrecnumをrecordcountにリネーム→有効レコードカウント
  2. recordcountは lookup テーブルの count に等しい
  3. maxrecordを新設し,最大(リンク)レコード番号を格納する
  4. recordcountの更新時に,maxrecordも更新する.
  5. maxrecordは単調に増加するものとし,(基準ソート時以外では)テーブルは縮小されない
  6. getmaxrecnではmaxrecordを返す
  7. maxrecordのアクセス関数をmaxRecordとする
  8. _maxrecnをリネームしてrecordCountとする
  9. getmaxrecnを廃止して,maxRecordに統一する

ダメだ!また,被参照カウント不一致が出てしまった.基準ソート→ Undo→ Redo→ Undo→ 一括削除→ Undoという手順だ.出ている時点は同じだが,今度はNAMEBOXのデストラクタで起きている.被参照カウントの残留も発生する.⇒CHECKREMAINSANSYOは一時止めておこう.⇒起動→ ルートノード削除→ Undoで再現する.これまで出ていなかったので,上の修正で作り込まれたものと思われる.⇒修正を一部戻してテストしてみたが同じだ.もう一度バックアップに戻るしかない.⇒いや,ダメだ.バックアップでも障害は起きている.

TREEVIEW::EraseTreeViewの入口ですでに不良は発生している.⇒UNDONODE::UndoCopy→ UNDOBASE::UndoCopyで起きているが,UndoCopyでは単にイメージを上書きしているだけなので,そうなることは避けられない.その部分はCountupReferenceで補正しているのだが,どうもそれだけではカバーできないということのようだ.最初の障害は#1540のCARDLINKで起きる.参照カウント不一致が起きているのは#80のMARGLINKだ.この結婚の夫が#1540で削除された@35のカードと思われる.⇒いや,読み違えている.

削除されたのは@23#1522のカードで,同時に#74のMARGLINKも削除されている.この2つは<再生>されているが,MARGLINK内の夫ないし子ノードのリンクは修復されていないようだ.

コメントを残す

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

CAPTCHA