allow sorting to be canceled

this removes all left over UI lag
This commit is contained in:
Pascal Kuthe 2023-08-03 21:05:02 +02:00
parent 91a265eb6b
commit 4049cdbd13
No known key found for this signature in database
GPG Key ID: D715E8655AE166A6
2 changed files with 42 additions and 30 deletions

View File

@ -12,6 +12,7 @@ use crate::worker::Woker;
pub use nucleo_matcher::{chars, Matcher, MatcherConfig, Utf32Str}; pub use nucleo_matcher::{chars, Matcher, MatcherConfig, Utf32Str};
mod boxcar; mod boxcar;
mod par_sort;
mod pattern; mod pattern;
mod utf32_string; mod utf32_string;
mod worker; mod worker;

View File

@ -7,6 +7,7 @@ use nucleo_matcher::MatcherConfig;
use parking_lot::Mutex; use parking_lot::Mutex;
use rayon::{prelude::*, ThreadPool}; use rayon::{prelude::*, ThreadPool};
use crate::par_sort::par_quicksort;
use crate::pattern::{self, MultiPattern}; use crate::pattern::{self, MultiPattern};
use crate::{boxcar, Match}; use crate::{boxcar, Match};
@ -200,40 +201,50 @@ impl<T: Sync + Send + 'static> Woker<T> {
}); });
} }
if self.canceled.load(atomic::Ordering::Relaxed) { let canceled = par_quicksort(
&mut self.matches,
|match1, match2| {
if match1.score > match2.score {
return true;
}
if match1.idx == u32::MAX {
return false;
}
if match2.idx == u32::MAX {
return true;
}
// the tie breaker is comparitevly rarely needed so we keep it
// in a branch especially because we need to access the items
// array here which involves some pointer chasing
let item1 = self.items.get_unchecked(match1.idx);
let item2 = &self.items.get_unchecked(match2.idx);
let len1: u32 = item1
.matcher_columns
.iter()
.map(|haystack| haystack.len() as u32)
.sum();
let len2 = item2
.matcher_columns
.iter()
.map(|haystack| haystack.len() as u32)
.sum();
if len1 == len2 {
match1.idx < match2.idx
} else {
len1 < len2
}
},
&self.canceled,
);
if canceled {
self.was_canceled = true; self.was_canceled = true;
} else { } else {
// TODO: cancel sort in progress?
self.matches.par_sort_unstable_by(|match1, match2| {
match2.score.cmp(&match1.score).then_with(|| {
if match1.idx == u32::MAX || match2.idx == u32::MAX {
return match1.idx.cmp(&match2.idx);
}
// the tie breaker is comparitevly rarely needed so we keep it
// in a branch especially because we need to access the items
// array here which involves some pointer chasing
let item1 = self.items.get_unchecked(match1.idx);
let item2 = &self.items.get_unchecked(match2.idx);
let len1: u32 = item1
.matcher_columns
.iter()
.map(|haystack| haystack.len() as u32)
.sum();
let len2 = item2
.matcher_columns
.iter()
.map(|haystack| haystack.len() as u32)
.sum();
(len1, match1.idx).cmp(&(len2, match2.idx))
})
});
// let old = self.matches.clone();
self.matches self.matches
.truncate(self.matches.len() - take(self.unmatched.get_mut()) as usize); .truncate(self.matches.len() - take(self.unmatched.get_mut()) as usize);
} if self.should_notify.load(atomic::Ordering::Acquire) {
(self.notify)();
if self.should_notify.load(atomic::Ordering::Acquire) { }
(self.notify)();
} }
} }
} }