xiangfu0 opened a new pull request, #19478:
URL: https://github.com/apache/pinot/pull/19478

   ## What
   
   `ColumnMetadataImpl` held min and max as `Comparable` references, so a 
numeric column retained two boxes it never needed. They are now stored as raw 
bits in two `long` words and boxed only inside `getMinValue()`/`getMaxValue()`; 
columns with a variable-width stored type keep object references and reuse the 
same two words for their three element-length values, which is what makes the 
change shrink the object rather than grow it. `FLOAT`/`DOUBLE` go through 
`floatToIntBits`/`doubleToLongBits` so `NaN` compares equal and `-0.0` stays 
distinct from `0.0`, matching `Float.equals`/`Double.equals`; a value whose 
class does not match its stored type falls back to the reference so nothing can 
be mistranslated. `bitsPerElement` moves into the flags word, with values 
outside the encodable range falling back to the existing lazily allocated 
holder.
   
   Measured with 500k instances sharing one field spec, used-heap delta after 
forced GC: a nullable INT column goes from 104 to 72 bytes, a STRING column 
stays at 72, and nothing regresses for multi-value or mixed-shape columns.
   
   Worth knowing: `getMinValue()`/`getMaxValue()` on a fixed-width column now 
return a freshly boxed value per call rather than the same instance. Values 
stay `equal()` and of the same class; only reference identity across calls is 
no longer guaranteed, and no production code depended on it.
   
   ## Tests
   
   `ColumnMetadataImplTest`: min and max round-trip for INT, LONG, FLOAT, 
DOUBLE, BOOLEAN, TIMESTAMP, STRING, JSON, BYTES and BIG_DECIMAL including the 
min-max-invalid flag and null cases; `NaN` is canonicalized but stays equal; 
`bitsPerElement` round-trips across 11 values including both sides of the 
encodable boundary and both overflow signs, asserting the flags do not bleed 
into it.
   ## 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}/metadata` JSON stays byte-identical, and 
every public and SPI signature keeps working.
   
   ## Stack
   
   Part 8 of 9, based on `xiangfu0/data-3221-6-lazy-materialization`. Review 
only this part's own commits; the rest of the diff belongs to the parts below 
it.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to