あなたの行はすべて平均の長さに近い合理的であると仮定しましょう(つまり、ログの半分程度を占める行がないことを意味します)。これにより、二分探索が可能になります。
次に、次の機能があることも前提としています。
//find the first start of a new log line after (or including) position start
//return the last position of the file if no start could be found
streampos findNextLineStart(ifstream &file, streampos start);
//extract the data as a timestamp from a line
int extractDate(ifstream &file, streampos lineStart);
これらの関数を使用して、次を実装できます。
//find the position of the first line whose date is bigger than the given
streampos lower_bound(ifstream &file, int date)
{
file.seekg(0, ios::end);
streampos begin = 0,
end = file.tellg();
while(begin < end)
{
streampos cur = (begin + end) / 2;
streampos start = findNextLineStart(file, cur);
//was a line start found?
if(start < end)
{
int lineDate = extractDate(file, start);
if(lineDate < date)
begin = start;
else
end = start;
}
else
//narrow the bound as no line was found
end = cur;
}
return begin;
}
これが(すべてのコーナーケースで)機能することを保証するものではありませんが、全体的な実装をスケッチしています。別の関数upper_bound
を使用すると、範囲内の行の開始と終了を取得できます。