Stop the segment preprocess from building a Schema per segment - #19486
Open
xiangfu0 wants to merge 2 commits into
Open
Stop the segment preprocess from building a Schema per segment#19486xiangfu0 wants to merge 2 commits into
xiangfu0 wants to merge 2 commits into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## xiangfu0/data-3221-9-column-arrays #19486 +/- ##
========================================================================
+ Coverage 67.76% 67.79% +0.02%
Complexity 1430 1430
========================================================================
Files 3493 3493
Lines 225070 225067 -3
Branches 35550 35545 -5
========================================================================
+ Hits 152515 152578 +63
+ Misses 60517 60450 -67
- Partials 12038 12039 +1
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:
|
…hema Two things the preprocess does on every segment load asked the segment metadata for its schema, and since the schema is derived and then cached, each one pinned a per-segment `Schema` for the segment's whole life: - `ForwardIndexHandler#computeOperations` needs the set of physical column names, and - `ColumnMinMaxValueGenerator` needs the columns its mode selects (the default mode is `ALL`, so this runs on every load). Both questions are answered by the column metadata the schema is itself derived from. `SegmentMetadata#getPhysicalColumnNames()` walks the column metadata for the first, falling back to the schema for a segment that holds no column metadata (a CONSUMING one), and the min/max generator now selects straight off each column's field spec. On a server measured with 13.6k loaded segments, the schemas built here were ~144 MB of tree entries and list slots, all of it a second copy of data the column metadata already holds. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Two follow-ups on `SegmentMetadata#getPhysicalColumnNames()`, both found by review of the previous commit rather than by a failure: - It returned a `HashSet` for a segment that holds column metadata but the schema's `TreeSet` for one that does not, so the expression it replaced (`getSchema().getPhysicalColumnNames()`, always sorted) silently became unordered for immutable segments and stayed sorted for CONSUMING ones — the worst shape for a caller that assumes order. It now returns a `SortedSet` for both, as the replaced expression did. - Its schema fallback for a segment holding no column metadata was reached through the default `getAllColumnMetadata()`, which is `getColumnMetadataMap().values()` — and `getColumnMetadataMap()` is `@Nullable`, documented to answer `null` for exactly that segment. The fallback worked only because the one implementation in the tree overrides the accessor. That default now honors its own documented contract and answers empty for a null map. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
xiangfu0
force-pushed
the
xiangfu0/data-3221-10-physical-column-names
branch
from
September 9, 2026 01:56
4a3d0d6 to
1bad6fd
Compare
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
Two things the segment preprocess does on every load asked the segment metadata for its
Schema. The schema is derived and then cached, so each one pinned aSchemaper loaded segment for the segment's whole life:ForwardIndexHandler#computeOperationswants the set of physical column names.ColumnMinMaxValueGeneratorwants the columns its mode selects — the default mode isALL, so this runs on every load too.Both questions are answered by the column metadata the schema is itself derived from.
SegmentMetadata#getPhysicalColumnNames()walks the column metadata (falling back to the schema for a segment that holds no column metadata, i.e. a CONSUMING one), and the min/max generator selects straight off each column's field spec instead of offschema.getAllFieldSpecs().No behavior change: the same columns are selected, in the same order the column metadata is held in, and
getSchema()still returns the same schema for anyone who asks for it.Why
Found on a production server holding 13.6k loaded segments: one
Schemaper segment, ~144 MB of tree entries and list slots, all of it a second copy of what the column metadata already holds. Part 7 of this series (#19478) made the per-segment schema lazy; these two callers were the reason it was still built for every segment anyway.Tests
SegmentMetadataImplTest#testPreprocessDoesNotBuildTheSegmentSchema:getPhysicalColumnNames()returns whatgetSchema().getPhysicalColumnNames()returns without materializing a schema, and a fullSegmentPreProcessor#process()over a v3 segment materializes none. The test fails if either call site is reverted.Stack
Part 10, based on #19481. Review only this part's own commit; the earlier parts account for the rest of the diff.
🤖 Generated with Claude Code