diff --git a/Cargo.lock b/Cargo.lock index 786ddb8..fde688c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -303,7 +303,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chronicler-cli" -version = "0.24.2" +version = "0.25.0" dependencies = [ "anyhow", "argh", @@ -2255,7 +2255,7 @@ dependencies = [ [[package]] name = "sweep" -version = "0.24.2" +version = "0.25.0" dependencies = [ "anyhow", "arrow-array", @@ -2279,7 +2279,7 @@ dependencies = [ [[package]] name = "sweep-cli" -version = "0.24.2" +version = "0.25.0" dependencies = [ "anyhow", "argh", diff --git a/Cargo.toml b/Cargo.toml index 9596176..ae594db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ resolver = "2" [workspace.package] authors = ["Pavel Aslanov "] edition = "2021" -version = "0.24.2" +version = "0.25.0" repository = "https://github.com/aslpavel/sweep-rs" [workspace.dependencies] diff --git a/chronicler-cli/src/history.rs b/chronicler-cli/src/history.rs index 3f779c9..00eaf98 100644 --- a/chronicler-cli/src/history.rs +++ b/chronicler-cli/src/history.rs @@ -59,7 +59,7 @@ impl Haystack for HistoryEntry { fn view( &self, ctx: &Self::Context, - positions: sweep::PositionsRef<&[u8]>, + positions: sweep::Positions<&[u8]>, theme: &Theme, ) -> Self::View { let cmd = HaystackDefaultView::new(ctx, self, positions, theme); @@ -97,7 +97,7 @@ impl Haystack for HistoryEntry { fn preview( &self, _ctx: &Self::Context, - _positions: sweep::PositionsRef<&[u8]>, + _positions: sweep::Positions<&[u8]>, theme: &Theme, ) -> Option { let mut text = Text::new(); diff --git a/chronicler-cli/src/navigator.rs b/chronicler-cli/src/navigator.rs index 08c13e3..fc6039b 100644 --- a/chronicler-cli/src/navigator.rs +++ b/chronicler-cli/src/navigator.rs @@ -19,7 +19,7 @@ use sweep::{ view::{Either, View}, Glyph, }, - Haystack, PositionsRef, Sweep, SweepEvent, SweepOptions, + Haystack, Positions, Sweep, SweepEvent, SweepOptions, }; #[derive(Debug, Clone)] @@ -104,7 +104,7 @@ impl Haystack for NavigatorItem { fn view( &self, ctx: &Self::Context, - positions: PositionsRef<&[u8]>, + positions: Positions<&[u8]>, theme: &sweep::Theme, ) -> Self::View { use NavigatorItem::*; @@ -117,7 +117,7 @@ impl Haystack for NavigatorItem { fn preview( &self, ctx: &Self::Context, - positions: PositionsRef<&[u8]>, + positions: Positions<&[u8]>, theme: &sweep::Theme, ) -> Option { use NavigatorItem::*; @@ -130,7 +130,7 @@ impl Haystack for NavigatorItem { fn preview_large( &self, ctx: &Self::Context, - positions: PositionsRef<&[u8]>, + positions: Positions<&[u8]>, theme: &sweep::Theme, ) -> Option { use NavigatorItem::*; diff --git a/chronicler-cli/src/walk.rs b/chronicler-cli/src/walk.rs index 75df3fe..156c59b 100644 --- a/chronicler-cli/src/walk.rs +++ b/chronicler-cli/src/walk.rs @@ -136,7 +136,7 @@ impl Haystack for PathItem { fn view( &self, ctx: &Self::Context, - positions: sweep::PositionsRef<&[u8]>, + positions: sweep::Positions<&[u8]>, theme: &sweep::Theme, ) -> Self::View { let path = HaystackDefaultView::new(ctx, self, positions, theme); @@ -154,7 +154,7 @@ impl Haystack for PathItem { fn preview( &self, ctx: &Self::Context, - _positions: sweep::PositionsRef<&[u8]>, + _positions: sweep::Positions<&[u8]>, _theme: &sweep::Theme, ) -> Option { let metadata = self.metadata.as_ref()?; diff --git a/sweep-lib/benches/scorer.rs b/sweep-lib/benches/scorer.rs index 0669083..ac9d5e2 100644 --- a/sweep-lib/benches/scorer.rs +++ b/sweep-lib/benches/scorer.rs @@ -18,13 +18,13 @@ pub fn scorer_benchmark(c: &mut Criterion) { group.throughput(Throughput::Elements(1_u64)); let mut score = Score::MIN; - let mut positions = Positions::new(CANDIDATE.len()); + let mut positions = Positions::new_owned(CANDIDATE.len()); group.bench_function("fuzzy", |b| { b.iter(|| fuzzy.score_ref(haystack.as_slice(), &mut score, positions.as_mut())) }); let mut score = Score::MIN; - let mut positions = Positions::new(CANDIDATE.len()); + let mut positions = Positions::new_owned(CANDIDATE.len()); group.bench_function("substr", |b| { b.iter(|| substr.score_ref(haystack.as_slice(), &mut score, positions.as_mut())) }); diff --git a/sweep-lib/src/candidate.rs b/sweep-lib/src/candidate.rs index 90197b1..e6df229 100644 --- a/sweep-lib/src/candidate.rs +++ b/sweep-lib/src/candidate.rs @@ -2,8 +2,8 @@ use crate::{ common::{json_from_slice_seed, LockExt, VecDeserializeSeed}, rpc::{RpcParams, RpcPeer}, widgets::ProcessOutput, - Haystack, HaystackBasicPreview, PositionsRef, Process, ProcessCommandArg, - ProcessCommandBuilder, Theme, + Haystack, HaystackBasicPreview, Positions, Process, ProcessCommandArg, ProcessCommandBuilder, + Theme, }; use anyhow::Error; use futures::Stream; @@ -381,12 +381,7 @@ impl Haystack for Candidate { self.inner.hotkey.clone() } - fn view( - &self, - ctx: &Self::Context, - positions: PositionsRef<&[u8]>, - theme: &Theme, - ) -> Self::View { + fn view(&self, ctx: &Self::Context, positions: Positions<&[u8]>, theme: &Theme) -> Self::View { // left side let mut positions_offset = 0; let left = fields_view( @@ -434,7 +429,7 @@ impl Haystack for Candidate { fn preview( &self, ctx: &Self::Context, - positions: PositionsRef<&[u8]>, + positions: Positions<&[u8]>, theme: &Theme, ) -> Option { if self.inner.preview.is_empty() { @@ -460,7 +455,7 @@ impl Haystack for Candidate { fn preview_large( &self, ctx: &Self::Context, - _positions: PositionsRef<&[u8]>, + _positions: Positions<&[u8]>, _theme: &Theme, ) -> Option { ctx.preview_get(self) @@ -481,7 +476,7 @@ type FieldsView = either::Either, Text>; #[allow(clippy::too_many_arguments)] pub fn fields_view( fields: &[Field<'_>], - positions: PositionsRef<&[u8]>, + positions: Positions<&[u8]>, positions_offset: &mut usize, candidate_context: &CandidateContext, face_default: Face, diff --git a/sweep-lib/src/haystack.rs b/sweep-lib/src/haystack.rs index 671e3f8..adfe345 100644 --- a/sweep-lib/src/haystack.rs +++ b/sweep-lib/src/haystack.rs @@ -6,7 +6,7 @@ use surf_n_term::{ CellWrite, KeyChord, Position, TerminalSurface, }; -use crate::{PositionsRef, Theme}; +use crate::{Positions, Theme}; /// Haystack /// @@ -31,18 +31,13 @@ pub trait Haystack: std::fmt::Debug + Clone + Send + Sync + 'static { } /// Return a view that renders haystack item in a list - fn view( - &self, - ctx: &Self::Context, - positions: PositionsRef<&[u8]>, - theme: &Theme, - ) -> Self::View; + fn view(&self, ctx: &Self::Context, positions: Positions<&[u8]>, theme: &Theme) -> Self::View; /// Side preview of the current item fn preview( &self, _ctx: &Self::Context, - _positions: PositionsRef<&[u8]>, + _positions: Positions<&[u8]>, _theme: &Theme, ) -> Option { None @@ -52,7 +47,7 @@ pub trait Haystack: std::fmt::Debug + Clone + Send + Sync + 'static { fn preview_large( &self, _ctx: &Self::Context, - _positions: PositionsRef<&[u8]>, + _positions: Positions<&[u8]>, _theme: &Theme, ) -> Option { None @@ -135,7 +130,7 @@ impl HaystackDefaultView { pub fn new( ctx: &H::Context, haystack: &H, - positions: PositionsRef<&[u8]>, + positions: Positions<&[u8]>, theme: &Theme, ) -> Self { let mut text = Text::new(); @@ -222,12 +217,7 @@ impl Haystack for String { type Preview = (); type PreviewLarge = (); - fn view( - &self, - ctx: &Self::Context, - positions: PositionsRef<&[u8]>, - theme: &Theme, - ) -> Self::View { + fn view(&self, ctx: &Self::Context, positions: Positions<&[u8]>, theme: &Theme) -> Self::View { HaystackDefaultView::new(ctx, self, positions, theme) } @@ -245,12 +235,7 @@ impl Haystack for &'static str { type Preview = (); type PreviewLarge = (); - fn view( - &self, - ctx: &Self::Context, - positions: PositionsRef<&[u8]>, - theme: &Theme, - ) -> Self::View { + fn view(&self, ctx: &Self::Context, positions: Positions<&[u8]>, theme: &Theme) -> Self::View { HaystackDefaultView::new(ctx, self, positions, theme) } diff --git a/sweep-lib/src/lib.rs b/sweep-lib/src/lib.rs index 39b0ed6..9d5440e 100644 --- a/sweep-lib/src/lib.rs +++ b/sweep-lib/src/lib.rs @@ -6,8 +6,8 @@ pub use haystack::{Haystack, HaystackBasicPreview, HaystackDefaultView, Haystack mod scorer; pub use scorer::{ - FuzzyScorer, KMPPattern, Positions, PositionsRef, Score, ScoreArray, ScoreItem, ScoreIter, - Scorer, SubstrScorer, + FuzzyScorer, KMPPattern, Positions, Score, ScoreArray, ScoreItem, ScoreIter, Scorer, + SubstrScorer, }; mod rank; diff --git a/sweep-lib/src/scorer.rs b/sweep-lib/src/scorer.rs index feea67e..ca4b116 100644 --- a/sweep-lib/src/scorer.rs +++ b/sweep-lib/src/scorer.rs @@ -26,7 +26,7 @@ pub trait Scorer: Send + Sync + fmt::Debug { &self, haystack: &[char], score: &mut Score, - positions: PositionsRef<&mut [u8]>, + positions: Positions<&mut [u8]>, ) -> bool; /// Run scorer on an arrow array of strings @@ -54,7 +54,7 @@ pub trait Scorer: Send + Sync + fmt::Debug { let mut score_local = Score::MIN; positions_buf.clear(); positions_buf.resize(positions_data_size(haystack_buf.len()), 0); - let positions = PositionsRef::new_data(positions_buf.as_mut()); + let positions = Positions::new(positions_buf.as_mut()); if !(self.score_ref(haystack_buf.as_slice(), &mut score_local, positions)) { return false; } @@ -189,7 +189,7 @@ impl ScoreArray { haystack: self.inner.haystack.value(index), haystack_index: self.inner.haystack_index.value(index) as usize, score: Score(self.inner.score.value(index)), - positions: PositionsRef::new_data(self.inner.positions.value(index)), + positions: Positions::new(self.inner.positions.value(index)), rank_index, }) } @@ -297,7 +297,7 @@ pub struct ScoreItem<'a> { pub haystack: &'a str, pub haystack_index: usize, pub score: Score, - pub positions: PositionsRef<&'a [u8]>, + pub positions: Positions<&'a [u8]>, pub rank_index: usize, } @@ -312,7 +312,7 @@ impl Scorer for &S { &self, haystack: &[char], score: &mut Score, - positions: PositionsRef<&mut [u8]>, + positions: Positions<&mut [u8]>, ) -> bool { (**self).score_ref(haystack, score, positions) } @@ -329,7 +329,7 @@ impl Scorer for Box { &self, haystack: &[char], score: &mut Score, - positions: PositionsRef<&mut [u8]>, + positions: Positions<&mut [u8]>, ) -> bool { (**self).score_ref(haystack, score, positions) } @@ -346,7 +346,7 @@ impl Scorer for Arc { &self, haystack: &[char], score: &mut Score, - positions: PositionsRef<&mut [u8]>, + positions: Positions<&mut [u8]>, ) -> bool { (**self).score_ref(haystack, score, positions) } @@ -437,7 +437,7 @@ impl Scorer for SubstrScorer { &self, haystack: &[char], score: &mut Score, - mut positions: PositionsRef<&mut [u8]>, + mut positions: Positions<&mut [u8]>, ) -> bool { positions.clear(); if self.words.is_empty() { @@ -609,7 +609,7 @@ impl FuzzyScorer { needle: &[char], haystack: &[char], score: &mut Score, - mut positions: PositionsRef<&mut [u8]>, + mut positions: Positions<&mut [u8]>, ) -> bool { positions.clear(); let n_len = needle.len(); @@ -699,7 +699,7 @@ impl Scorer for FuzzyScorer { &self, haystack: &[char], score: &mut Score, - positions: PositionsRef<&mut [u8]>, + positions: Positions<&mut [u8]>, ) -> bool { Self::subseq(self.needle.as_ref(), haystack) && Self::score_impl(self.needle.as_ref(), haystack, score, positions) @@ -746,22 +746,12 @@ fn positions_data_size(size: usize) -> usize { /// Position set implemented as bit-set #[derive(Clone, Hash)] -pub struct PositionsRef { +pub struct Positions { data: D, } -pub type Positions = PositionsRef>; - -impl Positions { - pub fn new(size: usize) -> Self { - let mut chunks = smallvec::SmallVec::new(); - chunks.resize(positions_data_size(size), 0); - Self { data: chunks } - } -} - -impl> PositionsRef { - pub fn new_data(data: D) -> Self { +impl> Positions { + pub fn new(data: D) -> Self { Self { data } } @@ -775,22 +765,30 @@ impl> PositionsRef { } } - pub fn as_ref(&self) -> PositionsRef<&[u8]> { - PositionsRef { + pub fn as_ref(&self) -> Positions<&[u8]> { + Positions { data: self.data.as_ref(), } } } -impl> PositionsRef { +impl Positions> { + pub fn new_owned(size: usize) -> Self { + let mut data = Vec::new(); + data.resize(positions_data_size(size), 0); + Positions { data } + } +} + +impl> Positions { /// set specified index as selected pub fn set(&mut self, index: usize) { let (index, mask) = positions_offset(index); self.data.as_mut()[index] |= mask; } - pub fn as_mut(&mut self) -> PositionsRef<&mut [u8]> { - PositionsRef { + pub fn as_mut(&mut self) -> Positions<&mut [u8]> { + Positions { data: self.data.as_mut(), } } @@ -803,12 +801,12 @@ impl> PositionsRef { } } -impl std::cmp::PartialEq> for PositionsRef
+impl std::cmp::PartialEq> for Positions
where DL: AsRef<[u8]>, DR: AsRef<[u8]>, { - fn eq(&self, other: &PositionsRef) -> bool { + fn eq(&self, other: &Positions) -> bool { let data_left = self.data.as_ref(); let data_right = other.data.as_ref(); let (data_large, data_small) = if data_left.len() >= data_right.len() { @@ -828,9 +826,9 @@ where } } -impl> std::cmp::Eq for PositionsRef {} +impl> std::cmp::Eq for Positions {} -impl> std::fmt::Debug for PositionsRef { +impl> std::fmt::Debug for Positions { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_list() .entries( @@ -842,7 +840,7 @@ impl> std::fmt::Debug for PositionsRef { } } -impl> Extend for PositionsRef { +impl> Extend for Positions { fn extend>(&mut self, iter: T) { for item in iter { self.set(item) @@ -869,7 +867,7 @@ impl Iterator for PositionsIter<'_> { } } -impl<'a, D> IntoIterator for &'a PositionsRef +impl<'a, D> IntoIterator for &'a Positions where D: AsRef<[u8]>, { @@ -893,11 +891,11 @@ mod tests { scorer: &dyn Scorer, ctx: &H::Context, haystack: H, - ) -> Option<(Score, Positions)> { + ) -> Option<(Score, Positions>)> { let mut target: Vec = Vec::new(); haystack.haystack_scope(ctx, |char| target.extend(char::to_lowercase(char))); let mut score = Score::MIN; - let mut positions = Positions::new(target.len()); + let mut positions = Positions::new_owned(target.len()); scorer .score_ref(target.as_slice(), &mut score, positions.as_mut()) .then_some((score, positions)) @@ -931,11 +929,11 @@ mod tests { assert!(subseq(&[], &one)); } - fn ps(items: impl AsRef<[usize]>) -> Positions { + fn ps(items: impl AsRef<[usize]>) -> Positions> { match items.as_ref().iter().max() { - None => Positions::new(0), + None => Positions::new_owned(0), Some(max) => { - let mut positions = Positions::new(max + 1); + let mut positions = Positions::new_owned(max + 1); positions.extend(items.as_ref().iter().copied()); positions } diff --git a/sweep-lib/src/widgets.rs b/sweep-lib/src/widgets.rs index e4b5802..46ddbb0 100644 --- a/sweep-lib/src/widgets.rs +++ b/sweep-lib/src/widgets.rs @@ -1,7 +1,7 @@ use crate::{ common::{AbortJoinHandle, LockExt}, FieldSelector, Haystack, HaystackBasicPreview, HaystackDefaultView, HaystackPreview, - PositionsRef, + Positions, }; use anyhow::Context; use futures::{future, FutureExt, TryFutureExt}; @@ -307,7 +307,7 @@ impl Haystack for ActionDesc { fn view( &self, ctx: &Self::Context, - positions: PositionsRef<&[u8]>, + positions: Positions<&[u8]>, theme: &Theme, ) -> Self::View { let mut chords_text = Text::new(); @@ -328,7 +328,7 @@ impl Haystack for ActionDesc { fn preview( &self, _ctx: &Self::Context, - _positions: PositionsRef<&[u8]>, + _positions: Positions<&[u8]>, _theme: &Theme, ) -> Option { let desc = Text::new().put_fmt(&self.description, None).take();