1
0
mirror of https://github.com/BurntSushi/ripgrep.git synced 2025-04-24 17:12:16 +02:00
This commit is contained in:
Andrew Gallant 2016-04-03 21:22:09 -04:00
parent 07bff7409b
commit 8d9d602945
2 changed files with 47 additions and 33 deletions

@ -62,28 +62,42 @@ fn run(args: &Args) -> Result<u64> {
} else { } else {
let searcher = let searcher =
try!(LineSearcherBuilder::new(&args.arg_pattern).create()); try!(LineSearcherBuilder::new(&args.arg_pattern).create());
if args.flag_count {
run_mmap_count_only(args, &searcher)
} else {
run_mmap(args, &searcher) run_mmap(args, &searcher)
} }
} }
}
#[inline(never)]
fn run_mmap(args: &Args, searcher: &LineSearcher) -> Result<u64> { fn run_mmap(args: &Args, searcher: &LineSearcher) -> Result<u64> {
use memmap::{Mmap, Protection}; use memmap::{Mmap, Protection};
assert!(args.arg_file.len() == 1); assert!(args.arg_file.len() == 1);
let mut wtr = io::BufWriter::new(io::stdout()); let mut wtr = io::BufWriter::new(io::stdout());
let mut count = 0;
let mmap = try!(Mmap::open_path(&args.arg_file[0], Protection::Read)); let mmap = try!(Mmap::open_path(&args.arg_file[0], Protection::Read));
let text = unsafe { mmap.as_slice() }; let text = unsafe { mmap.as_slice() };
let mut count = 0;
for m in searcher.search(text) { for m in searcher.search(text) {
if !args.flag_count {
try!(wtr.write(&text[m.start..m.end])); try!(wtr.write(&text[m.start..m.end]));
try!(wtr.write(b"\n")); try!(wtr.write(b"\n"));
}
count += 1; count += 1;
} }
if args.flag_count { Ok(count)
try!(writeln!(wtr, "{}", count));
} }
#[inline(never)]
fn run_mmap_count_only(args: &Args, searcher: &LineSearcher) -> Result<u64> {
use memmap::{Mmap, Protection};
assert!(args.arg_file.len() == 1);
let mut wtr = io::BufWriter::new(io::stdout());
let mmap = try!(Mmap::open_path(&args.arg_file[0], Protection::Read));
let text = unsafe { mmap.as_slice() };
let count = searcher.search(text).last().map_or(0, |m| m.count + 1);
try!(writeln!(wtr, "{}", count));
Ok(count) Ok(count)
} }

@ -1,3 +1,5 @@
use std::cmp;
use memchr::{memchr, memrchr}; use memchr::{memchr, memrchr};
use regex::bytes::Regex; use regex::bytes::Regex;
use syntax; use syntax;
@ -82,7 +84,7 @@ impl LineSearcher {
pub struct Match { pub struct Match {
pub start: usize, pub start: usize,
pub end: usize, pub end: usize,
pub count: usize, pub count: u64,
pub line: Option<usize>, pub line: Option<usize>,
pub locations: Vec<(usize, usize)>, pub locations: Vec<(usize, usize)>,
} }
@ -91,14 +93,12 @@ pub struct Iter<'b, 's> {
searcher: &'s LineSearcher, searcher: &'s LineSearcher,
buf: &'b [u8], buf: &'b [u8],
start: usize, start: usize,
count: usize, count: u64,
} }
impl<'b, 's> Iter<'b, 's> { impl<'b, 's> Iter<'b, 's> {
#[inline(always)] // reduces constant overhead
fn next_line_match(&mut self) -> Option<(usize, usize)> { fn next_line_match(&mut self) -> Option<(usize, usize)> {
if self.start >= self.buf.len() {
return None;
}
if let Some(ref req) = self.searcher.required { if let Some(ref req) = self.searcher.required {
while self.start < self.buf.len() { while self.start < self.buf.len() {
let e = match req.shortest_match(&self.buf[self.start..]) { let e = match req.shortest_match(&self.buf[self.start..]) {
@ -116,11 +116,9 @@ impl<'b, 's> Iter<'b, 's> {
} }
None None
} else { } else {
let e = match self.searcher.re.shortest_match(&self.buf[self.start..]) { self.searcher.re
None => return None, .shortest_match(&self.buf[self.start..])
Some(e) => self.start + e, .map(|e| self.find_line(self.start + e, self.start + e))
};
Some(self.find_line(e, e))
} }
} }
@ -140,13 +138,13 @@ impl<'b, 's> Iter<'b, 's> {
impl<'b, 's> Iterator for Iter<'b, 's> { impl<'b, 's> Iterator for Iter<'b, 's> {
type Item = Match; type Item = Match;
#[inline(always)] // reduces constant overhead
fn next(&mut self) -> Option<Match> { fn next(&mut self) -> Option<Match> {
let (prevnl, nextnl) = match self.next_line_match() { match self.next_line_match() {
None => return None, None => None,
Some((s, e)) => (s, e), Some((prevnl, nextnl)) => {
};
let count = self.count; let count = self.count;
self.start = nextnl + 1; self.start = cmp::min(self.buf.len(), nextnl + 1);
self.count += 1; self.count += 1;
Some(Match { Some(Match {
start: prevnl, start: prevnl,
@ -157,6 +155,8 @@ impl<'b, 's> Iterator for Iter<'b, 's> {
}) })
} }
} }
}
}
fn parse(re: &str) -> Result<syntax::Expr> { fn parse(re: &str) -> Result<syntax::Expr> {
let expr = let expr =