ソートされたデータがあれば、検索ソリューションは明白です。ソートされていないデータが与えられた場合、賢明なオプションは、ソートしてから検索するか、または単に線形検索です。
この質問は、データがある程度ソートされている場合、ただし再編成できない(書き込み操作にはセクターが必要)消去すると、セクターはRAMに収まりません)。
詳細:
データレコードはログに記録されますタイムスタンプ付きで順次。ただし、タイムスタンプクロックは、時刻から時刻はエポックにリセットされます同期される前にしばらくの間、または夏時間などにより単純に調整されます。
検索結果は、指定された時刻に最も近いタイムスタンプを持つログレコードである必要があります。特定のタイムスタンプでレコードのバイナリ検索を実行しているときに、不連続なログデータのパッチに到達し、間違った方向にピボットする可能性があります。
野蛮な線形手法の他に、ここで利用できるヒューリスティックはありますか?例えば極小値の影響を受けないシンプレックス検索?
更新:
レコードの約95%がソートされた順序であると想定できます。約5%(ログ全体に散在)は汚いしゃっくりです。しゃっくりの始まりは、タイムスタンプが時間的に逆方向に移動するときに識別できますおよびおよびログの先頭より前のスタンプが
この回答は、次の追加の仮定に基づいています。
検索は実際には2つの異なるアルゴリズムに分割されます。タイムスタンプが-afterログの先頭であるログを検索する場合、ログがしゃっくりで見つからないことがわかっているため、non-hiccup searchを使用します。 =以下。ログの開始前にタイムスタンプを検索する場合は、代わりにhiccup searchを使用します。タイムスタンプではなく他のいくつかの基準で検索する場合は、95%のカバレッジのために最初にしゃっくり以外の検索を試し、次にしゃっくり検索を試します。何も見つかりませんでした。
必要に応じて、前処理ステップにより、一時的な検索を高速化できます。
可能であれば、線形検索を使用してデータを事前分析し、しゃっくりデータの位置を見つけます。これは、これらの範囲を保存できるかどうかに完全に依存します。これは、ログの5%にすぎない場合に可能になる可能性があります(またはそうでない場合は、パフォーマンスが低下します)。
新しいログを書き込むたびに、対応するデータ構造を更新する必要があることに注意してください。少なくとも、ログのどの時点まで前処理が実行されたかを通知できる必要があります。
非ヒカップデータの検索は、バイナリ検索と線形検索の組み合わせによって可能です。通常のバイナリ検索を実行しますが、ピボット要素がログの開始前にタイムスタンプが付けられている場合、つまりピボット要素が一時的な中断である場合は、ピボット要素の前の最初のログエントリを特定し、それを実際のピボット要素として使用する必要があります。あなたの二分探索の。
タイムスタンプが付いたこの最初のログエントリafterログの先頭は、hiccupピボット要素から始まる線形検索によって見つかります。関連するピボット要素が配置されているキャッシュされたしゃっくりの前処理または増分更新からわかっている場合は、一定の時間でそこにジャンプできます。完全な線形検索を実行する必要がある場合は、データ構造を更新して、これらの位置が一時的な中断データでカバーされるように格納します。これにより、次回、適切なピボット要素をすばやく決定できます。
これは、前処理を行ったかどうかによって異なります。そうでない場合は、すべてのデータを線形検索します(この時点で前処理部分を実行することもできます)。それ以外の場合は、前処理されたデータ構造でしゃっくりデータの位置を確認でき、これらを直接検索できます。つまり、しゃっくりデータの5%のみを線形検索できます。
完全に前処理されたデータを使用した一時中断検索では、デフォルトのバイナリ検索とほぼ同じパフォーマンスが得られます。各ステップでの単純な比較の代わりに、ヒカップ要素にヒットしたかどうかを判断するための追加の比較が必要です。ヒットした場合は、実際のピボット要素を見つけるためにデータ構造にアクセスする必要があります。ただし、この追加の作業は、データセットの半分だけを除外するだけでなく、しゃっくりデータ部分も除外するという事実によって少し緩和されます。
もちろん、線形探索に頼らなければならない場合、これはそれに応じて低下します。
利用可能な既存のヒカップに関する情報がなく、すべてのデータを線形に検索する必要がある場合、ヒカップ検索は悪いケースです。
最後に、タイムスタンプを検索しないが、他の基準があり、そのようなログエントリが存在しない場合、これは最悪のケースです。実際、しゃっくりのデータ構造がない場合、両方の検索実行が同じしゃっくりの位置を線形にスキャンする可能性があるため、線形検索よりも遅くなります(ただし、O(n)のままです)。
データ構造が利用可能で完全に前処理されている場合、最悪の場合のランタイムはO(max(log(M)* log(N)、M))になります。ここで、Mは、線形に検索される一時的な中断データの量です。また、O(log(M))のデータ構造から任意のヒカップ位置を指定して、ヒカップデータの終わりを検索できると仮定します。