From 495e2ae7c1275e8cfa9c73686976fb0026dd41f4 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 15 Oct 2018 12:28:14 +0200 Subject: use threadpool instead of par_iter The way the parallel iterator splits the items, we get results from different bosses intermixed. The expected way to do it would be to search all logs related to a single boss first, before moving on, which is not what rayon did. Additionally, it forced us to collect the list of files into a vector first, before we could start the actual search. Using the scoped pool directly solves both of these problems, but the error handling suffered a bit, as we now use unwrap instead of returning a Result from the closure. But since we handle individual items, and might not want to stop just because a single item was faulty, this behaviour might be better. --- src/main.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/main.rs b/src/main.rs index 2f608df..76967b8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,8 +18,6 @@ use regex::Regex; use structopt::StructOpt; use walkdir::{DirEntry, WalkDir}; -use rayon::prelude::*; - use evtclib::{AgentKind, AgentName, EventKind, Log}; mod errors; @@ -211,14 +209,17 @@ fn is_log_file(entry: &DirEntry) -> bool { /// Run the grep search with the given options. fn grep(opt: &Opt) -> Result<(), RuntimeError> { - let walker = WalkDir::new(&opt.path); - let entries = walker.into_iter().collect::>(); - entries.into_par_iter().try_for_each(|e| { - let entry = e?; - if is_log_file(&entry) { - if let Some(result) = search_log(&entry, opt)? { - output::colored(io::stdout(), &result)?; - } + rayon::scope(|s| { + let walker = WalkDir::new(&opt.path); + for entry in walker { + let entry = entry?; + s.spawn(move |_| { + if is_log_file(&entry) { + if let Some(result) = search_log(&entry, opt).unwrap() { + output::colored(io::stdout(), &result).unwrap(); + } + } + }); } Ok(()) }) -- cgit v1.2.3