バックアップがネズミ講的に増大する

ある特定のサンプルでループカウントオーバーが発生する.この問題に対処するために,「極小反例サンプル」を自動抽出するという試みに取り組んでいるところだ.すでに実稼働する状態になっているが,1232点まで圧縮したところで例外が発生している.UNDOBASE::CommandEndでエラーが発生している模様だが,そのままアボートしている.⇒同じサンプルから開始したつもりだが,再現しない.まだそのポイントまで進んでいないのだろうか?

▲TribeRelocation→ StackTribeGene→ setcompleteで (!OnCompleteTribeBox && val && CheckMaximalSegment(funcname) > 1)で停止した.レッドラインオーバーで抜けているためだが,なぜ,これまで停止していなかったのか?という方がむしろ疑問だ.⇒ループカウントオーバーではつねに偽を返すように修正した.

まだ多少不具合は残っているが,走行中の極小反例サンプル生成ツールは550点の反例サンプルを出力した.

image

だいぶイメージに近付いてきた.修正を入れたあと検定再開して371点まで削減したところで,カード削除が空振りのときのUNDO処理でやけに時間が掛かるようになった.理由はわからない.nodule::ReferenceControlで時間が掛かっているのかもしれない.⇒UNDOオブジェクトの大量発生が再発しているのではないだろうか?

極小反例 371.zelをツールに仕掛けて,#32のカードを削除して,CARDLINK #1905 のデストラクタの中で「被参照カウントの残留」が発生した.45個も残っている.参照元はMARGBOXだ.⇒この「被参照カウントの残留」はUNDOの不良にも関係しているかもしれない.⇒いや,UNDOの不良はその次に削除された#41のカードについて発生している.確かに,UNDOのどこかが壊れてしまったことは確かであるように思われる.⇒UNDOの事象が発生するのはずっと後の#809のカードだ.このノードは1204個ものバックアップオブジェクトを抱えている.なぜこんなことが起きているのだろう?そのほとんどはCARDLINKだが,MARGLINKも一定程度混ざっている.これらは,UNDOCOMMAND #16923301にぶら下がっている.コマンドはDELALLCARDだ.しかし,このカードは単点削除されているように見えるのだが…

▲#809のカードを削除→UNDOでDELALLCARDが復元されている.このコマンドは1204個のバックアップオブジェクトを持っている.コマンドオブジェクトはUNDOCOMMAND #16923301.その前に,#804カードの削除でも類似の事象が発生している.UNDOCOMMAND #16923301.これもおかしい.UNDOCOMMAND が同じ番号を持っている.その前にもう一つ.#791カードというのがある.⇒いや,そもそもシステムの動き自体おかしい.デバッガのダンプテキストをコピーしてテキストエディタに貼り付けようとしたら,テキストエディタがフリーズしてしまった.⇒いや,違う.これはテキストがあまりに文字数が多いためだ.3781154行もある.

いずれにしてもかなりおかしい.「全カード削除」が実行されているのなら「全削除」というテキストがダンプに現れなくてはならないはずだが,まったく見当たらない.「DELALLCARD」というUNDOのコマンド名はあちこちに出てくる… ※「全削除」という用語は使われていない.

まず,先に「被参照カウントの残留」を片付けてしまうことにしよう.MARGBOX(22)というのは,「所属系列の先祖ノード人名リンクへの参照」だが,先祖ノードの系列に属する結婚枠はすべてこのノードを参照しているから,#1905の系列には45個の結婚が属していたと見られる.この系列は#1905の直系血族図を出力するために生成されたと考えられるが,そのあと,この系列に属するすべてのカードが削除された時点で消滅している.通常はこのような操作を行うときには,系統並び替えが実施され,その冒頭のClearTableで始末されているはずだが,極小反例ツールでは極力系統並び替えを実施しないようにしているので,いわば,「放置」状態になっていると考えられる.

系列枠リストを再生成するときには,系列枠はすべてパージされるので描画リストからは切断されているはずだが,結婚リンクが存続する限りは結婚枠は残存することになると思われる.しかし,系列に属するすべての人名リンクが削除された場合,結婚はすべて無効となって結婚リンクも同時に削除されているはずではないだろうか?だとすれば,結婚枠も削除されたと考えてよいのではないかと思う.結婚枠にはたとえば,#654009や#654265などがある.これらが削除されていることを確認しておこう.いや,#1905自体その系列に属しているのだから,その時点ではまだ存続している可能性がある.

先祖ノードからグループ内の結婚枠にアクセスするための経路としては,先祖ノードの人名枠に接続する描画リストをたどるという方法がある.また,別の方法として,もし,その時点で系列枠が存在しているとすれば,先祖ノードの人名枠のグループ,つまり系列枠ノードからグループメンバーを割り出すことも可能と思われる.まず,CARDLINKのデストラクタで人名枠が存続していること,またそのオブジェクトのグループも存続していることを確認しておこう.CARDLINKが系列先祖であることを知るにはどうすればよいか?

CARDLINKのDisposeの中から,CARDLINK->NAMEBOX->TRIBEBOX->CleanSansyo(CARDLINK)が実行されているので,これを見ておこう.⇒TRIBEBOX::CleanSansyoにはすでに描画リストを辿って結婚枠からの先祖ノード参照を削除する処理は入っているが,これに追加して,グループリストから結婚枠を特定して参照解除する処理を組み込んだ.ただし,これは空振りに終わった.⇒これらの点から見て,この障害は先祖ノードを含むブロックを一括削除したときにはつねに起こりそうな感じがするが,発生しない.

この障害には,計算量を軽減するための「UndoRedoで一時的に系統並び替えを停止@20220419」オプションが作用している.このオプションが立っているときにはエラーを無視することにする.正規のコードでも,undoredoがオンのときには警告パネルを出さないようになっている.従って,このオプション中は「非参照カウントの残留」は無視するというのが妥当である.「CHECKREMAINSANSYO」というオプション自体をオフにしておく必要がある.⇒対処した.

本線のUNDOに時間が掛かるようになるという問題に戻ろう.2, 3件の全削除が掛かって,カード数が361まで削減された後に事象が発現し,保全されるオブジェクト数が鰻登りに増加するようになる.⇒どうも,バックアップがネズミ講的に増大しているのではないか?という気がする.「極小反例 361.zel」から始めた場合,20個くらいの「カード削除」の後,単点の「カード全削除」が2回続き,その後の「カード削除」からバックアップの個数が増加し始める. 「UndoRedoで一時的に系統並び替えを停止@20220419」は動作に影響していない.明らかに現行論理ではかなりの重複バックアップが生じているが,これは一般的な動作で「増加」と直接結びつくものではない.PARTIALMAP, longtableのダブりも見受けられる.⇒カードの単点削除はそのつどUNDOされるので残っていないが,全削除された場合はそのまま残されているので,累積する.それが影響しているのだろう.

UNDOノードには①更新,②生成,③削除の3つのタイプがある.Undo/Redoでは②ないし③については生成/削除,ないしその逆操作を行い,①の更新では内容を上書きする.②と③は排他的だが,①の更新は一つのコマンドの中で複数発生する場合もあり得る.UndoとRedoではコマンドリングを逆向きに処理しているので,同じノード群でも結果は異なるものになると考えられる.このような実際のフローから見て,UNDOノードの重複を回避して単一のUNDOノードに集約するのは難しいように思われる.従って,UNDOノードを生成するときに可能な限り重複を避けるという方策しかないのではないだろうか?うまく,すれば①のみ,②→①ないし,①→③という組み合わせに極小化することは不可能ではないような気もするが…このためには,②ないし③のUNDOノードに初期/末期情報を掲載しておく必要がある.そこまでやるしかないのかどうかをまず見極める必要がある.


コメントを残す

メールアドレスが公開されることはありません。

CAPTCHA