use std::sync::{Mutex, MutexGuard};
use std::time::{Duration, Instant};
use typ_buffer::{SearchQuery, TextBuffer};
fn big_buffer() -> TextBuffer {
let line = " let editor = Editor::new(); // a representative line of code\n";
let text: String = std::iter::repeat_n(line, 50_000).collect();
TextBuffer::from_str(&text)
}
const BUDGET_US: u128 = 16_000;
static EXCLUSIVE: Mutex<()> = Mutex::new(());
fn exclusive() -> MutexGuard<'static, ()> {
EXCLUSIVE
.lock()
.unwrap_or_else(|poisoned| poisoned.into_inner())
}
#[test]
#[ignore = "wall-clock budget; run with --release --ignored"]
fn counting_graphemes_on_a_line_does_not_walk_the_buffer() {
let _guard = exclusive();
let buffer = big_buffer();
let last = buffer.line_count() - 1;
let start = Instant::now();
for _ in 0..1_000 {
std::hint::black_box(buffer.line_grapheme_count(last));
}
let per_call = start.elapsed() / 1_000;
println!("line_grapheme_count: {per_call:?}");
assert!(
per_call.as_micros() < 100,
"one line lookup cost {per_call:?}, which is a whole-buffer walk, not a line"
);
}
#[test]
#[ignore = "wall-clock budget; run with --release --ignored"]
fn searching_a_large_file_for_a_rare_needle_fits_in_a_keystroke() {
let _guard = exclusive();
let buffer = big_buffer();
let query = SearchQuery::new("Editor::from_pieces", true);
let mut best = Duration::MAX;
let mut hits = 0usize;
for _ in 0..5 {
let start = Instant::now();
let found = buffer.find_all(&query);
best = best.min(start.elapsed());
hits = found.len();
}
println!("find_all, rare needle: {best:?} ({hits} hits, best of 5)");
assert!(
best.as_micros() < BUDGET_US,
"find_all cost {best:?} at best, over the 16ms keystroke budget"
);
}
#[test]
#[ignore = "measurement, not a gate; run with --release --ignored"]
fn a_match_on_every_line_is_measured_not_budgeted() {
let buffer = big_buffer();
let query = SearchQuery::new("Editor", true);
let start = Instant::now();
let hits = buffer.find_all(&query);
println!(
"find_all, match on every line: {:?} ({} hits)",
start.elapsed(),
hits.len()
);
}