Skip to content

Prune SSTable I/O in scan_ns with zone maps and the sparse index#118

Open
mweiden wants to merge 1 commit into
mainfrom
claude/audit-fix-11-scan-ns-pruning
Open

Prune SSTable I/O in scan_ns with zone maps and the sparse index#118
mweiden wants to merge 1 commit into
mainfrom
claude/audit-fix-11-scan-ns-pruning

Conversation

@mweiden

@mweiden mweiden commented Jun 9, 2026

Copy link
Copy Markdown
Owner

Problem

Database::scan_ns read every SSTable file in full from storage and walked every line for any namespace scan. Partial-key SELECTs and COUNTs therefore cost O(total data across all tables) no matter which table they touched — and on the S3 backend that meant downloading every object per query.

Fix

New SsTable::scan_prefix(prefix, storage):

  • Zone map pruning: ZoneMap::may_contain_prefix rules out tables whose [min, max] key range cannot intersect the prefix interval [prefix, succ(prefix)) — answered with zero I/O.
  • Sparse index seek: scanning starts at the index entry at or before the prefix instead of byte 0.
  • Sorted early exit: the scan stops at the first key sorting past the prefix range.
  • Local storage reads through a mmap instead of loading the whole file into memory.

scan_ns delegates to it; merge semantics (oldest table → newest, memtable overlay last) are unchanged.

Tests

  • scan_prefix_returns_only_matching_entries (incl. the ab: vs a: boundary).
  • scan_prefix_skips_tables_outside_zone_map_without_io: a counting storage wrapper proves zone-map-excluded prefixes perform zero table reads.
  • scan_ns_merges_sstables_and_memtable: end-to-end merge behavior across two flushed generations plus the memtable, with namespace isolation.

Found by codebase audit (medium severity: O(total data) reads on the partial-key query path).

https://claude.ai/code/session_01CJXWjB9ERGgV6B9mRqrdM9


Generated by Claude Code

scan_ns read every SSTable file in full from storage and walked every
line for any namespace scan, making partial-key SELECTs and COUNTs
O(total data) regardless of which table they touched.

Add SsTable::scan_prefix: the zone map rules out tables whose key range
cannot intersect the namespace (answered with zero I/O), the sparse
index seeks near the first candidate line, and the scan stops at the
first key sorting past the prefix. Local storage is read through a
mmap instead of loading the file into memory. scan_ns now delegates to
it; merge semantics (oldest table to newest, memtable last) are
unchanged.

https://claude.ai/code/session_01CJXWjB9ERGgV6B9mRqrdM9
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.

2 participants