Skip to content

collections: drop byOff map + alias offsets; block zones/strDict maps -> slices - #222

Merged
bbockelm merged 2 commits into
mainfrom
colmeta-offsets-zones
Aug 23, 2026
Merged

collections: drop byOff map + alias offsets; block zones/strDict maps -> slices#222
bbockelm merged 2 commits into
mainfrom
colmeta-offsets-zones

Conversation

@bbockelm

Copy link
Copy Markdown
Collaborator

Based on main. Reopens two changes that were lost: #220 and #221 were merged into feature-branch bases instead of main, so their commits never reached main. This carries both, off main, in one PR (they are sequential — each edits the same columnar-metadata code in order — so they ship together rather than as two dependent PRs).

Follows #219 (already on main). Removes the last of the growing per-block/per-segment columnar-metadata heap. No on-disk format change; byte-identical marshal; applies to existing segments immediately.

1. Drop the per-segment byOff map; alias the arena-offset map (was #220, ~196 MB)

  • colNative kept a resident map[arenaOffset]index, one entry per record per columnarized segment. The offset map is already in hand and strictly ascending, so an O(log n) binary search (indexOf) replaces it; the map is removed.
  • colSegment.offs []uint32offsB []byte aliasing the mmap on reopen (read via offAt/offsLen).

2. Block zones + strDict maps → sorted slices (was #221, ~150–180 MB)

  • map[int]blockZone / map[int]strDictField → sorted-by-idx slices, binary-searched (zone, strDictOf). A Go map of a few dozen small entries carries ~2× its data in overhead, ×100K+ blocks.
  • A block-format bump to alias these would be data loss on columnar-native segments (attributes live only in the payload) and needs dual-read to be safe — so this changes the in-memory representation only, not the on-disk bytes.

Tests

TestColSegOffsAliasAndIndexOf (aliased read-back + indexOf present/absent) and an extended TestColBlockLayoutSharedAcrossBlocks (offset arrays packed u32; zones/strDict sorted, every entry findable, fixture non-vacuous). Full collections suite green on both stores.

🤖 Generated with Claude Code

bbockelm and others added 2 commits August 22, 2026 19:12
…rena-offset map

Two more per-segment columnar-metadata copies the heap profile flagged, no on-disk
format change.

byOff: colNative kept a resident map[arenaOffset]index -- one entry per record per
columnarized segment, ~164MB of live heap on a production archive -- for an O(1)
lookup. The offset map is already in hand and strictly ascending (records append in
order), so an O(log n) binary search (indexOf) replaces it; the map is removed.

offs: colSegment.offs []uint32 was materialized from the section on every open. It
is packed little-endian u32 on disk, so it becomes offsB []byte that ALIASES the
mmap on a reopened segment (zero heap; a built one holds a compact buffer), read via
offAt/offsLen -- the same aliasing #219 applied to the block offset arrays. Marshal
output is byte-identical; readU32s is gone, packU32s added for the build path.

~196MB off the resident plateau, and byOff no longer scales with record count.

TestColSegOffsAliasAndIndexOf covers the aliased read-back and indexOf (present ->
index; below/between/above -> not-found). Full collections suite green (both stores).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ump)

The last per-block columnar-metadata maps. A block kept zones (map[int]blockZone,
~174MB in the profile) and strDict (map[int]strDictField, ~156MB) -- one map each
per block over ~100K+ blocks, whose bucket overhead was ~2x the entries.

A block-format bump to alias them would be data loss on columnar-native segments
(their schema'd attributes live only in the block payload, so rejecting an old
section drops the only copy) and would need dual-format read to be safe. But the
map overhead is a representation choice, not on-disk: parse the SAME on-disk entries
into a sorted-by-idx slice and binary-search them (zone(), strDictOf()). Byte-
identical marshal, so every existing segment gets the smaller form immediately with
no migration.

seg.zones (the per-segment zone map keyed by attr id) is unrelated and untouched.

TestColBlockLayoutSharedAcrossBlocks extended: both slices sorted, every entry
findable via its accessor, fixture non-vacuous. Full collections suite green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@codecov

codecov Bot commented Aug 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@bbockelm
bbockelm merged commit 508a343 into main Aug 23, 2026
11 checks passed
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