fix(bench): refresh PreadReader index periodically in scroll_during_append (closes #36)
The reader's line_index and file_size were frozen at open time. After current_line exceeded the initial 150K lines, get_line_impl returned None for all subsequent reads. With the background thread appending ~10K lines/sec, ~40% of measured frame latencies were actually the cost of a None return, not real I/O. - Add PreadReaderCore::refresh_index(&mut self): seek to start, rebuild LineIndex, update file_size, invalidate read cache - Add PreadReaderPlain::refresh_index forwarding method - Add ReadCache::invalidate to force cache miss after reindex - Rewrite bench_scroll_during_append: time-based refresh (250ms), only record latencies for successful reads, assert max_line > initial - Add regression tests for refresh_index with appended lines
This commit is contained in:
@@ -180,18 +180,40 @@ fn bench_scroll_during_append(config: &BenchConfig, dir: &std::path::Path) -> Ve
|
||||
}
|
||||
});
|
||||
|
||||
let reader = PreadReaderPlain::open(&path).expect("Failed to open file");
|
||||
let mut reader = PreadReaderPlain::open(&path).expect("Failed to open file");
|
||||
let initial_lines = reader.total_lines();
|
||||
let mut frame_latencies = Vec::new();
|
||||
let mut current_line = 0usize;
|
||||
let mut refresh_count: u64 = 0;
|
||||
let mut none_count: u64 = 0;
|
||||
let scroll_start = std::time::Instant::now();
|
||||
let mut last_refresh = std::time::Instant::now();
|
||||
let refresh_interval = std::time::Duration::from_millis(250);
|
||||
|
||||
while scroll_start.elapsed().as_secs() < duration_secs {
|
||||
let t = std::time::Instant::now();
|
||||
let _ = reader.get_line(current_line);
|
||||
frame_latencies.push(t.elapsed().as_micros() as u64);
|
||||
current_line += 1;
|
||||
if last_refresh.elapsed() >= refresh_interval {
|
||||
reader.refresh_index().ok();
|
||||
refresh_count += 1;
|
||||
last_refresh = std::time::Instant::now();
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(_line) = reader.get_line(current_line) {
|
||||
let t = std::time::Instant::now();
|
||||
frame_latencies.push(t.elapsed().as_micros() as u64);
|
||||
current_line += 1;
|
||||
} else {
|
||||
none_count += 1;
|
||||
std::thread::sleep(std::time::Duration::from_millis(1));
|
||||
}
|
||||
}
|
||||
|
||||
let max_line = current_line;
|
||||
assert!(
|
||||
max_line > initial_lines,
|
||||
"benchmark never read past initial {initial_lines} lines (max={max_line})"
|
||||
);
|
||||
|
||||
reader.close();
|
||||
bg_handle.join().ok();
|
||||
|
||||
@@ -202,6 +224,10 @@ fn bench_scroll_during_append(config: &BenchConfig, dir: &std::path::Path) -> Ve
|
||||
extra.insert("duration_secs".into(), duration_secs as f64);
|
||||
extra.insert("append_rate_per_sec".into(), append_rate as f64);
|
||||
extra.insert("frames_rendered".into(), frame_latencies.len() as f64);
|
||||
extra.insert("refresh_count".into(), refresh_count as f64);
|
||||
extra.insert("none_count".into(), none_count as f64);
|
||||
extra.insert("initial_lines".into(), initial_lines as f64);
|
||||
extra.insert("max_line_seen".into(), max_line as f64);
|
||||
|
||||
vec![BenchmarkResult {
|
||||
category: "growth".into(),
|
||||
|
||||
Reference in New Issue
Block a user