Skip to content

Commit

Permalink
Merge pull request #3 from nomad/fast-single-char-queries
Browse files Browse the repository at this point in the history
fzf-v2: add fast path for single-char queries
  • Loading branch information
noib3 authored Nov 24, 2023
2 parents a1d1ddb + 53144b7 commit 89f8247
Showing 1 changed file with 57 additions and 0 deletions.
57 changes: 57 additions & 0 deletions src/algos/fzf/fzf_v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,16 @@ impl Fzf for FzfV2 {

let opts = CandidateOpts::new(is_sensitive, self.normalization);

if pattern.char_len() == 1 {
return fuzzy_single_char::<RANGES>(
pattern.char(0),
candidate,
opts,
self.scheme(),
ranges,
);
}

let (match_offsets, last_match_offset) =
matches(&mut self.slab.matched_indices, pattern, candidate, opts)?;

Expand Down Expand Up @@ -507,3 +517,50 @@ fn matched_ranges(
}
}
}

/// TODO: docs
#[inline]
fn fuzzy_single_char<const RANGES: bool>(
pattern_char: char,
candidate: Candidate,
opts: CandidateOpts,
scheme: &Scheme,
ranges: &mut MatchedRanges,
) -> Option<Score> {
let mut max_score = 0;

let mut max_score_pos = 0;

for char_offset in
candidate.matches(pattern_char, opts.is_case_sensitive, opts.char_eq)
{
let prev_class = if char_offset == 0 {
scheme.initial_char_class
} else {
char_class(candidate.char(char_offset - 1), scheme)
};

let this_class = char_class(candidate.char(char_offset), scheme);

let bonus = compute_bonus(prev_class, this_class, scheme);

let score = bonus::MATCH + bonus * bonus::FIRST_QUERY_CHAR_MULTIPLIER;

if score > max_score {
max_score = score;
max_score_pos = char_offset;
}
}

if max_score == 0 {
return None;
}

if RANGES {
let start = candidate.to_byte_offset(max_score_pos);
let byte_len = candidate.char(max_score_pos).len_utf8();
ranges.insert(start..start + byte_len);
}

Some(max_score)
}

0 comments on commit 89f8247

Please sign in to comment.