Fold PhysicalColumnIndexContainer's IndexTypeMap into a presence mask and a dense reader array - #19475
Open
xiangfu0 wants to merge 1 commit into
Conversation
This was referenced Sep 6, 2026
Open
Open
… plus dense readers A server holding tens of thousands of wide segments (1000+ columns) creates one PhysicalColumnIndexContainer per (segment, column) at load time. Each one held a package-private IndexTypeMap object plus an IndexReader[] spanning the numeric-id range of the present readers: the common forward_index (id 2) + nullvalue_vector (id 8) shape paid for 7 slots to hold 2 readers, i.e. 24 B container + 24 B map + 48 B array = 96 B per column. The container now stores a `long _presentMask` (bit i set when the index type with numeric id i has a reader) and an exactly-sized `IndexReader[] _readers` ordered by numeric id, sharing one empty array for columns without readers. getIndex(type) is a shift, a mask and a popcount into the dense array, so it stays O(1) on the query path; the forward + null-vector shape drops to 32 B container + 24 B array = 56 B, and no shape regresses because a dense array is never larger than a span array. Construction also writes straight into a scratch array instead of two ArrayLists and a ShortArrayList per column. Numeric ids are validated against the 64-bit mask at construction with a clear IllegalStateException (13 index types in OSS today), rather than adding an unreachable fallback path. Behaviour is otherwise unchanged: getIndex returns null for absent types, the forwardIndexOnly filtering, IndexReaderConstraintException handling and init-failure cleanup are kept, close() closes every reader exactly once in id order, and the multi-column text reader setter/getter are untouched. Compatibility: IndexTypeMap was package-private with no references outside this file, ColumnIndexContainer and IndexService numeric ids are unchanged, and there is no SPI, on-disk, wire or REST JSON impact, so mixed-version deployments are unaffected. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
xiangfu0
force-pushed
the
xiangfu0/data-3221-4-index-container-mask
branch
from
September 9, 2026 01:56
33a59e3 to
0bbde43
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## xiangfu0/data-3221-3-datasource-adapter #19475 +/- ##
=============================================================================
- Coverage 57.81% 57.80% -0.02%
- Complexity 1 7 +6
=============================================================================
Files 2688 2688
Lines 164324 164308 -16
Branches 26683 26681 -2
=============================================================================
- Hits 95008 94977 -31
- Misses 61291 61293 +2
- Partials 8025 8038 +13
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
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.
What
PhysicalColumnIndexContainerstored its readers in anIndexTypeMapholding a span-sizedIndexReader[]: with forward index at numeric id 2 and null vector at 8, a column with two readers allocated seven slots. It now keeps alongpresence mask plus a densely packed, exactly sized reader array, sogetIndexis a shift, mask andLong.bitCountinstead of a range check, at the same O(1) cost. Construction also drops the transient per-columnArrayLists.A
Preconditions.checkStaterejects a numeric index id of 64 or above at construction rather than silently misbehaving; OSS uses 13 ids today.Tests
PhysicalColumnIndexContainerTest: forward only, forward plus null vector, and a mix spanning the lowest and a high id, assertinggetIndexreturns the created reader for present types and null for absent ones, thatforwardIndexOnlyfiltering still applies, and thatclosecloses each reader exactly once.Why
A server keeps one metadata object graph per (segment, column) for as long as the segment is loaded, so on wide tables the per-column footprint decides how many segments a server can hold. Measured end to end on a 1000-column segment, this series takes the heap retained at load from 4.08 MB to 0.175 MB per segment (4,080 to 174 bytes per column), with a fully compacting collector on both sides. No on-disk format change, the
/tables/{table}/segments/{segment}/metadataJSON stays byte-identical, and every public and SPI signature keeps working.Stack
Part 4 of 9, based on #19474. Review only this part's own commits; the earlier parts account for the rest of the diff.