Repository navigation
fix(vector): rebuild after an admitted one is no longer deferred forever at 10M (#7260) - #9289
Conversation
…instead of deferring a rebuild (#7260) The online rebuild gate priced a rebuild as the new graph plus the old on-heap graph resident, so once the delta buffer outgrew a heap of ~2x the graph every later rebuild was deferred and the delta scan grew without bound. When that estimate does not fit, the gate now swaps the resident graph for its certified on-disk copy (same ordinals), re-prices the build against what the copy costs, and admits it. The deferral WARNING is also logged once per streak.
|
This pull request does not currently match the merge queue conditions, so it cannot be queued from here. The box comes back if it matches again. |
ReviewOverall a well-reasoned fix: the swap only happens once the rebuild is admitted, the identity check via `persistedGraphSource` is a safe certification, and `persistedGraphSource` is cleared when a build publishes. Comments below, roughly by importance. Correctness / risk
Minor
Tests
Style follows the surrounding code and the `assertThat(...).isTrue()` convention. No new dependencies, nothing security-sensitive. |
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 17 |
🟢 Coverage 81.91% diff coverage · -5.75% coverage variation
Metric Results Coverage variation ✅ -5.75% coverage variation Diff coverage ✅ 81.91% diff coverage Coverage variation details
Coverable lines Covered lines Coverage Common ancestor commit (cbf701d) 214016 182272 85.17% Head commit (bedfadc) 246709 (+32693) 195926 (+13654) 79.42% (-5.75%) Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch:
<coverage of head commit> - <coverage of common ancestor commit>Diff coverage details
Coverable lines Covered lines Diff coverage Pull request (#9289) 94 77 81.91% Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified:
<covered lines added or modified>/<coverable lines added or modified> * 100%
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (5)
Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 2 remain after this review. 📝 WalkthroughWalkthroughOnline vector-index rebuild admission can replace an eligible resident on-heap graph with its certified persisted on-disk twin when the rebuild does not fit the ordinary heap estimate. Heap-budget calculations now accept supplied measurements, and metrics and regression tests cover demotion and deferral behavior. ChangesOnline Rebuild Admission
Priority: ➖ Normal Estimated code review effort: 4 (Complex) | ~45 minutes Change: Bug fix · Severity of issue fixed: Medium Sequence Diagram(s)sequenceDiagram
participant LSMVectorIndex
participant VectorHeapBudget
participant PersistedGraph
participant LSMVectorIndexMetrics
LSMVectorIndex->>VectorHeapBudget: Estimate rebuild with the resident graph
alt Ordinary estimate does not fit
LSMVectorIndex->>PersistedGraph: Load the certified on-disk twin
PersistedGraph-->>LSMVectorIndex: Return the twin and node upper bound
LSMVectorIndex->>VectorHeapBudget: Estimate rebuild with the twin retained
alt Revised estimate fits and graph identity is unchanged
LSMVectorIndex->>LSMVectorIndex: Swap the resident graph under the write lock
LSMVectorIndex->>LSMVectorIndexMetrics: Increment resident graph demotions
else Revised estimate does not fit or eligibility fails
LSMVectorIndex->>LSMVectorIndex: Record a memory deferral
end
end
Suggested reviewers: Merge Risk: ⚪ Minimal · up to No actionable issue remains from this review; the change is mergeable after normal checks. Security Architecture ReviewSecurity architecture risk: 🟡 Moderate · up to The change includes identity checks and failure cleanup, but a new reference can keep an old graph alive during a rebuild intended to release it first. This can weaken protection against memory exhaustion. No new access or privilege boundary was established. Retained concerns
Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 4 | ❓ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 33 functions across 4 files. (1 skipped: 1 too large.) ✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
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. Comment |
ReviewOverall a well-reasoned fix with good comments and a pinned-heap test overload. A few points: Correctness / risk
Quality
Tests Security / performance: no security concerns. Search latency during demotion is the documented trade-off; the new Nice work; mainly worth checking items 1 and 3. |
…t was published (#7260)
ReviewThe approach is sound. Demoting to the certified persisted twin, with identity tracked by Potential issues
Style / minor
TestsCoverage of the happy path, the uncertified-twin path and the swap-not-applied path looks good. I would add:
Overall: good fix. Item 1 is the one I would resolve before merging. |
…, reset the deferral streak on admission (#7260)
ReviewThe approach is sound: demoting to the certified persisted twin, tracked by reference identity, and changing nothing unless the rebuild is admitted. Most of the concerns below are about the heap-credit logic. Potential bugs
Code quality
Tests
Performance and securityNo security concerns. The page-read search latency during demotion is documented and exposed via the new Overall this looks good. I would fix item 1 before merging. |
… the budget arithmetic (#7260)
ReviewThe approach is sound. The demotion swaps the resident graph only once the rebuild is certain to be admitted. Points to consider
Overall: logic looks correct and well documented. Items 1, 3 and 6 are the ones I would address before merge. 🤖 Generated with Claude Code |
…g, wrap a long log line (#7260)
|
Review of #9289 (resident graph demotion for deferred rebuilds) Solid, carefully reasoned fix. Tracking the persisted twin by reference identity ( Points to consider
Tests: No security concerns. Performance is fine: the path only runs on an admission miss, and costs one graph load plus a lock acquisition. Nice work, only minor items above. |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #9289 +/- ##
=========================================
Coverage 76.93% 76.93%
+ Complexity 3982 3981 -1
=========================================
Files 2128 2128
Lines 214016 214105 +89
Branches 45541 45560 +19
=========================================
+ Hits 164656 164729 +73
- Misses 31781 31789 +8
- Partials 17579 17587 +8 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…ted from the shipped 26.10.1 wheel (#228) The 46 per-test-file pages under development/testing/ restated the tests' own names and docstrings and had drifted (a wrong auto-transaction default, a skip that does not exist, a marker table missing a test, 12 of 62 test files absent from the overview). They are replaced by one development/testing.md with a table of every test file, the markers, the zero-skips gate as it is now, what the docs tests run, and the section on writing a test. Also removed: examples/basic.md, examples/import.md, examples/vectors.md (pointers that examples/index.md and the guide already cover) and getting-started/distributions.md (merged into installation.md; its two needles leave tests/test_docs_examples.py with it). Known issues and the vectors guide now say what is true for the shipped wheel: upstream ArcadeData#9277, ArcadeData#9278, ArcadeData#9281, and ArcadeData#7260 are fixed upstream for 26.11.1 (PRs ArcadeData#9288 and ArcadeData#9289) and still present in 26.10.1; ArcadeData#9290 is still open. The JPype entries no longer say the wheel installs 1.7.1 (it declares jpype1>=1.5.0). API, guide, and development pages: removed pre-26.10.1 workaround history for bugs the wheel ships fixed, sections that duplicated the guide, and wrong statements found against the source (schema of_type, set_wal_flush, troubleshooting entries, type-mapping table, wheel and server-stack sizes measured on the 26.10.1 wheel). Hunks that open PR #164 also touches are left alone. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ubz3m6QXHESerCkehC1qgi
…ted from the shipped 26.10.1 wheel (#228) The 46 per-test-file pages under development/testing/ restated the tests' own names and docstrings and had drifted (a wrong auto-transaction default, a skip that does not exist, a marker table missing a test, 12 of 62 test files absent from the overview). They are replaced by one development/testing.md with a table of every test file, the markers, the zero-skips gate as it is now, what the docs tests run, and the section on writing a test. Also removed: examples/basic.md, examples/import.md, examples/vectors.md (pointers that examples/index.md and the guide already cover) and getting-started/distributions.md (merged into installation.md; its two needles leave tests/test_docs_examples.py with it). Known issues and the vectors guide now say what is true for the shipped wheel: upstream ArcadeData#9277, ArcadeData#9278, ArcadeData#9281, and ArcadeData#7260 are fixed upstream for 26.11.1 (PRs ArcadeData#9288 and ArcadeData#9289) and still present in 26.10.1; ArcadeData#9290 is still open. The JPype entries no longer say the wheel installs 1.7.1 (it declares jpype1>=1.5.0). API, guide, and development pages: removed pre-26.10.1 workaround history for bugs the wheel ships fixed, sections that duplicated the guide, and wrong statements found against the source (schema of_type, set_wal_flush, troubleshooting entries, type-mapping table, wheel and server-stack sizes measured on the 26.10.1 wheel). Hunks that open PR #164 also touches are left alone. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ubz3m6QXHESerCkehC1qgi
…ted from the shipped 26.10.1 wheel (#229) * docs: retire stale and duplicate Python bindings pages, fix what drifted from the shipped 26.10.1 wheel (#228) The 46 per-test-file pages under development/testing/ restated the tests' own names and docstrings and had drifted (a wrong auto-transaction default, a skip that does not exist, a marker table missing a test, 12 of 62 test files absent from the overview). They are replaced by one development/testing.md with a table of every test file, the markers, the zero-skips gate as it is now, what the docs tests run, and the section on writing a test. Also removed: examples/basic.md, examples/import.md, examples/vectors.md (pointers that examples/index.md and the guide already cover) and getting-started/distributions.md (merged into installation.md; its two needles leave tests/test_docs_examples.py with it). Known issues and the vectors guide now say what is true for the shipped wheel: upstream ArcadeData#9277, ArcadeData#9278, ArcadeData#9281, and ArcadeData#7260 are fixed upstream for 26.11.1 (PRs ArcadeData#9288 and ArcadeData#9289) and still present in 26.10.1; ArcadeData#9290 is still open. The JPype entries no longer say the wheel installs 1.7.1 (it declares jpype1>=1.5.0). API, guide, and development pages: removed pre-26.10.1 workaround history for bugs the wheel ships fixed, sections that duplicated the guide, and wrong statements found against the source (schema of_type, set_wal_flush, troubleshooting entries, type-mapping table, wheel and server-stack sizes measured on the 26.10.1 wheel). Hunks that open PR #164 also touches are left alone. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ubz3m6QXHESerCkehC1qgi * docs: testing.md says a strict xfail fires when the fix reaches the engine the suite runs on, which CI builds from upstream's snapshot jars (#228) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ubz3m6QXHESerCkehC1qgi * docs: known issues says ArcadeData#9290 is fixed upstream (ArcadeData#9299, 26.11.1) and the tripwires are plain regression tests that fail on the 26.10.1 wheel (#228) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ubz3m6QXHESerCkehC1qgi --------- Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
…et" (#335) The weekly docs pass (2026-10-19) found the bindings docs still describing six engine fixes as "fixed for 26.11.1, which is not released yet". Each fix's merge commit is an ancestor of the 26.10.2 tag (e5040d0), so 26.10.2 carries them all. - known-issues.md: the six entries leave the page by its own rule and are listed under "Fixed in 26.10.2"; the ArcadeData#9228, ArcadeData#9289 and light_edges notes in the guide and API pages, the wheel sizes (70.2 MiB download, 97.8 MiB unpacked, computed from the PyPI file) and the test docstrings follow. - test_bridge_fixes: from ArcadeData#10253 the engine's Result.toJSON writes an undeclared LocalDate as days since the epoch, as it already wrote a declared DATE on 26.10.2. to_json_list keeps its documented midnight-UTC milliseconds (the #116 fix); the test no longer requires the two to be equal, and results.md stops saying they are. - sync-upstream.sh --help prints the real path lists (it named 1 of 5 fork-owned paths and 4 of 7 allowlisted workflows); release.md and upstream-bindings-pr.md: a dead anchor, a wrong step number, an optional argument shown as required. - FAIRNESS.md: a probe path that is not in the repository; PAGE-SPEC.md: f3_sparse_perquery exists and is skipped, not unbuilt. Closes #335. Closes #99: its cause, ArcadeData#9694, is fixed by ArcadeData#9703, which 26.10.2 carries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…et" (#335) (#336) The weekly docs pass (2026-10-19) found the bindings docs still describing six engine fixes as "fixed for 26.11.1, which is not released yet". Each fix's merge commit is an ancestor of the 26.10.2 tag (e5040d0), so 26.10.2 carries them all. - known-issues.md: the six entries leave the page by its own rule and are listed under "Fixed in 26.10.2"; the ArcadeData#9228, ArcadeData#9289 and light_edges notes in the guide and API pages, the wheel sizes (70.2 MiB download, 97.8 MiB unpacked, computed from the PyPI file) and the test docstrings follow. - test_bridge_fixes: from ArcadeData#10253 the engine's Result.toJSON writes an undeclared LocalDate as days since the epoch, as it already wrote a declared DATE on 26.10.2. to_json_list keeps its documented midnight-UTC milliseconds (the #116 fix); the test no longer requires the two to be equal, and results.md stops saying they are. - sync-upstream.sh --help prints the real path lists (it named 1 of 5 fork-owned paths and 4 of 7 allowlisted workflows); release.md and upstream-bindings-pr.md: a dead anchor, a wrong step number, an optional argument shown as required. - FAIRNESS.md: a probe path that is not in the repository; PAGE-SPEC.md: f3_sparse_perquery exists and is skipped, not unbuilt. Closes #335. Closes #99: its cause, ArcadeData#9694, is fixed by ArcadeData#9703, which 26.10.2 carries. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Fixes #7260.
Problem
The online rebuild gate charged the freshly built on-heap graph as resident for the whole next build. Once the buffered writes of a long first rebuild outgrew what a heap of ~2x the graph can hold beside a second graph, every later rebuild was deferred and the delta scan grew without bound.
Fix
admitOnlineRebuildswaps the resident on-heap graph for its certified persisted twin (same ordinals; identity tracked bypersistedGraphSource), re-prices the build against what the twin costs, and admits it. Nothing is changed unless the rebuild is admitted, and searches keep working (reading topology from pages until the replacement publishes).residentGraphDemotions.Tests
Issue7260ResidentGraphDemotionTest(heap figures pinned via a package-private overload, no 24 GB fixture).Summary by CodeRabbit