From 0dc8383d2e4c722f2e12693aafcaca1909030d76 Mon Sep 17 00:00:00 2001 From: Cameron Cordes Date: Tue, 19 May 2020 18:19:18 -0400 Subject: [PATCH] Fix massive memory allocation issue Not exactly sure what was going on, other than cloning of the FileMatch with its results, since it is recursive I believe this blew up the stack/heap with unnecessary allocations. By using an iterator and filter this seemed to greatly reduce memory use and improve speed. --- src/main.rs | 50 ++++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/src/main.rs b/src/main.rs index f57658e..076a4a1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,34 +19,40 @@ fn main() { } } -fn traverse_dir(config: &config::Config, dir: &Path, operation: fn(&config::Config, &Path) -> io::Result) - -> io::Result> { +fn traverse_dir( + config: &config::Config, + dir: &Path, + operation: fn(&config::Config, &Path) -> io::Result, +) -> io::Result> { + let mut matches: Vec = Vec::new(); + for entry in fs::read_dir(dir)? { + let entry = entry?; + let file_type = entry.file_type()?; - let mut matches: Vec = Vec::new(); - for entry in fs::read_dir(dir)? { - let entry = entry?; - let file_type = entry.file_type()?; + if file_type.is_dir() { + let mut results = traverse_dir(&config, &entry.path(), operation)?; + let has_results = results + .iter() + .filter({ |mat| mat.matches.len() > 0 }) + .count() + > 0; - if file_type.is_dir() { - let results = traverse_dir(&config, &entry.path(), operation)?; - for mat in results.as_slice() { - if mat.matches.len() > 0 { - matches.append(&mut results.clone()); - } - } - } else { - let result = operation(&config, &entry.path()); - match result { - Result::Ok(result) if result.matches.len() > 0 => matches.push(result), - _ => () - } + if has_results { + matches.append(&mut results); + } + } else { + let result = operation(&config, &entry.path()); + match result { + Result::Ok(result) if result.matches.len() > 0 => matches.push(result), + _ => (), } } - - Ok(matches) } -#[derive(Debug, Clone)] + Ok(matches) +} + +#[derive(Debug)] struct FileMatch { file_name: String, matches: Vec