diff --git a/.gitignore b/.gitignore index d4be7ab..ce5edeb 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ compile_commands.json .luacheckcache benchmarks flamegraph* +perf.data* diff --git a/rust/lib.rs b/rust/lib.rs index 0189f15..b1e6cf0 100644 --- a/rust/lib.rs +++ b/rust/lib.rs @@ -66,18 +66,19 @@ pub extern "C" fn ivy_files(c_pattern: *const c_char, c_base_dir: *const c_char) } pub fn inner_files(pattern: String, base_dir: String) -> String { - // Bail out early if the pattern is empty its never going to find anything + let mut output = String::new(); + + // Bail out early if the pattern is empty; it's never going to find anything if pattern.is_empty() { - return String::new(); + return output; } let files = get_files(&base_dir); - let mut output = String::new(); let sorter_options = sorter::Options::new(pattern); let files = sorter::sort_strings(sorter_options, files); - for file in files.lock().unwrap().iter() { + for file in files.iter() { output.push_str(&file.content); output.push('\n'); } diff --git a/rust/sorter.rs b/rust/sorter.rs index cdb9983..83ba5b9 100644 --- a/rust/sorter.rs +++ b/rust/sorter.rs @@ -1,8 +1,8 @@ use super::matcher; use super::thread_pool; +use std::sync::mpsc; use std::sync::Arc; -use std::sync::Mutex; pub struct Match { pub score: i64, @@ -23,30 +23,37 @@ impl Options { } } -pub fn sort_strings(options: Options, strings: Vec) -> Arc>> { - let matches: Arc>> = Arc::new(Mutex::new(Vec::new())); - let matcher = Arc::new(Mutex::new(matcher::Matcher::new(options.pattern))); +pub fn sort_strings(options: Options, strings: Vec) -> Vec { + let mut matches = Vec::new(); + let matcher = Arc::new(matcher::Matcher::new(options.pattern)); let pool = thread_pool::ThreadPool::new(std::thread::available_parallelism().unwrap().get()); + let (tx, rx) = mpsc::channel::(); + for string in strings { let thread_matcher = Arc::clone(&matcher); - let thread_matches = Arc::clone(&matches); + let thread_transmitter = tx.clone(); pool.execute(move || { - let score = thread_matcher.lock().unwrap().score(string.to_string()); + let score = thread_matcher.score(string.to_string()); if score > 25 { - let mut tmp = thread_matches.lock().unwrap(); - let content = string.clone(); - tmp.push(Match { score, content }); + thread_transmitter + .send(Match { + score, + content: string, + }) + .expect("Failed to push data to channel"); } }) } drop(pool); + drop(tx); - matches - .lock() - .unwrap() - .sort_by(|a, b| a.score.cmp(&b.score)); + while let Ok(result) = rx.recv() { + matches.push(result) + } + + matches.sort_by(|a, b| a.score.cmp(&b.score)); matches }