コンテンツにスキップ

gram 索引

扱うこと: 検索で照合する本文インデックスのファイルを絞る、自前の 2-gram の索引(gram 索引)の形・作り方・安全側の決まり。扱わないこと: 検索の流れ全体(検索)。先に読むページ: インデックスのファイルの形。

検索のたびに本文インデックスのファイルを全部読まないよう、ファイルごとの 2-gram(隣り合う 2 文字)を索引に持つ。検索語を含むファイルには、検索語のすべての 2-gram が必ず入っている。そのため、検索語の 2-gram を 1 つでも含まないファイルは照合しなくてよい。絞っても結果(行・行番号・順番)は、すべてを照合したときと同じになる。

work/store/gram/<インデックス名>/toc.tsv          … 目録
work/store/gram/<インデックス名>/g<10 桁>.seg     … 区画

gram 索引は本文インデックスから作り直せる派生データで、無くても検索できる(すべて照合する)。

使う条件と順序

  • 文字どおりに探すとき(正規表現でないとき)で、検索語から 2-gram を作れるときだけ使う。2-gram は空白で区切った部分の隣り合う 2 文字(小文字にそろえる)。多いときは 16 個に均等に間引く。
  • 検索の順序は、gram 索引(1 つもファイルを外せなかったときは使えない扱い)、使えなければすべて照合。

安全側の決まり

次のときは、そのファイルを必ず照合する(絞らない)。

  • どの区画にも載っていないファイル。
  • 更新日時か大きさが、区画に書いたものと違うファイル。
  • 目録・区画が無い、読めない、壊れている(区画の長さが先頭と目録に合わない、末尾の印が違う)インデックス。
  • 2-gram を数える間に書き換わったファイル、64MB を超えるファイル、読めないファイル(区画に載せない)。

同じファイルが複数の区画にあるときは、新しい区画の記録だけを使う。

区画の形

リトルエンディアン。先頭 24 バイト(印 TBGR・版 1・ファイル数・名前の長さ・2-gram の数・組の数)、更新日時(int64 × ファイル数)、大きさ(int64 × ファイル数)、ファイルの相対パス(UTF-8、改行区切り、大文字と小文字を区別せず昇順)、2-gram の値(uint32 昇順。先の文字 + 65536 × 後の文字)、組の始まり(int32 × (2-gram の数 + 1))、ファイルの番号(int32 × 組の数)、末尾の印 TBGE。

目録は 1 行目 tebunko-gram<TAB>1、next<TAB>次の区画の番号、seg<TAB>名前<TAB>長さ(古い順)、old<TAB>名前(まとめ直しで外した区画)。

作り方

  • インデックス作成の最後に、インデックスごとに今の状態へ合わせる。載っていないファイル・変わったファイルの 2-gram を数え(最大 4 スレッド)、新しい区画として足す。
  • 区画は一時ファイルに書き終えてから名前を付け、目録も一時ファイルから置き換える。途中で止まっても前の目録のままで使える。
  • 区画の数が、まとめた後の数(生きている組の総数を 1200 万で割って切り上げた数。最小 1。古い区画に残った重複と消えたファイルの分は、「今のファイルの数 / 全区画のファイルの数」の割合で除く)より 8 以上多くなったら、すべてのファイルを数え直してまとめる(組が 1200 万を超えるときは複数の区画になる)。外した区画は 1 世代だけ目録の old に残し、次の回に消す。
  • 目録に載っていない区画と書きかけの一時ファイルは、次の回の始めに消す。消せなくても(検索が開いている)エラーにしない。
  • インデックスを消したとき、無くなったインデックスの置き場を消す(インデックス作成の最後にも、無いインデックスの置き場を消す)。