Repository navigation
Connection-per-operation performance: index seeks, linear inserts, in-place UPDATE, Turso checkpoint parity, encrypted pooling - #77
Merged
Marc-André Moreau (mamoreau-devolutions) merged 1 commit intoOct 5, 2026
Conversation
…eks, linear inserts, in-place UPDATE, Turso checkpoint parity, encrypted pooling Fixes the hot paths a connection-per-operation workload over GUID-keyed rowid tables hits (Remote Desktop Manager's SQLite data source): - Spill directory is resolved lazily and cached, so 8.3 short-form TEMP paths no longer cost ~1.5 ms per statement. - SqliteDataReader caches declared types per result set instead of running PRAGMA table_info/index_list/index_info for every GetValue call. - Pooled open/close skips the second-pager catalog probe when nothing committed (shared generation + durable view token gate). - Single-table index equality SEARCH seeks the durable index b-tree instead of materializing and sorting the whole index per query. - Unique-index validation on INSERT uses a cached key set (imports were O(n^2)). - Plain UPDATE ... WHERE on rowid tables touches only matched rows, with incremental unique-index checks. - WAL byte-range lock leases reuse idle handles of a mapped -shm carrier (file opens cost milliseconds under Windows file-system filters). - Checkpoints no longer force a full rescan by bumping the local generation. - Turso checkpoint policy for provider connections (core/storage/pager.rs commit_wal, wal.rs should_checkpoint): checkpoint after commit only past 1000 WAL frames, plus a best-effort checkpoint on close. Replicas, MVCC and structural changes keep checkpointing immediately. Made viable by: resumable WAL validation scans, reusing the validated commit-frame header, keeping a valid wal-index at open instead of rebuilding it (which reset live read marks), and publishing a read mark at the committed boundary for read-only readers. - Encrypted connections are pooled per cipher and SHA-256 key fingerprint; AhtolaConnection accepts Pooling=True with encryption. - Encrypted opens of non-Ahtola ciphertext (e.g. SEE) no longer claim a plaintext SQLite header. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Marc-André Moreau (mamoreau-devolutions)
merged commit Oct 5, 2026
b086d62
into
master
11 checks passed
Marc-André Moreau (mamoreau-devolutions)
deleted the
claude/ahtola-sqlite-perf-c43fd7
branch
October 5, 2026 18:36
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
Fixes the hot paths of a connection-per-operation workload over GUID-keyed rowid tables (Remote Desktop Manager's SQLite data source), from the RDM engine benchmark report: Windows 8.3 TEMP paths,
GetValueschema PRAGMAs, slow pooled opens, table-scanning GUID lookups, quadratic inserts, O(n) updates, per-commit lock and checkpoint overhead, unpooled encrypted opens, and a misleading error for SEE-encrypted files.Reader and query paths
VdbeExecutionOptionsresolves the spill directory lazily through a cache keyed onTMP/TEMP/USERPROFILE(an 8.3 short-form TEMP made eachGetTempPath()~1.5 ms).SqliteDataReader: declared types, undeclared-source flags and select-source PRAGMA results are cached per result set (keyed on statement + SQL, reset byNextResult).GetManagedIndexRows): seeks the durable index b-tree instead of materializing every row and sorting the whole index; inside a transaction it reads through the transaction's own writes. Rowid tables without method indexes only.Write paths
UPDATE ... WHEREon rowid tables (no FROM/LIMIT/ORDER BY/RETURNING, no rowid change, no FK-relevant assignment) runsPerformUpdateInPlace: matched rows only, same rowid-order WHERE/SET interleaving, incremental unique checks, in-place row replacement. Conflict handling (IGNORE/FAIL partial publish) mirrors the full path. The full path also prunes WHERE evaluation to equality candidates.Storage
-shmcarrier (≤16 per access mode, closed with the final mapping, identity-checked, never reused after a failed unlock; macOS keeps its brokered descriptors). File opens cost 1–4.5 ms under Windows file-system filters, while a lock on an open handle costs ~25 µs.SqliteConnection/AhtolaConnectionlocal files (core/storage/pager.rscommit_wal,wal.rsshould_checkpoint, threshold 1000): ordinary row commits checkpoint once the WAL holds more than 1000 committed frames, plus a best-effort checkpoint on close. Replicas, MVCC and structural changes (full rewrites, REINDEX, VACUUM, page-size and journal-mode changes) keep checkpointing immediately. This needed four changes:walIndexReadHdr;AhtolaConnectionnow acceptsPooling=Truewith encryption.Behavior changes
.dbfile alone does not contain the latest commits (as in SQLite/Turso WAL mode): copy the-walwith it or runPRAGMA wal_checkpoint(TRUNCATE). Documented indocs/dotnet-packages.md.ClearPool/ClearAllPools. Documented.Measurements
RDM-shaped harness (GUID blob PK, ~1.3 KB XML
DATA, connection per operation), 10,000 entries, Windows 11 / .NET 10 Release / Defender on. The machine was noisy, so comparisons were made back to back.SELECT 1+ closeDataTable(GetValue)Not addressed
IPageCodec.Test plan
ConnectionPerOperationWorkloadTests(seek correctness incl. transactions and triggers, unique-key cache, in-place UPDATE conflict semantics and FK enforcement, reader declared types, pooled reopen, lock-handle pool, deferred checkpoints and peer visibility across WAL restarts, error text, temp dir) andManagedConnectionPoolingTestsencrypted-pooling cases./build.ps1 validate-package/validate-trim./build.ps1 format-check(already fails on master for unrelated files)🤖 Generated with Claude Code