Skip to content

TreeDB: route RaBitQ search via HNSW pack - #2603

Open
snissn wants to merge 6 commits into
mainfrom
snissn/2587-manager
Open

TreeDB: route RaBitQ search via HNSW pack#2603
snissn wants to merge 6 commits into
mainfrom
snissn/2587-manager

Conversation

@snissn

@snissn snissn commented Jun 11, 2026

Copy link
Copy Markdown
Owner

Objective

Fixes #2587. Route eligible TreeDB rabitq_1bit quantized_only and quantized_rerank searches through the prepared hnsw_search_pack_v1 traversal seam with a RaBitQ score plane.

Context

RaBitQ was still using the quantized column-graph traversal path after the pack traversal seam landed. This PR reuses that seam for RaBitQ so traversal/scoring counters and exact-read guardrails line up with the prepared pack route while preserving existing RaBitQ v1 scorer semantics.

Current delta against origin/main

origin/main moved during review and now contains the parallel RaBitQ pack-route implementation from #2606. After merging latest main (ae23f683e), this PR's remaining diff is intentionally small:

  • remove production-mode full-diagnostics forcing from the RaBitQ pack traversal (StatsMode: opts.StatsMode);
  • keep the traversal-breadth/rerank test in VectorIndexSearchStatsModeFullDiagnostics;
  • keep the Windows heap-fallback-safe rerank counter assertion.

The design/evidence below documents the full #2587 route work and the guardrails this PR preserves.

Non-goals

  • No RaBitQ v2 / BRQ / multi-bit codec work.
  • No durable format, codec identity, or stored asset migration.
  • No scalar_u8 route change.
  • No exact-FP32 route change.
  • No speedup claim versus exact FP32 or scalar_u8 beyond same-host context rows below.

Design

  • Adds a RaBitQ-specific prepared-pack route in column_hnsw_rabitq_prepared_search.go.
  • Selects the route only when the query mode is quantized, the selected quantized index is rabitq_1bit v1, stats mode is supported, and the hnsw_search_pack_v1 asset is direct/heap healthy.
  • quantized_only uses pack traversal with the RaBitQ quantized score plane and keeps exact vector/norm reads at zero.
  • quantized_rerank traverses the full configured efSearch breadth with the RaBitQ score plane, trims only the retained shortlist, then exact-reranks that shortlist from prepared pack FP32 vectors.
  • Scalar U8 remains on the existing column-graph prepared route; exact FP32 remains on the existing pack route.
  • Production stats stay production-minimal; tests that assert traversal breadth request full diagnostics explicitly.

Hard invariant statement: this PR does not intentionally change the RaBitQ v1 durable layout, LSB-first bit order, padding semantics, weighted sign-dot score formula, codec name/version/config identity, durable asset identity, or fail-closed behavior for invalid/unavailable RaBitQ assets.

Correctness / tests

Latest pushed head: 21f57662d (merges latest origin/main ae23f683e; PR functional product code remains the 2cb1baee0 RaBitQ route plus the Windows heap-fallback test expectation fix).

Local checks on 21f57662d:

git diff --check origin/main...HEAD
GOWORK=off go test ./TreeDB/collections -run '^TestRabitQPreparedHNSWSearchPackRerankPreservesEfTraversal2587$' -count=1
GOWORK=off go test ./TreeDB/internal/rabitq ./TreeDB/collections ./cmd/treedb_vector_search_demo ./TreeDB/documentservice -count=1
GOWORK=off go test ./TreeDB/collections -race -run '^TestCollectionSearchVectorIndexWithBufferRabitQConcurrentPreparedPack2587$' -count=1

GitHub status check rollup is green on 21f57662d after merging latest origin/main.

Coverage added/updated:

  • RaBitQ prepared-pack parity against the existing v1 SearchCosine scorer.
  • Eligible RaBitQ reports SearchRouteHNSWSearchPack=1 / HNSWSearchPackActive=1 and avoids column-graph fallback counters.
  • Scalar U8 stays on the column-graph prepared route.
  • quantized_only exact vector/norm reads remain zero.
  • quantized_rerank exact calls/read bytes are limited to the retained shortlist; pack rerank may report NormBytesRead=0 because norms come from prepared pack vectors.
  • Concurrent collection prepared-pack route race coverage.
  • Documentservice benchmark validator accepts the quantized pack route stats.
  • Demo expectations accept the RaBitQ prepared-pack route.

Benchmark evidence

Baseline for collected route benchmarks: origin/main 7f6689046. Candidate functional code: 2cb1baee0; after #2606 reached main, the latest PR diff is the production-stats/test correction described above, so these benchmark rows are retained as route evidence rather than rerun for the now-small delta.

Clean hot-cache matrix (-benchtime=100000x -count=5, same Apple M3 host) showed RaBitQ pack-route counters active and hot rows at 0 B/op, 0 allocs/op:

  • Direct RaBitQ SearchWithBuffer: quantized_only c=1/c=8 and quantized_rerank c=1 were statistically neutral; quantized_rerank c=8 improved 6.388µ -> 3.631µ (-43.16%).
  • Collection RaBitQ SearchVectorIndexWithBuffer: quantized_only improved c=1 26.46µ -> 13.45µ (-49.16%) and c=8 7.251µ -> 3.989µ (-44.99%); quantized_rerank c=1/c=8 were statistically neutral in that run.
  • Route/resource guardrails: hnsw_search_pack_active/search=1, hnsw_search_pack_fallbacks/search=0, quantized_only norm_B/search=0, and rerank exact score calls stayed at the configured shortlist.

Production-gate matrix (BenchmarkCollectionVectorQuantizedProductionGate2591, -benchtime=10000x -count=5) also kept hot RaBitQ rows at 0 B/op, 0 allocs/op; production timings were mixed/noisy after restoring full efSearch traversal for rerank correctness, with collection quantized_rerank c=1 still improving 189.8µ -> 91.3µ (-51.9%). Exact-FP32 code is unchanged; exact rows are treated as guardrail/CI coverage rather than promoted as a speedup.

Risk notes

  • Route is fail-closed: if the pack asset is missing/stale/invalid or stats mode is unsupported, existing fallback paths remain available.
  • The Windows CI fix in the latest commit only relaxes a test assumption for heap-copy fallback prepared-score counters; it does not change product code.
  • No migration/backward compatibility scaffolding is needed because no durable format changes are introduced.

Summary by CodeRabbit

  • Bug Fixes

    • Corrected search statistics mode handling in vector index prepared search operations to respect user-configured settings directly.
  • Tests

    • Updated test diagnostics to capture full statistics during vector search pack and fallback comparisons.

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 00251b80-6667-42c5-8453-9b76b53360b1

📥 Commits

Reviewing files that changed from the base of the PR and between ae23f68 and 21f5766.

📒 Files selected for processing (2)
  • TreeDB/collections/column_hnsw_rabitq_prepared_search.go
  • TreeDB/collections/column_vector_graph_rabitq_quantized_asset_test.go

📝 Walkthrough

Walkthrough

This PR removes stats-mode normalization from the RaBitQ prepared HNSW search path. Previously, minimal stats requests were automatically upgraded to full diagnostics; now the caller's StatsMode is passed through directly. The supporting test is updated to explicitly request full diagnostics and refine the rerank assertion message.

Changes

Stats Mode Pass-Through

Layer / File(s) Summary
Stats mode pass-through in prepared traversal
TreeDB/collections/column_hnsw_rabitq_prepared_search.go
Removes the traversalStatsMode normalization logic; columnHNSWPreparedTraversalOptions.StatsMode now assigned directly from opts.StatsMode without upgrading minimal stats to full diagnostics.
Test diagnostics and rerank assertion update
TreeDB/collections/column_vector_graph_rabitq_quantized_asset_test.go
Test now explicitly sets StatsMode to VectorIndexSearchStatsModeFullDiagnostics for pack/fallback comparisons; pack-path rerank assertion message updated to clarify "pack rerank prepared score calls" expectation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related issues

  • #2587 — This PR implements the stats-mode handling for the prepared pack-style HNSW traversal seam for RaBitQ, directly supporting the goal of routing rabitq_1bit search through the prepared traversal path while preserving quantized semantics and measuring overhead.

Poem

A rabbit removes the stats mode veil,
Pass it through, let it not fail,
Tests now ask for diagnostics bright,
Prepared traversals see full light, 🐇✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'TreeDB: route RaBitQ search via HNSW pack' is directly related to the main change: routing TreeDB rabitq_1bit searches through prepared hnsw_search_pack_v1 traversal with RaBitQ scoring, which matches the core objective of PR #2587.
Linked Issues check ✅ Passed The changes directly implement the core objective to route rabitq_1bit quantized_only and quantized_rerank searches through prepared pack-style traversal [#2587], removing production-mode diagnostics forcing and preserving RaBitQ v1 semantics as required.
Out of Scope Changes check ✅ Passed All changes are scoped to RaBitQ pack-route implementation and test adjustments: removing StatsMode normalization in production code and updating test expectations for diagnostics and Windows heap-fallback behavior—all directly within #2587 objectives.

✏️ 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 snissn/2587-manager

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.

@snissn

snissn commented Jun 11, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@snissn

snissn commented Jun 11, 2026

Copy link
Copy Markdown
Owner Author

@copilot review

@snissn

snissn commented Jun 11, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

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.

@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: 328e39a1e0

ℹ️ 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".

if err != nil && searchStats.QuantizedScorerActive == 0 && searchStats.QuantizedScoreCalls == 0 {
p.routeStats.apply(&response.Stats)
} else {
vectorIndexSearchRouteStatsForHNSWSearchPackRoute(reader.hnswSearchPack.routeStats(reader.hnswSearchPackStatus, reader.hnswSearchPackOpenNanos)).apply(&response.Stats)

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 Preserve benchmark route contract for RaBitQ

When SearchBenchmarkVector calls Collection.SearchVectorIndexWithBuffer for a rabitq_1bit quantized query, this new branch now returns SearchRouteHNSWSearchPack=1 here; for rerank it also reports NormBytesRead=0 because exact reads come from the pack. The existing validateBenchmarkQuantizedVectorSearchRoute in TreeDB/documentservice/service.go still rejects any quantized response that touches HNSW pack counters and requires nonzero norm reads for rerank, so RaBitQ benchmark requests that previously passed now fail closed with CodeIndexUnavailable. Please either keep the service path on the old column-graph route or update the benchmark validator/diagnostics for the new RaBitQ pack route.

Useful? React with 👍 / 👎.

@snissn

snissn commented Jun 11, 2026

Copy link
Copy Markdown
Owner Author

Latest head is 8342f02 (test expectation update only after CI failure); CI is running again. @codex review

@snissn

snissn commented Jun 11, 2026

Copy link
Copy Markdown
Owner Author

Latest head is 8342f02 (test expectation update only after CI failure); CI is running again. @copilot review

@snissn

snissn commented Jun 11, 2026

Copy link
Copy Markdown
Owner Author

Latest head is 8342f02 (test expectation update only after CI failure); CI is running again. @coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

@snissn Sure, I'll kick off a review of the latest head 8342f02a8. Since this is noted as a test expectation update only after the CI failure, I'll focus the incremental review on any new changes in that commit.

✅ Action performed

Review finished.

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.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

ℹ️ 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".

@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: 53bba87cfc

ℹ️ 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 on lines +73 to +76
scorer, err := r.prepareRabitQQuantizedScorer(queryMode, opts.QuantizedIndexName, query, scratch)
if err != nil {
recordColumnVectorGraphQuantizedAssetErrorStats(&stats, err)
return nil, stats, err

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 Preserve query-validation errors before preparing RaBitQ scorer

When the new RaBitQ pack route is selected, malformed queries such as zero/NaN vectors reach prepareRabitQQuantizedScorer, whose EncodeQuery failure is wrapped as ErrVectorIndexSearchUnavailable and then recorded as a quantized asset error here. The previous SearchCosine path validated the query norm first and returned the query-norm error without marking the index asset invalid; in Collection.SearchVectorIndexWithBuffer this new unavailable error also causes the prepared quantized cache to be invalidated for a bad user query. Please validate the query norm before scorer preparation (as the legacy path does) so invalid input does not look like index corruption/unavailability.

Useful? React with 👍 / 👎.

@snissn

snissn commented Jun 11, 2026

Copy link
Copy Markdown
Owner Author

Latest head is 08b9e8a; PR body is updated and CI status check rollup is green. @codex review

@snissn

snissn commented Jun 11, 2026

Copy link
Copy Markdown
Owner Author

Latest head is 08b9e8a; PR body is updated and CI status check rollup is green. @copilot review

@snissn

snissn commented Jun 11, 2026

Copy link
Copy Markdown
Owner Author

Latest head is 08b9e8a; PR body is updated and CI status check rollup is green. @coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

@snissn Sure! Kicking off the review of the latest head 08b9e8a40 now. I'll do a full incremental pass covering the RaBitQ prepared-pack route changes, the new column_hnsw_rabitq_prepared_search.go traversal seam, the quantized_only/quantized_rerank path selection logic, and the updated test expectations. I'll flag anything that looks off against the invariants stated in the PR description (scorer semantics, fail-closed behavior, no durable format changes, etc.).

✅ Action performed

Review finished.

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.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

ℹ️ 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".

# Conflicts:
#	TreeDB/collections/column_vector_graph_rabitq_quantized_asset_test.go
@snissn

snissn commented Jun 11, 2026

Copy link
Copy Markdown
Owner Author

Latest head is 21f5766 after merging origin/main; PR body is updated with the current small delta and CI status check rollup is green. @codex review

@snissn

snissn commented Jun 11, 2026

Copy link
Copy Markdown
Owner Author

Latest head is 21f5766 after merging origin/main; PR body is updated with the current small delta and CI status check rollup is green. @copilot review

@snissn

snissn commented Jun 11, 2026

Copy link
Copy Markdown
Owner Author

Latest head is 21f5766 after merging origin/main; PR body is updated with the current small delta and CI status check rollup is green. @coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

@snissn Sure! Kicking off the incremental review of the latest head 21f57662d now. Given that the remaining diff is intentionally small — restoring StatsMode: opts.StatsMode to production-minimal behavior, keeping the full-diagnostics test assertion, and fixing the Windows heap-fallback rerank counter expectation — I'll focus the pass on confirming those three deltas are correct and that no unintended changes slipped in during the merge of origin/main (ae23f683e).

✅ Action performed

Review finished.

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.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

ℹ️ 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".

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.

Route TreeDB rabitq_1bit search through prepared pack-style traversal

1 participant