Skip to content

⚡ Bolt: Reuse Uint8Array and fast O(K) reset for visited tracker#414

Open
AhmmedSamier wants to merge 1 commit intomasterfrom
bolt-fast-uint8array-reset-3281649880735625941
Open

⚡ Bolt: Reuse Uint8Array and fast O(K) reset for visited tracker#414
AhmmedSamier wants to merge 1 commit intomasterfrom
bolt-fast-uint8array-reset-3281649880735625941

Conversation

@AhmmedSamier
Copy link
Copy Markdown
Owner

@AhmmedSamier AhmmedSamier commented May 5, 2026

💡 What:
Replaced the per-search allocation of new Uint8Array(this.items.length) in SearchEngine.performUnifiedSearch with a reusable, class-level visitedBuffer and a visitedTracker array for fast O(K) clearing.

🎯 Why:
In the hot path of searching (especially burst/continuous searching), allocating a large array (proportional to total workspace items) and subsequently garbage collecting it creates significant memory pressure and pauses.

📊 Impact:
Reduces array allocation overhead on every search query to zero. The buffer is now cleared in O(K) time where K is only the number of items actually visited during the search, not the total size of the workspace items array. The burst search benchmark for "No match" scenario stays basically the same or slightly faster while avoiding huge memory swings.

🔬 Measurement:
Run cd language-server && bun run benchmarks/search_burst.bench.ts and verify memory usage metrics/execution times.


PR created automatically by Jules for task 3281649880735625941 started by @AhmmedSamier

Summary by CodeRabbit

  • Performance Improvements

    • Optimized search engine memory usage by reusing allocation buffers across repeated searches instead of creating new ones each time, reducing overhead and improving performance.
  • Tests

    • Added benchmark results documenting search performance metrics across various scenarios.

…rch engine

Co-authored-by: AhmmedSamier <17784876+AhmmedSamier@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 5, 2026

📝 Walkthrough

Walkthrough

The search engine is refactored to eliminate per-search allocations of a visited tracking array by reusing an instance-level visitedBuffer (Uint8Array) and visitedTracker (number array). Helper methods switch from accepting an optional visited array parameter to a useVisited boolean flag that references the reusable instance state, which is cleared only after each search completes via try/finally cleanup.

Changes

Search Engine Deduplication Buffer Reuse

Layer / File(s) Summary
Data Structure
language-server/src/core/search-engine.ts
Instance fields visitedBuffer: Uint8Array and visitedTracker: number[] are added to track and reuse deduplication state across multiple searches.
Core Implementation
language-server/src/core/search-engine.ts
performUnifiedSearch is refactored to compute useVisited, lazily allocate/resize visitedBuffer on demand, run searches with the boolean flag, and use try/finally to reset visited marks only for tracked indices before clearing the tracker.
Helper Methods
language-server/src/core/search-engine.ts
searchWithIndices and searchAllItems replace the optional visited?: Uint8Array parameter with useVisited: boolean, consulting and updating this.visitedBuffer and this.visitedTracker directly when deduplication is enabled.
Embedded Patch
language-server/apply_patch.sh
Patch file documenting the full implementation details of the reusable buffer mechanism and state management logic.
Benchmark Results
language-server/benchmarks/results_burst.json
Benchmark results for "Burst Search" scenarios ("App", "Zzz", "S") with timing statistics (avgMs, totalMs, minMs, maxMs, p95Ms, stdDevMs).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • AhmmedSamier/DeepLens#371: Directly modifies language-server/src/core/search-engine.ts to replace per-search index tracking with Uint8Array-based marker arrays in performUnifiedSearch and helper methods.
  • AhmmedSamier/DeepLens#344: Replaces SearchEngine's heavier index-deduplication structures (Set/new per-call Uint8Array) with Uint8Array-based tracking, which this PR further optimizes by introducing a reusable instance-level buffer.
  • AhmmedSamier/DeepLens#368: Modifies language-server/src/core/search-engine.ts to replace Set-based visited tracking with Uint8Array-based presence tracking; this PR extends that optimization with buffer reuse and signature changes to helper methods.

Poem

🐰 A rabbit hops through the warren with glee,

One tunnel reused instead of made new—

No waste of fresh burrows, just one buffer so free,

Each search leaves no footprints once searches are through! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main optimization: reusing a Uint8Array and implementing a fast O(K) reset mechanism for the visited tracker, which directly aligns with the changeset's core purpose of eliminating per-search allocations and reducing GC pressure.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bolt-fast-uint8array-reset-3281649880735625941

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@language-server/src/core/search-engine.ts`:
- Around line 186-187: The clear() method currently doesn't reset the reusable
visited state, leaving a previously large Uint8Array retained; update the
clear() implementation to explicitly reset the visitedBuffer to a new
Uint8Array(0) and visitedTracker to an empty array (visitedBuffer = new
Uint8Array(0); visitedTracker = [];), alongside the existing cache/field resets
so the engine truly frees that memory when clearing state.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 28d062d2-9c1f-413a-acdd-baa042fd7c94

📥 Commits

Reviewing files that changed from the base of the PR and between 0b051a9 and 6917058.

📒 Files selected for processing (3)
  • language-server/apply_patch.sh
  • language-server/benchmarks/results_burst.json
  • language-server/src/core/search-engine.ts

Comment on lines +186 to +187
private visitedBuffer: Uint8Array = new Uint8Array(0);
private visitedTracker: number[] = [];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Reset reusable visited state when clearing engine state.

clear() (Line 756 onward) doesn’t reset the new visitedBuffer/visitedTracker, so a previously large Uint8Array can stay retained after a full clear. Please clear these alongside other caches.

💡 Proposed fix
     clear(): void {
         this.items = [];
@@
         this.inactiveFileItems = [];
+        this.visitedBuffer = new Uint8Array(0);
+        this.visitedTracker = [];
         this.invalidateDerivedCaches();
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@language-server/src/core/search-engine.ts` around lines 186 - 187, The
clear() method currently doesn't reset the reusable visited state, leaving a
previously large Uint8Array retained; update the clear() implementation to
explicitly reset the visitedBuffer to a new Uint8Array(0) and visitedTracker to
an empty array (visitedBuffer = new Uint8Array(0); visitedTracker = [];),
alongside the existing cache/field resets so the engine truly frees that memory
when clearing state.

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