minor performance boost

This commit is contained in:
Alexander Mohr 2025-05-19 21:36:34 +02:00
parent ab56048574
commit 0557593230

View file

@ -1,6 +1,6 @@
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::rc::Rc; use std::rc::Rc;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex, RwLock};
use std::thread; use std::thread;
use std::time::Instant; use std::time::Instant;
@ -29,7 +29,7 @@ use crate::config::{Anchor, Config, MatchMethod, SortOrder, WrapMode};
use crate::desktop::known_image_extension_regex_pattern; use crate::desktop::known_image_extension_regex_pattern;
use crate::{Error, config, desktop}; use crate::{Error, config, desktop};
type ArcMenuMap<T> = Arc<Mutex<HashMap<FlowBoxChild, MenuItem<T>>>>; type ArcMenuMap<T> = Arc<RwLock<HashMap<FlowBoxChild, MenuItem<T>>>>;
type ArcProvider<T> = Arc<Mutex<dyn ItemProvider<T> + Send>>; type ArcProvider<T> = Arc<Mutex<dyn ItemProvider<T> + Send>>;
pub struct Selection<T: Clone + Send> { pub struct Selection<T: Clone + Send> {
@ -83,6 +83,20 @@ impl From<config::Align> for Align {
} }
} }
fn into_core_order(gtk_order: &Ordering) -> core::cmp::Ordering {
match gtk_order {
Ordering::Smaller => {
core::cmp::Ordering::Less
}
Ordering::Larger => {
core::cmp::Ordering::Greater
}
_ => {
core::cmp::Ordering::Equal
}
}
}
/// An entry in the list of selectable items in the UI. /// An entry in the list of selectable items in the UI.
/// Supports nested items but these cannot nested again (only nesting with depth == 1 is supported) /// Supports nested items but these cannot nested again (only nesting with depth == 1 is supported)
#[derive(Clone, PartialEq)] #[derive(Clone, PartialEq)]
@ -523,7 +537,7 @@ fn build_ui<T, P>(
window, window,
search: SearchEntry::new(), search: SearchEntry::new(),
main_box: FlowBox::new(), main_box: FlowBox::new(),
menu_rows: Arc::new(Mutex::new(HashMap::new())), menu_rows: Arc::new(RwLock::new(HashMap::new())),
search_text: Arc::new(Mutex::new(String::new())), search_text: Arc::new(Mutex::new(String::new())),
}); });
@ -581,15 +595,15 @@ fn build_ui<T, P>(
log::debug!("got items after {:?}", wait_for_items.elapsed()); log::debug!("got items after {:?}", wait_for_items.elapsed());
let active_cfg = config.clone(); let active_cfg = config.clone();
let map_cfg = config.clone(); //let map_cfg = config.clone();
let animate_window = ui_elements.window.clone(); let animate_window = ui_elements.window.clone();
animate_window.connect_is_active_notify(move |w| { animate_window.connect_is_active_notify(move |w| {
window_show_resize(&active_cfg.clone(), w); window_show_resize(&active_cfg.clone(), w);
}); });
animate_window.connect_map(move |w| { // animate_window.connect_map(move |w| {
window_show_resize(&map_cfg.clone(), w); // window_show_resize(&map_cfg.clone(), w);
}); // });
build_ui_from_menu_items(&ui_elements, &meta, provider_elements); build_ui_from_menu_items(&ui_elements, &meta, provider_elements);
@ -626,7 +640,7 @@ fn build_main_box<T: Clone + 'static>(config: &Config, ui_elements: &Rc<UiElemen
fb.grab_focus(); fb.grab_focus();
fb.invalidate_sort(); fb.invalidate_sort();
let lock = ui_clone.menu_rows.lock().unwrap(); let lock = ui_clone.menu_rows.read().unwrap();
select_first_visible_child(&*lock, &ui_clone.main_box); select_first_visible_child(&*lock, &ui_clone.main_box);
}); });
} }
@ -697,22 +711,22 @@ fn build_ui_from_menu_items<T: Clone + 'static + Send>(
meta: &Rc<MetaData<T>>, meta: &Rc<MetaData<T>>,
mut items: Vec<MenuItem<T>>, mut items: Vec<MenuItem<T>>,
) { ) {
items.reverse();
let start = Instant::now(); let start = Instant::now();
{ {
while let Some(b) = ui.main_box.child_at_index(0) { while let Some(b) = ui.main_box.child_at_index(0) {
ui.main_box.remove(&b); ui.main_box.remove(&b);
drop(b); drop(b);
} }
ui.menu_rows.lock().unwrap().clear(); ui.menu_rows.write().unwrap().clear();
let meta_clone = Rc::<MetaData<T>>::clone(meta); let meta_clone = Rc::<MetaData<T>>::clone(meta);
let ui_clone = Rc::<UiElements<T>>::clone(ui); let ui_clone = Rc::<UiElements<T>>::clone(ui);
glib::idle_add_local(move || { glib::idle_add_local(move || {
ui_clone.main_box.unset_sort_func();
let mut done = false; let mut done = false;
{ {
let mut lock = ui_clone.menu_rows.lock().unwrap(); let mut lock = ui_clone.menu_rows.write().unwrap();
for _ in 0..25 { for _ in 0..25 {
if let Some(item) = items.pop() { if let Some(item) = items.pop() {
@ -732,19 +746,18 @@ fn build_ui_from_menu_items<T: Clone + 'static + Send>(
); );
} }
let items_sort = ArcMenuMap::clone(&ui_clone.menu_rows);
ui_clone.main_box.set_sort_func(move |child1, child2| {
sort_menu_items_by_score(child1, child2, &items_sort)
});
if done { if done {
let mut lock = ui_clone.menu_rows.lock().unwrap(); let lock = ui_clone.menu_rows.read().unwrap();
let menus = &mut *lock; let items_sort = ArcMenuMap::clone(&ui_clone.menu_rows);
select_first_visible_child(menus, &ui_clone.main_box); ui_clone.main_box.set_sort_func(move |child1, child2| {
sort_flow_box_childs(child1, child2, &items_sort)
});
select_first_visible_child(&lock, &ui_clone.main_box);
log::debug!( log::debug!(
"Created {} menu items in {:?}", "Created {} menu items in {:?}",
menus.len(), &lock.len(),
start.elapsed() start.elapsed()
); );
ControlFlow::Break ControlFlow::Break
@ -787,11 +800,10 @@ fn handle_key_press<T: Clone + 'static + Send>(
custom_keys: Option<&Vec<KeyBinding>>, custom_keys: Option<&Vec<KeyBinding>>,
) -> Propagation { ) -> Propagation {
let update_view = |query: &String| { let update_view = |query: &String| {
let mut lock = ui.menu_rows.lock().unwrap(); let mut lock = ui.menu_rows.write().unwrap();
let menus = &mut *lock;
set_menu_visibility_for_search( set_menu_visibility_for_search(
query, query,
menus, &mut lock,
&meta.config, &meta.config,
meta.search_ignored_words.as_ref(), meta.search_ignored_words.as_ref(),
); );
@ -865,7 +877,7 @@ fn handle_key_press<T: Clone + 'static + Send>(
expander.set_expanded(true); expander.set_expanded(true);
} else { } else {
let opt_changed = { let opt_changed = {
let lock = ui.menu_rows.lock().unwrap(); let lock = ui.menu_rows.read().unwrap();
let menu_item = lock.get(fb); let menu_item = lock.get(fb);
menu_item.map(|menu_item| { menu_item.map(|menu_item| {
( (
@ -904,12 +916,12 @@ fn handle_key_press<T: Clone + 'static + Send>(
Propagation::Proceed Propagation::Proceed
} }
fn sort_menu_items_by_score<T: Clone>( fn sort_flow_box_childs<T: Clone>(
child1: &FlowBoxChild, child1: &FlowBoxChild,
child2: &FlowBoxChild, child2: &FlowBoxChild,
items_lock: &ArcMenuMap<T>, items_lock: &ArcMenuMap<T>,
) -> Ordering { ) -> Ordering {
let lock = items_lock.lock().unwrap(); let lock = items_lock.read().unwrap();
let m1 = lock.get(child1); let m1 = lock.get(child1);
let m2 = lock.get(child2); let m2 = lock.get(child2);
@ -920,6 +932,10 @@ fn sort_menu_items_by_score<T: Clone>(
return Ordering::Larger; return Ordering::Larger;
} }
sort_menu_items_by_score(m1, m2)
}
fn sort_menu_items_by_score<T: Clone>(m1: Option<&MenuItem<T>>, m2: Option<&MenuItem<T>>) -> Ordering {
match (m1, m2) { match (m1, m2) {
(Some(menu1), Some(menu2)) => { (Some(menu1), Some(menu2)) => {
fn compare(a: f64, b: f64) -> Ordering { fn compare(a: f64, b: f64) -> Ordering {
@ -988,7 +1004,7 @@ where
send_selected_item(ui, meta, custom_key.cloned(), selected_item); send_selected_item(ui, meta, custom_key.cloned(), selected_item);
return Ok(()); return Ok(());
} else if let Some(s) = ui.main_box.selected_children().into_iter().next() { } else if let Some(s) = ui.main_box.selected_children().into_iter().next() {
let list_items = ui.menu_rows.lock().unwrap(); let list_items = ui.menu_rows.read().unwrap();
let item = list_items.get(&s); let item = list_items.get(&s);
if let Some(selected_item) = item { if let Some(selected_item) = item {
if selected_item.visible { if selected_item.visible {
@ -1359,6 +1375,8 @@ pub fn apply_sort<T: Clone>(items: &mut [MenuItem<T>], order: &SortOrder) {
item.initial_sort_score += special_score; item.initial_sort_score += special_score;
} }
} }
items.sort_by(|l, r| into_core_order(&sort_menu_items_by_score(Some(l), Some(r))));
} }
} }
} }