コントロールキー+マウスホイールでズーム

一段落付いたところで,修正をフィックスしておこう.⇒まず,UNDOに関する修正をフィックスしてしまおう.まだ,全面的な動作確認を行ってはいないが,今回の修正を不可逆的なものとして確定する.

  1. 「UndoNumberを設置する@20220418」7箇所
  2. 「UNDOのShadowをfreeblock化@20220423」2箇所
  3. 「UndoEndでコマンドを追加しない@20220424」→廃止
  4. 「ShadowチェーンからUNDOノードを検出する@20220423」1箇所
  5. 「UNDOTYPEを新設する@20220424」4箇所
  6. 「CommandStartで現コマンドを全クリア@20220425」3箇所
  7. 「CheckMaximalCompaction呼び出しを抑制@20220426」1箇所
  8. 「仮修正」27箇所

まだ,あれこれ対処する必要がある箇所はあると思われるが,一応完了したことにして,また,コラッツ木生成ツールに戻ることにしよう.どこいら辺から脇道に逸れて来たのか?ログで確認しておこう.⇒2022/04/12に「検証テストカウント3200のADLサンプルでハングする」という記事がある.おそらくこの辺りだろう.「TC3000という呪われたサンプル」は2022/04/15だ.

コラッツ木生成ツールの方は,A面とB面の3機能(コラッツ数列,アドレス変換,幹線木)の動作チェックが終わって,検証テストに入ったところだ.A面とB面3機能に関しては,一般木と仮想木の両サイドをチェックしているが,検証テストはまだ一般木のテスト中だ.今回修正で一般木のテストはパスできたと思われるので,仮想木の動作チェックに移行するところだが,コラッツ木生成ツールに移る前に懸案をいくつか片付けておきたい.

  1. コラッツ特注版のための例外措置としての「中吊りを強制」をオプションとして切り替え可能にする
  2. 系図画面のモードで「縦書き」と「横書き」をオプションとして切り替えできるようにする
  3. MAXIMALGRAPH::MergeUpperSegmentで結婚点一致の条件を緩和しているが,許容値上限の是非を確認する
  4. スケールの大きいファイルを開いたとき,メモリ不足のため「生描画に切り替えます」という動作になっているが,ズーム倍率を調整して回避できるのではないか?
  5. コントロールキー+ホイールでズームできるようにする また,ズームボタンを押したときのタイマーの初期値をもっと小さくする

項目5から片付けよう.現行でも,ホイール操作によるスクロールはサポートされているし,ズーム動作はズームイン,ズームアウトボタンとして実装されている.問題は,ホイール操作はOCXの受けるイベント,ボタン操作はVBのイベントになっているという点だ.いや,ホイールイベント自体はVBで取っているようだ.FramePositionというメソッドで受渡ししている.⇒いや,その前にCtrl+リールというのはすでに「水平スクロール」として使われている.「Ctrl+ホイール」でズームというのはかなり一般化しているので,仕様変更した方がよい.ホイールスクロールは,ALTキーで受けることにしよう.⇒実装した.ZOOMINTERVALを200(ms),ZOOMRATEを0.95に設定した.

項目4は現状とする.

▲ADLファイルをダブルクリックで起動できるが,データ数が上限を超えていますのエラーが反復表示される.サンプルはCollatzTest.G.ADL.しかし,ファイルメニュー→隣接リストのインポートでは問題なく読み込める.実際データは4720点しか入っていない.⇒おかしい.隣接リストのインポートとコマンドライン起動で異なる動作になっている.どちらもまったく同じコードを実行しているように見えるのだが…

Dim NewFileName As String = MakeAdjacencyList(.FileName)
OpenFileProc(NewFileName, OPENMOD.FULLIMPORT)

BASETABLE::emptyrecnでは,maxrecn < tablesizeで上限オーバーを検査している.maxrecn=tablesizeという状態になっているため,上限オーバーと判定されている.このmaxrecnという数は「有効なレコード数」となっているが,ややあいまいなところがある.おそらく,有効なデータの最大レコード番号という意味で使われているのではないかという気がする.maxrecnのアクセス関数として_maxrecnが使われている.レコード番号とデータカウントの混乱を避けるために,maxrecnではなく,dataCountという変数を用いることにする.アクセス関数はDataCountとしておこう.

どうもこの修正は野火のように際限なく拡がりそうな気配だ.ある時期に,効率的な観点から「参照番号とレコード番号を一致させる」ということを試みた時期があり,その残滓が残っていると見られる.つまり,参照番号をインデックスとしてテーブルに直接アクセスできるという設計で,このためには参照番号はテーブルサイズより必ず小さくなくてはならない.これはUNDOでカードを元の位置に戻さなくてはならないという辺りからの発想ではないかと思われるが,本来的にはその必要はなかったのではないだろうか?つまり,UNDOはカードのリンクがテーブル上のどこに配置されていたとしても,動作可能であるはずだ.

コラッツ特注版では原則として参照番号と名前は一致することを建前としているが,実際にはハッシュ衝突が多発するため,番号と位置が一致しない場合が発生し得る.一度修正を戻して,バックアップを取ってから始めた方が賢明かもしれない.リリース版のバックアップはあるが,リール・ズームを導入しているので,そこまで戻してから出直すことにする.実際のデータがどうなっているのかは分からないが,参照番号<テーブルサイズというのは悪い設計ではないと思われる.参照番号の位置にそのカードが存在しない場合は,つねに前方を検索するという探索法はそれほど効率の悪いものではないと考えられる.ただし,テーブルの上端に達した場合には下端に戻って検索を続ける必要がある.

現行論理はほぼそれに沿ったものになっているはずだが,ハッシュで衝突が起きた場合でかつテーブル上限を超えた場合の始末が入っていない.この修正をまず入れておく必要がある.⇒LINKTABLE::GetRefnumに修正をいれたところ,この関数内ですでにオーバーフローが発生している.確かに,ADL.CSVファイルを見ると8192点のレコードが入っている.MAXPDB=0x2000=8192だから上限に達している.テーブルは1発進なので(MAXPDB-1)個までしか収納できない.ハッシュ関数には0x1FFFを使っているので,生成される参照番号は8191までだ.⇒tablesizeは内部変数なので,実際のテーブルサイズより1小さく設定しておくことにしよう.

テーブルオーバーフローを無視して処理を進めることで系統並び替えまでは進んだが,絶対座標変換で例外が発生してしまった.Bobject::ResetAbsoluteでスタックオーバーフローが発生している.なぜだろう?NAMEBOX::DrawNameText→ PrintParameter→ getGenerationでエラーが出るようになった.getGenerationでは絶対座標系から呼び出されることを禁止している.しかし,これまでは何の問題もなく動作していたのだが… 暫定的にPRINTPARAMETERを止めてみよう.→描画できた.親子関係がぶつぶつに途切れているため,「木」というよりは「ヤブ」と言うより,ほとんど「草原」に近いものになっている.「横幅に合わせてズーム」しても,19%以上には拡大できない.「メモリ描画環境を使わない」ときは,ズーム倍率の制限は不用なのではなかったろうか?

いずれにせよ,ほとんど「手が付けられない」レベルに悪い.ファイル上のデータは8192点なので,テーブルオーバーフローになるのは高々1件に留まるはずなのに,ぼろぼろオーバーフローが発生している.いや,実際に登録に失敗しているカード数はそれほど多くはない.7331964,7326588の2点だけのように思われる.コマンドライン起動ではなく,隣接リストのインポートでも結果は同じだ.上記で「ファイルメニュー→隣接リストのインポートでは問題なく読み込める」としているのは,おそらくサンプルを取り違えたのだと思う.

テスト中のサンプルはCollatzTest.G.ADLだが,似た名前のCollatzTree.G.ADLというのがデスクトップにある.リリース版の動作をチェックしてみたが同じ結果になった.このサンプルが「ブッシュ」のようになってしまうのは,オリジナルのADLがそのようなファイルになっているためだろう.つまり,このサンプルは上限を遥かに超えたサンプルを生成して,大量の足切りが発生していたのだと思う.従って,現行の仕掛り版は基本的なところでは正しく動作していると言ってよいと思う.

コメントを残す

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

CAPTCHA