Skip to content

feat: stream searches and add reproducible benchmarks - #41

Open
ParthJadhav wants to merge 1 commit into
masterfrom
codex/rust-search-overhaul
Open

feat: stream searches and add reproducible benchmarks#41
ParthJadhav wants to merge 1 commit into
masterfrom
codex/rust-search-overhaul

Conversation

@ParthJadhav

Copy link
Copy Markdown
Owner

Summary

  • make searches genuinely streaming with bounded memory, prompt cancellation, exact concurrent limits, and error-aware traversal
  • fix literal filename matching, strict searches without extensions, directory leakage, case-insensitive extensions, and repeated metadata reads
  • add lossless path results, multiple extensions, result-type selection, minimum depth, symlink, filesystem-boundary, thread-count, and early file-size controls
  • improve similarity sorting and update maintained dependencies while removing the direct regex dependency
  • add controlled and cross-tool benchmarks, expanded regression coverage, stronger CI, an MSRV, changelog, benchmark report, and product roadmap

Performance

On the same warm 100,000-file fixture, with equal 10,000-path outputs and 15 measured runs:

Revision Mean Range
This PR 57.1 ms 52.3–68.2 ms
260286c 78.1 ms 71.8–86.2 ms

That is a 1.37x throughput improvement.

The reproducible 50,000-file tool comparison verifies identical sorted sets of 5,000 paths before timing:

Tool Mean Range
rust_search 30.7 ms 29.9–33.2 ms
ripgrep --files 31.0 ms 30.1–32.2 ms
fd 35.0 ms 33.2–37.7 ms
find 95.9 ms 88.1–99.0 ms

See BENCHMARKS.md for the environment, methodology, caveats, internal timings, and reproduction commands.

Compatibility

This corrects two behaviors that callers may have observed despite the documented API:

  • default searches now consistently return files and links instead of sometimes including directories
  • search_input is now literal text instead of implicitly interpreting regex punctuation

Search construction also returns before traversal completes. These changes are documented in CHANGELOG.md; maintainers should consider whether the next publication warrants a major version.

Verification

  • 49 unit and integration tests
  • 24 doctests
  • macOS symlink and traversal tests
  • Linux-only non-UTF-8 path regression test in CI
  • cargo fmt --all -- --check
  • cargo clippy --all-targets -- -D warnings
  • rustdoc with warnings denied
  • Rust 1.88 MSRV check
  • packaged-crate compilation
  • exact cross-tool result-set parity before benchmarks

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 59bb0a46d7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/search.rs
Comment on lines +363 to +365
if !matcher.is_match(&entry) {
return WalkState::Continue;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Cancel dropped searches before finding a match

When a query has no matches in a large tree, dropping the iterator only disconnects the result receiver, but this branch never observes that disconnection and continues walking every entry. Since channel failure is checked only while sending a match or traversal error, rare- or no-match searches can leave detached walker threads consuming filesystem I/O long after callers stop using them, contrary to the documented prompt cancellation behavior.

Useful? React with 👍 / 👎.

Comment thread src/search.rs
Comment on lines +395 to +396
if types
.add("rust-search-extension", &format!("*.{extension}"))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Escape extensions before installing the glob prefilter

On filesystems that permit glob metacharacters in extensions, inputs such as .ext("?") or .ext("*") are interpreted as glob patterns rather than literal suffixes. TypesBuilder::add accepts these patterns, after which extension_prefiltered causes the exact extension comparison to be skipped, so ? matches every one-character extension and * matches arbitrary extensions; the prefilter must escape user input or retain the literal matcher.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant