use std::collections::HashMap; use std::path::Path; use crate::metrics::MetricsCollector; use crate::mmap_reader::{ MmapReaderPhaseAware, MmapReaderPlain, MmapReaderPopulate, MmapReaderRandom, MmapReaderSequential, }; use crate::pread_reader::{PreadReaderPlain, PreadReaderRandom, PreadReaderSequential}; use crate::runner::BenchConfig; use crate::types::BenchmarkResult; use crate::FileReaderBackend; pub fn run(config: &BenchConfig) -> Vec { let mut results = Vec::new(); results.extend(bench_hot_open::("mmap", "plain", config)); results.extend(bench_hot_open::( "mmap", "sequential", config, )); results.extend(bench_hot_open::("mmap", "random", config)); results.extend(bench_hot_open::( "mmap", "populate", config, )); results.extend(bench_hot_open::( "mmap", "phase_aware", config, )); results.extend(bench_hot_open::("pread", "plain", config)); results.extend(bench_hot_open::( "pread", "random", config, )); results.extend(bench_hot_open::( "pread", "sequential", config, )); if !config.quick_mode { if MetricsCollector::clear_file_cache(&config.test_file).is_ok() { results.extend(bench_cold_open::("mmap", "plain", config)); results.extend(bench_cold_open::( "mmap", "sequential", config, )); results.extend(bench_cold_open::( "mmap", "random", config, )); results.extend(bench_cold_open::( "mmap", "populate", config, )); results.extend(bench_cold_open::( "mmap", "phase_aware", config, )); results.extend(bench_cold_open::( "pread", "plain", config, )); results.extend(bench_cold_open::( "pread", "random", config, )); results.extend(bench_cold_open::( "pread", "sequential", config, )); } } results } fn bench_hot_open( backend: &str, variant: &str, config: &BenchConfig, ) -> Vec { open_and_measure::(backend, variant, &config.test_file, "hot_open") } fn bench_cold_open( backend: &str, variant: &str, config: &BenchConfig, ) -> Vec { let _ = MetricsCollector::clear_file_cache(&config.test_file); open_and_measure::(backend, variant, &config.test_file, "cold_open") } fn open_and_measure( backend: &str, variant: &str, path: &Path, test_name: &str, ) -> Vec { let start = std::time::Instant::now(); let reader = B::open(path).expect("Failed to open file"); let elapsed = start.elapsed(); let rss = MetricsCollector::read_rss(); let faults = MetricsCollector::read_page_faults(); let result = BenchmarkResult { category: "startup".into(), test_name: test_name.into(), backend: backend.into(), variant: variant.into(), latency_us: vec![elapsed.as_micros() as u64], rss_kb: rss.vm_rss_kb, rss_peak_kb: rss.vm_hwm_kb, page_faults: faults.minor_faults + faults.major_faults, extra: { let mut m = HashMap::new(); m.insert("total_lines".into(), reader.total_lines() as f64); m.insert( "file_size_mb".into(), reader.file_size() as f64 / (1024.0 * 1024.0), ); m }, }; reader.close(); vec![result] }