From 742f9417517e3984be15f4cb61e6a35dc16b1408 Mon Sep 17 00:00:00 2001 From: = <=> Date: Sat, 27 Jan 2024 22:44:39 +0100 Subject: [PATCH] Mejoras de rendimiento --- src/fuzzy_search/fuzzy.rs | 34 ++++++++++++++++- src/fuzzy_search/mod.rs | 3 +- src/ui/renderer.rs | 77 +++++++++++++++++++++++++-------------- 3 files changed, 83 insertions(+), 31 deletions(-) diff --git a/src/fuzzy_search/fuzzy.rs b/src/fuzzy_search/fuzzy.rs index f2af58d..affc847 100644 --- a/src/fuzzy_search/fuzzy.rs +++ b/src/fuzzy_search/fuzzy.rs @@ -1,6 +1,7 @@ #[inline] -pub fn fzs(pattern: &str, list: &mut [String]) { - list.sort_by_key(|x| distance(pattern, x)); +pub fn fzs(pattern: &str, list: &mut Vec, n: usize) { + // list.sort_by_key(|x| distance(pattern, x)); + *list = sort_n_first(list, n, |x| distance(pattern, x.as_str())); } fn distance(pattern: &str, text: &str) -> usize { @@ -30,3 +31,32 @@ fn distance(pattern: &str, text: &str) -> usize { matrix[0][0] } + +fn sort_n_first(list: &mut [String], n: usize, mut key: F) -> Vec +where + F: FnMut(String) -> usize, +{ + let mut result = vec![String::from(""); n]; + let mut values = vec![0; n]; + + for e in list { + let e_val = key(e.clone()); + for (i, other) in result.clone().iter().enumerate() { + if other.is_empty() { + result[i] = e.to_string(); + values[i] = e_val; + break; + } + if e_val < values[i] { + result.insert(i, e.to_string()); + result.truncate(n); + values.insert(i, e_val); + values.truncate(n); + break; + } + } + } + + // result.reverse(); + result +} diff --git a/src/fuzzy_search/mod.rs b/src/fuzzy_search/mod.rs index 8906cbd..84ae0f3 100644 --- a/src/fuzzy_search/mod.rs +++ b/src/fuzzy_search/mod.rs @@ -12,6 +12,7 @@ pub fn test( list: Vec, input: Arc, String)>>, result: Arc>>, + n: usize, ) -> JoinHandle<()> { // let list = [ // "pear", @@ -33,7 +34,7 @@ pub fn test( thread::spawn(move || { let pattern = String::from_iter(input.read().unwrap().0.clone()); - fzs(pattern.as_str(), &mut list2); + fzs(pattern.as_str(), &mut list2, n); *result.write().unwrap() = list2; }) } diff --git a/src/ui/renderer.rs b/src/ui/renderer.rs index e7381a6..f50cb33 100644 --- a/src/ui/renderer.rs +++ b/src/ui/renderer.rs @@ -48,27 +48,42 @@ pub fn run(path: &str, recursive: usize) { let cursor: Arc> = Arc::new(RwLock::new(0)); let results: Arc>> = Arc::new(RwLock::new(Vec::new())); start_get_input(size.0 as usize, input.clone(), cont.clone(), cursor.clone()); - // let list = read_dir(path) - // .unwrap() - // .map(|x| x.unwrap().file_name().to_str().unwrap().to_string()) - // .collect::>(); - let list = get_files(Vec::new(), path, recursive); + execute!(stdout(), MoveTo(2, 3), Print("Reading files...")).unwrap(); + let mut list = Vec::new(); + get_files(&mut list, path, recursive); + execute!(stdout(), MoveTo(2, 3), Print(" ")).unwrap(); - let mut search_thread = test(list.clone(), input.clone(), results.clone()); + let mut search_thread = test( + list.clone(), + input.clone(), + results.clone(), + size.1 as usize - 4, + ); let mut processing = false; let mut last_input = String::new(); + let mut loading_message = String::from("Loading..."); + loading_message.push_str(String::from_iter(vec![' '; size.0 as usize - (4 + 10)]).as_str()); + let clear_loading = String::from_iter(vec![' '; size.0 as usize - 4]); + while cont.read().unwrap().to_owned() { let input_buff = input.read().unwrap().0.clone(); if String::from_iter(input.read().unwrap().clone().0).as_str() != last_input.as_str() { - search_thread = test(list.clone(), input.clone(), results.clone()); + search_thread = test( + list.clone(), + input.clone(), + results.clone(), + size.1 as usize - 4, + ); processing = true; + execute!(stdout(), MoveTo(2, 3), Print(loading_message.clone())).unwrap(); } if processing && search_thread.is_finished() { let res_list = results.read().unwrap(); - queue!(stdout(), Hide).unwrap(); + execute!(stdout(), Hide, MoveTo(2, 3), Print(clear_loading.clone())).unwrap(); + for (i, res) in res_list[0..(size.1 as usize - 4).min(res_list.len())] .iter() .enumerate() @@ -78,18 +93,21 @@ pub fn run(path: &str, recursive: usize) { queue!( stdout(), MoveTo(2, 3 + i as u16), - Print(format!("{}{}", res, spaces)) + Print(format!("{}{}", res, spaces)), + // MoveTo(2, 3), + // Print(format!("{} ", res_list.len())), ) .unwrap(); } queue!(stdout(), Show).unwrap(); + processing = false; } queue!( stdout(), MoveTo(2, 1), Print(input.read().unwrap().clone().1), - MoveTo(cursor.read().unwrap().to_owned() as u16 + 2, 1) + MoveTo(cursor.read().unwrap().to_owned() as u16 + 2, 1), ) .unwrap(); @@ -142,8 +160,8 @@ fn print_frame(width: usize, height: usize) { execute!(stdout()).unwrap(); } -fn get_files(list: Vec, path: &str, recursive: usize) -> Vec { - let mut list2 = list.clone(); +fn get_files(list: &mut Vec, path: &str, recursive: usize) { + // let mut list2 = list.clone(); let path_format = if path == "." { "".to_string() @@ -152,18 +170,19 @@ fn get_files(list: Vec, path: &str, recursive: usize) -> Vec { }; if recursive < 1 { - list2.append( - &mut read_dir(path) - .unwrap() - .map(|x| { - format!( - "{}{}", - path_format, - x.unwrap().file_name().to_str().unwrap() - ) - }) - .collect::>(), - ) + if let Ok(file_list) = read_dir(path) { + list.append( + &mut file_list + .map(|x| { + format!( + "{}{}", + path_format, + x.unwrap().file_name().to_str().unwrap() + ) + }) + .collect(), + ); + } } else { for e in read_dir(path) .unwrap() @@ -171,11 +190,13 @@ fn get_files(list: Vec, path: &str, recursive: usize) -> Vec { .collect::>() { let e_path = format!("{}{}", path_format, e); - list2.push(e_path.clone()); - if metadata(e_path.clone()).unwrap().is_dir() { - list2 = get_files(list2, e_path.as_str().clone(), recursive - 1); + list.push(e_path.clone()); + + if let Ok(met) = metadata(e_path.clone()) { + if met.is_dir() { + get_files(list, e_path.as_str().clone(), recursive - 1); + } } } } - list2 }