diff --git a/crates/bench/src/data_gen.rs b/crates/bench/src/data_gen.rs index e885ccc..3901163 100644 --- a/crates/bench/src/data_gen.rs +++ b/crates/bench/src/data_gen.rs @@ -84,10 +84,8 @@ pub fn generate_growable_file(dir: &Path) -> std::io::Result { /// Append `count` lines to the file pub fn append_lines(path: &Path, count: usize) -> std::io::Result<()> { let existing_lines = count_existing_lines(path)?; - let mut file = BufWriter::with_capacity( - 64 * 1024, - fs::OpenOptions::new().append(true).open(path)?, - ); + let mut file = + BufWriter::with_capacity(64 * 1024, fs::OpenOptions::new().append(true).open(path)?); for i in 0..count { writeln!( file, diff --git a/crates/bench/src/main.rs b/crates/bench/src/main.rs index d1ac93f..0d1a131 100644 --- a/crates/bench/src/main.rs +++ b/crates/bench/src/main.rs @@ -27,8 +27,10 @@ fn main() { let suites = match args.suites { Some(names) => { - let parsed: Result, _> = - names.iter().map(|s| s.parse::()).collect(); + let parsed: Result, _> = names + .iter() + .map(|s| s.parse::()) + .collect(); match parsed { Ok(s) => Some(s), Err(e) => { diff --git a/crates/bench/src/mmap_reader.rs b/crates/bench/src/mmap_reader.rs index bf1ef5e..e6b7d41 100644 --- a/crates/bench/src/mmap_reader.rs +++ b/crates/bench/src/mmap_reader.rs @@ -7,14 +7,14 @@ use std::fs::File; use std::io::BufReader; use std::path::Path; -use std::sync::atomic::{AtomicBool, AtomicPtr, AtomicU8, Ordering}; use std::sync::Once; +use std::sync::atomic::{AtomicBool, AtomicPtr, AtomicU8, Ordering}; use memmap2::{Advice, Mmap, MmapOptions, RemapOptions}; -use nix::sys::signal::{sigaction, SaFlags, SigAction, SigHandler, SigSet, Signal}; +use nix::sys::signal::{SaFlags, SigAction, SigHandler, SigSet, Signal, sigaction}; -use crate::line_index::LineIndex; use crate::FileReaderBackend; +use crate::line_index::LineIndex; // ─── SIGBUS Handler ────────────────────────────────────────────────────────── // @@ -35,7 +35,10 @@ const HANDLER_NONE: u8 = 0; const HANDLER_DEFAULT: u8 = 1; const HANDLER_IGNORE: u8 = 2; const HANDLER_PLAIN: u8 = 3; // extern "C" fn(c_int) -#[allow(clippy::unseparated_literal_suffix, reason = "clarity: this is the SA_SIGACTION variant")] +#[allow( + clippy::unseparated_literal_suffix, + reason = "clarity: this is the SA_SIGACTION variant" +)] const HANDLER_SIGACTION: u8 = 4; // extern "C" fn(c_int, *mut siginfo_t, *mut c_void) /// Old SIGBUS handler type — raw atomic, async-signal-safe to read. @@ -107,11 +110,8 @@ extern "C" fn sigbus_handler( HANDLER_SIGACTION => { let ptr = OLD_HANDLER_PTR.load(Ordering::Acquire); if !ptr.is_null() { - let f: extern "C" fn( - libc::c_int, - *mut libc::siginfo_t, - *mut std::ffi::c_void, - ) = unsafe { std::mem::transmute(ptr) }; + let f: extern "C" fn(libc::c_int, *mut libc::siginfo_t, *mut std::ffi::c_void) = + unsafe { std::mem::transmute(ptr) }; f(sig, info, ctx); } else { unsafe { libc::_exit(128 + sig) }; diff --git a/crates/bench/src/pread_reader.rs b/crates/bench/src/pread_reader.rs index 6078d5a..6ebcec8 100644 --- a/crates/bench/src/pread_reader.rs +++ b/crates/bench/src/pread_reader.rs @@ -15,8 +15,8 @@ use std::os::unix::fs::FileExt; use std::os::unix::io::AsRawFd; use std::path::Path; -use crate::line_index::LineIndex; use crate::FileReaderBackend; +use crate::line_index::LineIndex; const BLOCK_SIZE: usize = 256; const CACHE_CHUNK: usize = 4096; @@ -478,12 +478,19 @@ mod tests { let mut reader = PreadReaderPlain::open(&path).unwrap(); assert_eq!(reader.total_lines(), 3); assert_eq!(reader.get_line(0), Some("alpha".to_owned())); - assert_eq!(reader.get_line(3), None, "should be out of bounds before append"); + assert_eq!( + reader.get_line(3), + None, + "should be out of bounds before append" + ); // Phase 2: append 2 more lines { use std::io::Write as _; - let mut f = std::fs::OpenOptions::new().append(true).open(&path).unwrap(); + let mut f = std::fs::OpenOptions::new() + .append(true) + .open(&path) + .unwrap(); f.write_all(b"delta\nepsilon\n").unwrap(); } diff --git a/crates/bench/src/report.rs b/crates/bench/src/report.rs index 6c83790..2c7178f 100644 --- a/crates/bench/src/report.rs +++ b/crates/bench/src/report.rs @@ -145,8 +145,7 @@ pub fn format_report(results: &[BenchmarkResult]) -> String { let mut mem_rows: Vec<&BenchmarkResult> = category_results.to_vec(); mem_rows.sort_by(|a, b| { - (&a.test_name, &a.backend, &a.variant) - .cmp(&(&b.test_name, &b.backend, &b.variant)) + (&a.test_name, &a.backend, &a.variant).cmp(&(&b.test_name, &b.backend, &b.variant)) }); for r in mem_rows { let variant_label = format!("{} ({})", r.backend, r.variant); @@ -243,21 +242,60 @@ mod tests { #[test] fn report_ordering_independent_of_input_order() { let set_a = vec![ - make_result("sequential", "read_1mb", "pread", "default", vec![100, 110, 105]), - make_result("sequential", "read_1mb", "mmap", "default", vec![80, 85, 90]), - make_result("sequential", "read_4kb", "pread", "default", vec![10, 12, 11]), + make_result( + "sequential", + "read_1mb", + "pread", + "default", + vec![100, 110, 105], + ), + make_result( + "sequential", + "read_1mb", + "mmap", + "default", + vec![80, 85, 90], + ), + make_result( + "sequential", + "read_4kb", + "pread", + "default", + vec![10, 12, 11], + ), make_result("sequential", "read_4kb", "mmap", "default", vec![8, 9, 7]), ]; let set_b = vec![ make_result("sequential", "read_4kb", "mmap", "default", vec![8, 9, 7]), - make_result("sequential", "read_1mb", "mmap", "default", vec![80, 85, 90]), - make_result("sequential", "read_4kb", "pread", "default", vec![10, 12, 11]), - make_result("sequential", "read_1mb", "pread", "default", vec![100, 110, 105]), + make_result( + "sequential", + "read_1mb", + "mmap", + "default", + vec![80, 85, 90], + ), + make_result( + "sequential", + "read_4kb", + "pread", + "default", + vec![10, 12, 11], + ), + make_result( + "sequential", + "read_1mb", + "pread", + "default", + vec![100, 110, 105], + ), ]; let report_a = format_report(&set_a); let report_b = format_report(&set_b); - assert_eq!(report_a, report_b, "Reports must be identical regardless of input order"); + assert_eq!( + report_a, report_b, + "Reports must be identical regardless of input order" + ); } } diff --git a/crates/bench/src/runner.rs b/crates/bench/src/runner.rs index fc94465..de54b93 100644 --- a/crates/bench/src/runner.rs +++ b/crates/bench/src/runner.rs @@ -154,7 +154,11 @@ mod tests { ("concurrent", Suite::Concurrent), ]; for (s, expected_suite) in expected { - assert_eq!(Suite::from_str(s).unwrap(), expected_suite, "failed to parse '{s}'"); + assert_eq!( + Suite::from_str(s).unwrap(), + expected_suite, + "failed to parse '{s}'" + ); } } diff --git a/crates/bench/src/suites/concurrent.rs b/crates/bench/src/suites/concurrent.rs index 15c521d..d77d52a 100644 --- a/crates/bench/src/suites/concurrent.rs +++ b/crates/bench/src/suites/concurrent.rs @@ -1,5 +1,6 @@ use std::collections::HashMap; +use crate::FileReaderBackend; use crate::metrics::MetricsCollector; use crate::mmap_reader::{ MmapReaderPhaseAware, MmapReaderPlain, MmapReaderPopulate, MmapReaderRandom, @@ -8,7 +9,6 @@ use crate::mmap_reader::{ 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(); diff --git a/crates/bench/src/suites/growth.rs b/crates/bench/src/suites/growth.rs index 49cb012..87715e5 100644 --- a/crates/bench/src/suites/growth.rs +++ b/crates/bench/src/suites/growth.rs @@ -1,12 +1,12 @@ use std::collections::HashMap; +use crate::FileReaderBackend; use crate::data_gen; use crate::metrics::MetricsCollector; use crate::mmap_reader::MmapReaderPlain; use crate::pread_reader::PreadReaderPlain; use crate::runner::BenchConfig; use crate::types::BenchmarkResult; -use crate::FileReaderBackend; pub fn run(config: &BenchConfig) -> Vec { let mut results = Vec::new(); diff --git a/crates/bench/src/suites/jump.rs b/crates/bench/src/suites/jump.rs index d0c9f6f..acce0e6 100644 --- a/crates/bench/src/suites/jump.rs +++ b/crates/bench/src/suites/jump.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use super::FRAME_LINES; +use crate::FileReaderBackend; use crate::metrics::MetricsCollector; use crate::mmap_reader::{ MmapReaderPhaseAware, MmapReaderPlain, MmapReaderPopulate, MmapReaderRandom, @@ -9,7 +10,6 @@ use crate::mmap_reader::{ 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(); diff --git a/crates/bench/src/suites/memory.rs b/crates/bench/src/suites/memory.rs index e379f4b..fa6231e 100644 --- a/crates/bench/src/suites/memory.rs +++ b/crates/bench/src/suites/memory.rs @@ -1,5 +1,6 @@ use std::collections::HashMap; +use crate::FileReaderBackend; use crate::metrics::MetricsCollector; use crate::mmap_reader::{ MmapReaderPhaseAware, MmapReaderPlain, MmapReaderPopulate, MmapReaderRandom, @@ -8,7 +9,6 @@ use crate::mmap_reader::{ 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(); diff --git a/crates/bench/src/suites/render.rs b/crates/bench/src/suites/render.rs index cd033d1..6407dd4 100644 --- a/crates/bench/src/suites/render.rs +++ b/crates/bench/src/suites/render.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use super::FRAME_LINES; +use crate::FileReaderBackend; use crate::metrics::MetricsCollector; use crate::mmap_reader::{ MmapReaderPhaseAware, MmapReaderPlain, MmapReaderPopulate, MmapReaderRandom, @@ -9,7 +10,6 @@ use crate::mmap_reader::{ 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(); @@ -248,7 +248,11 @@ mod tests { assert!( !ranges_overlap(pos[i].1, pos[j].1), "overlap: {:?} @ {} vs {:?} @ {} (total={})", - pos[i].0, pos[i].1, pos[j].0, pos[j].1, total + pos[i].0, + pos[i].1, + pos[j].0, + pos[j].1, + total ); } } @@ -269,7 +273,10 @@ mod tests { assert!( !ranges_overlap(pos[i].1, pos[j].1), "overlap at total=104: {:?} @ {} vs {:?} @ {}", - pos[i].0, pos[i].1, pos[j].0, pos[j].1 + pos[i].0, + pos[i].1, + pos[j].0, + pos[j].1 ); } } @@ -283,7 +290,10 @@ mod tests { assert!( !ranges_overlap(pos[i].1, pos[j].1), "overlap at total=105: {:?} @ {} vs {:?} @ {}", - pos[i].0, pos[i].1, pos[j].0, pos[j].1 + pos[i].0, + pos[i].1, + pos[j].0, + pos[j].1 ); } } diff --git a/crates/bench/src/suites/rotation.rs b/crates/bench/src/suites/rotation.rs index 8f5a8b5..f8d9dc4 100644 --- a/crates/bench/src/suites/rotation.rs +++ b/crates/bench/src/suites/rotation.rs @@ -1,12 +1,12 @@ use std::collections::HashMap; +use crate::FileReaderBackend; use crate::data_gen; use crate::metrics::MetricsCollector; use crate::mmap_reader::{self, MmapReaderPlain}; use crate::pread_reader::PreadReaderPlain; use crate::runner::BenchConfig; use crate::types::BenchmarkResult; -use crate::FileReaderBackend; pub fn run(config: &BenchConfig) -> Vec { let mut results = Vec::new(); diff --git a/crates/bench/src/suites/startup.rs b/crates/bench/src/suites/startup.rs index f463502..adb48ff 100644 --- a/crates/bench/src/suites/startup.rs +++ b/crates/bench/src/suites/startup.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use std::path::Path; +use crate::FileReaderBackend; use crate::metrics::MetricsCollector; use crate::mmap_reader::{ MmapReaderPhaseAware, MmapReaderPlain, MmapReaderPopulate, MmapReaderRandom, @@ -9,7 +10,6 @@ use crate::mmap_reader::{ 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(); diff --git a/crates/core/src/io/file_reader.rs b/crates/core/src/io/file_reader.rs index e9a03a0..fbc0ae2 100644 --- a/crates/core/src/io/file_reader.rs +++ b/crates/core/src/io/file_reader.rs @@ -33,8 +33,8 @@ impl FileReader { } else { // SAFETY: 使用只读 Mmap(非 MmapMut),文件以只读方式打开。 // memmap2 内部持有文件描述符,确保 mmap 期间文件不会被关闭。 - let m = unsafe { memmap2::Mmap::map(&file) } - .map_err(|e| CoreError::Mmap(e.to_string()))?; + let m = + unsafe { memmap2::Mmap::map(&file) }.map_err(|e| CoreError::Mmap(e.to_string()))?; // Layer 3: mmap 后立即 stat 同一 fd,检测截断(TOCTOU 缓解,非安全证明) let current_size = file.metadata()?.len(); @@ -507,7 +507,11 @@ mod tests { reader.reload().unwrap(); assert_eq!(reader.line_count(), 1); assert_eq!(reader.get_line(0), Some("new")); - assert_eq!(reader.get_line(1), None, "old line should not be accessible"); + assert_eq!( + reader.get_line(1), + None, + "old line should not be accessible" + ); } #[test] diff --git a/crates/core/src/io/index_cache.rs b/crates/core/src/io/index_cache.rs index e9f9674..2c74686 100644 --- a/crates/core/src/io/index_cache.rs +++ b/crates/core/src/io/index_cache.rs @@ -1,7 +1,7 @@ use std::io::{Read as _, Write as _}; use std::path::Path; -use crate::io::cache_util::{cache_path, CACHE_VERSION}; +use crate::io::cache_util::{CACHE_VERSION, cache_path}; use crate::io::line_index::LineIndex; pub struct IndexCache; @@ -47,11 +47,7 @@ impl IndexCache { /// /// The file hash is derived from `data` (the same byte slice used to build the index), /// avoiding TOCTOU issues from re-reading the file from disk. - pub fn save_with_hash( - file_path: &Path, - index: &LineIndex, - data: &[u8], - ) -> std::io::Result<()> { + pub fn save_with_hash(file_path: &Path, index: &LineIndex, data: &[u8]) -> std::io::Result<()> { let dest = cache_path(file_path).ok_or_else(|| { std::io::Error::new(std::io::ErrorKind::NotFound, "cannot determine cache path") })?; @@ -382,6 +378,10 @@ mod tests { } let final_data = std::fs::read(&dest).expect("dest file should exist"); - assert_eq!(final_data.len(), 64 * 1024, "final file must be exactly one payload"); + assert_eq!( + final_data.len(), + 64 * 1024, + "final file must be exactly one payload" + ); } -} \ No newline at end of file +} diff --git a/crates/core/src/io/read_cache.rs b/crates/core/src/io/read_cache.rs index e3ae08a..a6f67b1 100644 --- a/crates/core/src/io/read_cache.rs +++ b/crates/core/src/io/read_cache.rs @@ -492,4 +492,4 @@ mod tests { let err = cache.get(&file, u64::MAX, 1).unwrap_err(); assert_eq!(err.kind(), io::ErrorKind::InvalidInput); } -} \ No newline at end of file +} diff --git a/crates/core/src/types.rs b/crates/core/src/types.rs index 5c6276f..6e39ba3 100644 --- a/crates/core/src/types.rs +++ b/crates/core/src/types.rs @@ -324,10 +324,7 @@ mod tests { Ok(LogLevel::Unknown("CUSTOM".into())) ); // Pure whitespace becomes Unknown(""). - assert_eq!( - " ".parse::(), - Ok(LogLevel::Unknown("".into())) - ); + assert_eq!(" ".parse::(), Ok(LogLevel::Unknown("".into()))); // Internal whitespace is NOT collapsed. assert_eq!( "W ARN".parse::(), diff --git a/crates/core/src/watcher/file_watcher.rs b/crates/core/src/watcher/file_watcher.rs index c068dfb..14a11a6 100644 --- a/crates/core/src/watcher/file_watcher.rs +++ b/crates/core/src/watcher/file_watcher.rs @@ -1,7 +1,7 @@ use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex}; -use crossbeam_channel::{bounded, Receiver, Sender}; +use crossbeam_channel::{Receiver, Sender, bounded}; use notify::{Event, EventKind, RecommendedWatcher, RecursiveMode, Watcher}; use crate::error::Result;