大きなファイルを読み取ることで解決する問題があり、そのアプローチ方法については一般的な考えがありますが、もっと良い方法があるのではないかと考えています。
問題は次のとおりです。私はいくつかの巨大なディスクファイル(それぞれ)にそれぞれのレコード(合計レコードの周り64GB
)でいっぱいになっています。各レコードには、他のフィールドの中でも、タイムスタンプと、タイムスタンプが有効かどうかを示すisValidフラグがあります。ユーザーがタイムスパンを入力すると、タイムスタンプが指定された範囲内にあるすべてのレコードを返す必要があります。2.5KB
25,000,000
データのレイアウトは、「有効」とマークされたすべてのレコードについて、タイムスタンプが単調に増加するようになっています。無効なレコードはまったく考慮されるべきではありません。したがって、これはファイルが一般的にどのように見えるかです(範囲ははるかに大きいですが):
a[0] = { Time=11, IsValid = true };
a[1] = { Time=12, IsValid = true };
a[2] = { Time=13, IsValid = true };
a[3] = { Time=401, IsValid = false }; // <-- should be ignored
a[4] = { Time=570, IsValid = false }; // <-- should be ignored
a[5] = { Time=16, IsValid = true };
a[6] = { Time=23, IsValid = true }; // <-- time-to-index offset changed
a[7] = { Time=24, IsValid = true };
a[8] = { Time=25, IsValid = true };
a[9] = { Time=26, IsValid = true };
a[10] = { Time=40, IsValid = true }; // <-- time-to-index offset changed
a[11] = { Time=41, IsValid = true };
a[12] = { Time=700, IsValid = false }; // <-- should be ignored
a[13] = { Time=43, IsValid = true };
タイムスタンプとカウンターの間のオフセットが一定である場合、最初のレコードを探すことはO(1)
操作になります(私は単にインデックスにジャンプします)。そうではないので、私はこの情報を(すばやく)見つけるための別の方法を探しています。
1つの方法は、修正された二分探索かもしれませんが、無効なレコードのより大きなブロックを処理する方法が完全にはわかりません。ルックアップを高速化するために「インデックス」を作成することもできると思いますが、このような大きなファイルが多数あり、抽出されたデータサイズはファイル全体よりもはるかに小さいため、これらの各ファイルをトラバースしたくありません。 、レコードごとに、インデックスを生成します。インデックスを作成する際に、バイナリ検索も役立つかどうかを考えています。
言うまでもなく、インデックスに最適な構造が何であるかはわかりません。平衡二分木?