[Core] Batch canonical replay SQLite probes - #149
Open
tommy0103 wants to merge 3 commits into
Open
Conversation
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
Scope
index_stateKey Changes
packages/core/src/persist.tsactivates bounded replay filtering once a stream reaches 250 records, prefetches canonical rows in key-safe batches, and sends only new or changed exact-value records through the existing UPSERTs.delete-sessionas a hard boundary, preserving duplicate-key, duration, retraction, and delete/reinsert semantics.tests/persist-replay-probes.test.mjsmakes SQLite statement executions observable on both real bindings and proves a 4,004-record replay needs only 51 bulk reads plus 8 genuine writes.tests/persist-test-fixtures.mjs, avoiding duplicate binding and canonical-record setup.Validation
npm test: pass, 667/667 tests under normal filesystem-event permissionsnpm run typecheck: pass for root and app tsconfigsnode --experimental-strip-types --experimental-sqlite --experimental-test-module-mocks --test tests/persist-replay-probes.test.mjs tests/persist-idempotency.test.mjs tests/persist.test.mjs tests/indexer-upsert-drift.test.mjs: pass, 20/20 testsnpx eslint packages/core/src/persist.ts tests/persist-test-fixtures.mjs tests/persist-idempotency.test.mjs tests/persist-replay-probes.test.mjs: pass, 0 errorsgit diff --check: passnpm run lint: locally blocked by 94 pre-existing errors in user-owned untracked generated artifacts underdocs/book/site/dist,resume_rebuild,tmp, andoutput; no errors are reported for this PR's filesStatement-count regression benchmark
Both
node:sqliteandbetter-sqlite3run the same controlled replay:Canonical SQLite executions fall from 4,004 per-record UPSERT/probes to 59 total: 51 bounded reads and 8 new/modified writes. The same suite verifies that a one-record delta performs zero prefetch reads and one direct write.
The regression benchmark records persistence and finalize in separate timer regions rather than treating their sum as persistence. One representative local run reported:
node:sqlitebetter-sqlite3These synthetic timings are diagnostics, not pass/fail thresholds; statement counts are the regression assertion.
Controlled real-corpus phase measurements
The benchmark replayed the same 24,197,667-byte Codex session against the same 1,098,883,072-byte local index inside rollback-only transactions.
origin/main)The independent finalize measurement separates its own work further: project-path refresh 862.1 ms, unresolved backfill 0.46 ms, workflow healing 0.20 ms, and FTS readiness 0.04 ms. The dominant finalize cost is the separate #105 project-path scan and is not attributed to persistence.
origin/mainThe residual 53 executions are 51 batch reads plus 2 ordered duration updates present in the replay. Statement executions fell 98.8%; persistence latency fell 77.6%.
Controlled complete incremental-build A/B
A copy-on-write clone of the same 1.10 GB index received the same appended real transcript record for each trial. Each arm ran complete
buildIndexwork, including discovery, parse, persistence, project-path refresh, and finalize; order alternated across three restored trials.origin/mainCold-cache variance is visible and #105 finalize work remains in both arms, but the new implementation was faster in every paired trial; median complete-build latency fell 77.9%.
Risks and Rollback
Related Issues
Closes #132