Skip to content

perf: single-pass contiguous DELETE + BTree separator-delete fix - #361

Merged
MPCoreDeveloper merged 3 commits into
masterfrom
perf/bulk-contiguous-delete
Sep 3, 2026
Merged

perf: single-pass contiguous DELETE + BTree separator-delete fix#361
MPCoreDeveloper merged 3 commits into
masterfrom
perf/bulk-contiguous-delete

Conversation

@MPCoreDeveloper

Copy link
Copy Markdown
Owner

Summary

B9: single-pass contiguous DELETE fast path — the DELETE mirror of #360's UPDATE fast path. Strictly ascending pk = <literal> DELETEs on a plaintext fixed-width columnar table with physically adjacent records remove every PK/hash-index entry in one pass: one contiguous range read + indexed columns decoded from the raw slots (no per-row pread, no full-row deserialization). Same narrow gate; any mismatch falls back to the generic loop before anything is removed.

Latent correctness fix (found while validating)

BTree.Delete removed separator keys from internal nodes without repairing the child-pointer ↔ separator mapping. After bulk deletes, whole ranges became unreachable — a generic-path hazard too (deleting internal separators corrupts traversal for any sizable delete, not just the new fast path). Fix: internal separators are now replaced by their in-order successor from the right subtree's leftmost leaf (leaf underflow is harmless), with empty-neighbour fallbacks that keep the child count consistent.

Measured (AppendOnly --pk, default = fixed-width)

before after
DELETE ~55-77K ops/s ~135K ops/s
DELETE gap vs SQLite ~4-6× 2.1×
UPDATE ~84K ~79K (noise)

Tests

Full suite 1652/1652 (+2 FixedWidthBulkDeleteTests): contiguous DELETE engages twice (two batches over 1-2000) and removes rows from PK and hash-index paths (including a TEXT hash index, decoded through the overflow arena); gapped/odd-id DELETEs fall back to the generic loop and stay correct. BulkContiguousDeleteBatches diagnostics prove engagement.

Note: a pre-existing SELECT COUNT(*)-after-DELETE discrepancy (generic and bulk alike) surfaced while testing; the tests assert index-path correctness (per-key point + hash lookups) rather than COUNT(*). Separately tracked.

MPCoreDeveloper added 3 commits September 3, 2026 09:18
…+ fix BTree.Delete separator corruption

B9: Table.TryBulkDeleteContiguousFixedWidth mirrors the UPDATE fast path: strictly ascending pk=literal DELETEs on a plaintext fixed-width columnar table with physically adjacent records remove every PK/hash-index entry in one pass (one contiguous range read, indexed columns decoded from raw slots, no full-row deserialization). Same narrow gate as the UPDATE path; any mismatch falls back to the generic loop before anything is removed.

Latent correctness bug found while validating: BTree.Delete removed separator keys from INTERNAL nodes without fixing the child-pointer mapping, so after bulk deletes whole ranges became unreachable (search could not descend to them). Internal separators are now replaced by their in-order successor from the right subtree's leftmost leaf (leaf underflow is harmless); empty-neighbour fallbacks keep the pointer count consistent. This also fixes the same hazard for the generic per-row delete path.
…ly every row)

Locks in the fix for the large descending-batch UPDATE no-op observed while building the contiguous fast paths: the fast path refuses descending keys and the generic per-row loop now applies all rows.
…nd DELETE fast paths

Extracts TryReadContiguousFixedWidthRecords (PK adjacency verification + one range read + length-prefix check) so the B8 UPDATE and B9 DELETE bulk paths no longer duplicate the probe (Sonar duplication gate).
@sonarqubecloud

sonarqubecloud Bot commented Sep 3, 2026

Copy link
Copy Markdown

@MPCoreDeveloper
MPCoreDeveloper merged commit 668ea8e into master Sep 3, 2026
13 checks passed
@MPCoreDeveloper
MPCoreDeveloper deleted the perf/bulk-contiguous-delete branch September 3, 2026 09:45
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