diff options
| author | Ellie Huxtable <ellie@elliehuxtable.com> | 2024-06-26 12:40:17 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-26 12:40:17 +0100 |
| commit | 1201caee5c7b3020e1c879e527feb934fd1d8023 (patch) | |
| tree | 5af6ecc78075401e459c97b65f74689e141d5137 /crates/atuin-history/src | |
| parent | feat: add several other GitHub access token patterns (#2200) (diff) | |
| download | atuin-1201caee5c7b3020e1c879e527feb934fd1d8023.zip | |
perf(search): benchmark smart sort (#2202)
Diffstat (limited to 'crates/atuin-history/src')
| -rw-r--r-- | crates/atuin-history/src/lib.rs | 1 | ||||
| -rw-r--r-- | crates/atuin-history/src/sort.rs | 46 |
2 files changed, 47 insertions, 0 deletions
diff --git a/crates/atuin-history/src/lib.rs b/crates/atuin-history/src/lib.rs index 9d34677f..e7b33916 100644 --- a/crates/atuin-history/src/lib.rs +++ b/crates/atuin-history/src/lib.rs @@ -1 +1,2 @@ +pub mod sort; pub mod stats; diff --git a/crates/atuin-history/src/sort.rs b/crates/atuin-history/src/sort.rs new file mode 100644 index 00000000..4465a142 --- /dev/null +++ b/crates/atuin-history/src/sort.rs @@ -0,0 +1,46 @@ +use atuin_client::history::History; + +type ScoredHistory = (f64, History); + +// Fuzzy search already comes sorted by minspan +// This sorting should be applicable to all search modes, and solve the more "obvious" issues +// first. +// Later on, we can pass in context and do some boosts there too. +pub fn sort(query: &str, input: Vec<History>) -> Vec<History> { + // This can totally be extended. We need to be _careful_ that it's not slow. + // We also need to balance sorting db-side with sorting here. SQLite can do a lot, + // but some things are just much easier/more doable in Rust. + + let mut scored = input + .into_iter() + .map(|h| { + // If history is _prefixed_ with the query, score it more highly + let score = if h.command.starts_with(query) { + 2.0 + } else if h.command.contains(query) { + 1.75 + } else { + 1.0 + }; + + // calculate how long ago the history was, in seconds + let now = time::OffsetDateTime::now_utc().unix_timestamp(); + let time = h.timestamp.unix_timestamp(); + let diff = std::cmp::max(1, now - time); // no /0 please + + // prefer newer history, but not hugely so as to offset the other scoring + // the numbers will get super small over time, but I don't want time to overpower other + // scoring + #[allow(clippy::cast_precision_loss)] + let time_score = 1.0 + (1.0 / diff as f64); + let score = score * time_score; + + (score, h) + }) + .collect::<Vec<ScoredHistory>>(); + + scored.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap().reverse()); + + // Remove the scores and return the history + scored.into_iter().map(|(_, h)| h).collect::<Vec<History>>() +} |
