diff options
author | Andrew Gallant <jamslam@gmail.com> | 2016-09-06 21:47:33 -0400 |
---|---|---|
committer | Andrew Gallant <jamslam@gmail.com> | 2016-09-06 21:47:33 -0400 |
commit | ca058d7584ddc16d88a8dbff90b89cae8fca6e90 (patch) | |
tree | 5e2e02a1442c81a789c7f32b8abc67c6a66bfde1 /src/main.rs | |
parent | af3b56a6238da1e07c207869868b03f65f22fe1b (diff) |
Add support for memory maps.
I though plain `read` had usurped them, but when searching a very small
number of files, mmaps can be around 20% faster on Linux. It'd be really
unfortunate to leave that on the table.
Mmap searching doesn't support contexts yet, but we probably don't really
care. And duplicating that logic doesn't sound fun. Without contexts, mmap
searching is delightfully simple.
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/src/main.rs b/src/main.rs index 10611907..15b250a6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,6 +34,7 @@ use std::thread; use crossbeam::sync::chase_lev::{self, Steal, Stealer}; use grep::Grep; +use memmap::{Mmap, Protection}; use walkdir::DirEntry; use args::Args; @@ -61,6 +62,7 @@ mod ignore; mod out; mod printer; mod search; +mod search_buffer; mod sys; mod terminal; mod types; @@ -221,7 +223,11 @@ impl Worker { if let Ok(p) = path.strip_prefix("./") { path = p; } - self.search(printer, path, file) + if self.args.mmap() { + self.search_mmap(printer, path, &file) + } else { + self.search(printer, path, file) + } } }; match result { @@ -248,4 +254,23 @@ impl Worker { rdr, ).run().map_err(From::from) } + + fn search_mmap<W: Send + io::Write>( + &mut self, + printer: &mut Printer<W>, + path: &Path, + file: &File, + ) -> Result<u64> { + if try!(file.metadata()).len() == 0 { + // Opening a memory map with an empty file results in an error. + return Ok(0); + } + let mmap = try!(Mmap::open(file, Protection::Read)); + Ok(self.args.searcher_buffer( + printer, + &self.grep, + path, + unsafe { mmap.as_slice() }, + ).run()) + } } |