データは並べ替えられているため、データの小さなまばらなサブセットをメモリに保持するだけで、コンテンツを非常に迅速かつ効率的に見つけることができます。たとえば、N 番目ごとの要素をメモリに格納するとします。API を効率的に初期化するには、このスパース リストをディスク上の別のファイルにコンパイルして、取得するために 100 GB のデータをストリーミングする必要がないようにする必要があります。
これらのタームごとに、タームが開始するファイルのヘッドに相対的なディスク オフセットを保存する必要があります。次に、スパース リストとオフセットのペアをメモリにロードするだけで、2 つのリクエストの実装が簡単になります。
getStringByIndex(n):
Get floor(n/N)-th string/offset pair from list
Seek offset position in index
Read/Skip n mod N strings, then return the next one
getIndexByString(s):
Binary search over sparse list in memory
Locate lower and upper bound string/offset pairs
If a string/offset pair is in the i-th position in our sparse list,
then the string itself is the (N x i)-th string in our index.
We can use this information to compute the return value
If the string we want isn't in memory:
Seek lower-bound offset in index
Read strings until we:
a) Find a match
b) Reach the high-bound offset
c) Reach a string which is lexicographically greater than the one we are looking for
Else
Just return the index for the matching string in our sparse list
インデックス内の文字列が固定幅の場合は、さらに最適化を行うことができます。
このアルゴリズムを実装する場合は、このアルゴリズムの「N」の選択に注意する必要があります。ディスク上の位置から 10 バイトを読み取るコストは、同じ位置から 10,000 バイトを読み取るコストよりもはるかに低くはないことを思い出してください。一番痛い。