You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
perf(fuzzy): match only the previous results when the query gets longer - #914
Fuzzy file search keeps the set of files that the last plain-text query matched. When the next query extends that query and the typo budget (len / 4, clamped to 2..=6) stays the same, the search matches only that set instead of all files. Adding or replacing file rows clears the cache. Each layer tracks its own candidates, and each query reapplies deletion and ranking filters.
Depends on #873. Regression tests compare incremental and cold results after compaction, same-size base replacement and restoration of a deleted file.
On a synthetic 100,000-file index with four search threads, Criterion measured the final keystroke at 17.44 ms with a cold query cache and 11.66 ms after typing the prefix. Prefix preparation is outside the timed interval. Each layer retains one 32-bit row number per matching candidate.
A path that matches a needle within k typos also matches every prefix of that needle within k typos, so the reduced set gives the same results. Scoring, filename fallback, sorting and pagination run unchanged on the matched files.
Chromium, ~500k files, max_threads = 4
main
this PR
typing, p50 per keystroke (2 runs)
28.4 / 31.3 ms
19.4 / 19.6 ms
typing, p90
54.0 / 55.8 ms
41.4 / 40.6 ms
typing, p99
99.9 / 81.4 ms
66.4 / 65.8 ms
single query, p50 (no previous query)
35.4 / 36.5 ms
36.3 / 35.2 ms
Typing = each of 60 file names typed one character at a time with a 40 ms gap. Single queries do not change, because they have no previous query to reuse.
Note
The cache applies only to plain-text queries without constraints. Multi-part queries (dir name) and queries with constraints (*.rs, status:modified) use the full search as before.
Correctness
New test incremental_typing_matches_full_search: 40k paths, typing with typos, backspace and a typo budget change. Each keystroke must give the same items, order and scores as a full search.
Chromium check: 11,163 keystrokes over 450 typing sessions, each compared with a full search on the same picker: 0 mismatches.
make test-rust and make lint-rust pass.
Cache invalidation
Event
Cache
file appended (watcher)
cleared
file restored after delete
cleared
full rescan / commit_new_sync / collect_files
cleared
get_file_mut (public)
cleared
file deleted
kept, deleted files are excluded from results
file count or base count changed
cache not used
Summary by CodeRabbit
New Features
Create and manage index layers, add paths with optional metadata, and save or load layer files.
Build a layer file independently or load a saved snapshot as the base index.
Node.js, Bun, and C interfaces provide layer management and indexing-completion checks.
Performance
Refined plain-text searches can reuse relevant matches from earlier queries; large searches also use optimized ranking and pagination.
Bug Fixes
File scans exclude .git metadata, shortened path reads preserve valid UTF-8, and deleted files are omitted from search results.
Auto reviews are disabled on base/target branches other than the default branch.
Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.
Run configuration
Source mode: Auto
Repository: Unavailable
Branch: Unavailable
File: No configuration file from this repository applied
Commit: Unavailable
Layers: Repository UI
Review profile: CHILL
Plan: Advanced
Run ID: 1d612367-10f5-4589-bed1-c99779b91f16
You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.
Use the checkbox below for a quick retry:
Trigger review
No actionable comments were generated in the recent review.
Walkthrough
The fuzzy scorer now reuses cached candidates for eligible incremental text queries. FilePicker stores the cache and clears it when indexed files or layers change.
Changes: Incremental fuzzy search
Layer / File(s)
Summary
Candidate reuse and scoring crates/fff-core/src/score.rs
The scorer stores per-layer candidates for eligible queries and reuses them for query prefixes. Deleted files remain candidates in the cache but are excluded from current scoring. Tests compare cached and uncached results.
FilePicker passes the cache to scoring and clears it when mutable file access, sync replacement, file additions, or layer operations can change indexed data.
Incremental-search validation and benchmarks crates/fff-core/tests/*, crates/fff-core/benches/fuzzy_search_bench.rs
Tests cover deleted files, overlay-layer changes, base replacement, and disk rescans. Benchmarks measure cold and warm incremental queries.
sequenceDiagram
participant FilePicker
participant FuzzyScorer
participant CandidateCache
FilePicker->>FuzzyScorer: Submit query and cache
FuzzyScorer->>CandidateCache: Read eligible prior candidates
CandidateCache-->>FuzzyScorer: Return candidates by layer
FuzzyScorer->>CandidateCache: Store current candidates
FuzzyScorer-->>FilePicker: Return scored results and updated cache
Loading
Possibly related PRs
dmtrKovalenko/fff#873: Introduces the layered-index APIs and layer operations that this change uses to maintain per-layer fuzzy-match candidates.
Suggested reviewers:gustav-fff
Merge Risk: Minimal · previous review 92892
No issue requiring a fix before merge was established.
Pre-merge checks: 4 · 1
Failed checks: 1 warning
Check name
Status
Explanation
Resolution
Docstring Coverage
Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta…
Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed checks: 4 passed
Check name
Status
Explanation
Title check
The title clearly and concisely describes the main performance change: reusing previous fuzzy-search results for longer queries.
Linked Issues check
Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check
Check skipped because no linked issues were found for this pull request.
Description Check
Check skipped - CodeRabbit’s high-level summary is enabled.
Full details: Docstring Coverage
Explanation
Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 21 functions across 6 files.
Resolution
Write docstrings for the functions missing them to satisfy the coverage threshold.
Finishing Touches
Generate docstrings
Commit to this branch
Create a new PR
🧪 Generate unit tests (beta)
Commit to this branch
Create a new PR
Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.
⚠️Unverified finding
Verification ran but could not confirm this finding. It is shown for review, not as a verified issue.
The "Spell Check with Typos" check flags "omnibx_veiw".
The typo is on purpose and the test needs it. The check reports veiw, so it will keep firing. Exclude this word in the typos config, or build the string so the checker does not see it (for example, concat!("omnibx_v", "eiw")).
Source: Linters/SAST tools
ℹ️ Review info⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Advanced
Run ID: ba059de0-006f-4a8d-ab3f-ba1caabbeccd
📥 Commits
Reviewing files that changed from the base of the PR and between f64bab2 and 616787f.
📒 Files selected for processing (2)
crates/fff-core/src/file_picker.rs
crates/fff-core/src/score.rs
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.
Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
code-reviewedReview completed; does not imply approval
1 participant
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fuzzy file search keeps the set of files that the last plain-text query matched. When the next query extends that query and the typo budget (
len / 4, clamped to 2..=6) stays the same, the search matches only that set instead of all files. Adding or replacing file rows clears the cache. Each layer tracks its own candidates, and each query reapplies deletion and ranking filters.Depends on #873. Regression tests compare incremental and cold results after compaction, same-size base replacement and restoration of a deleted file.
On a synthetic 100,000-file index with four search threads, Criterion measured the final keystroke at 17.44 ms with a cold query cache and 11.66 ms after typing the prefix. Prefix preparation is outside the timed interval. Each layer retains one 32-bit row number per matching candidate.
A path that matches a needle within
ktypos also matches every prefix of that needle withinktypos, so the reduced set gives the same results. Scoring, filename fallback, sorting and pagination run unchanged on the matched files.max_threads = 4mainTyping = each of 60 file names typed one character at a time with a 40 ms gap. Single queries do not change, because they have no previous query to reuse.
Note
The cache applies only to plain-text queries without constraints. Multi-part queries (
dir name) and queries with constraints (*.rs,status:modified) use the full search as before.Correctness
incremental_typing_matches_full_search: 40k paths, typing with typos, backspace and a typo budget change. Each keystroke must give the same items, order and scores as a full search.make test-rustandmake lint-rustpass.Cache invalidation
commit_new_sync/collect_filesget_file_mut(public)Summary by CodeRabbit
.gitmetadata, shortened path reads preserve valid UTF-8, and deleted files are omitted from search results.