1
0
mirror of https://github.com/BurntSushi/ripgrep.git synced 2025-06-30 22:23:44 +02:00

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.
This commit is contained in:
Andrew Gallant
2016-09-06 21:47:33 -04:00
parent af3b56a623
commit ca058d7584
4 changed files with 384 additions and 29 deletions

View File

@ -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())
}
}