LuciferYang opened a new pull request, #9614:
URL: https://github.com/apache/paimon/pull/9614

   ### Purpose
   
   close #9613
   
   `BitmapFileIndexMetaV2.BitmapIndexBlock.tryAdd` refused an entry whenever it 
pushed the block past `index-block-size`, without asking whether the block 
already held anything. `serialize` answers a refusal by opening one new block 
and retrying once, and that block is empty too, so the same entry is refused 
again and the write ends at `throw new RuntimeException("index fail")`. A 
single dictionary key larger than the limit therefore fails the whole data 
file, not just its index.
   
   The threshold is `index-block-size` minus 16 bytes: a block starts at 
`Integer.BYTES` for its entry count, and a STRING entry costs `2 * 
Integer.BYTES` plus the `Integer.BYTES + sizeInBytes` that 
`getSerializeSizeMeasure` reports. With the default 16kb that means one 
16369-byte value, and a single row carrying it is enough. Fixed-width types 
cannot get close to the limit, so this is a variable-length column problem.
   
   An empty block now takes its first entry unconditionally, so an oversized 
key gets a block to itself and the entries after it spill over as before. That 
treats the limit as the packing target it is, which is also how the two sibling 
implementations read it: `BitmapGlobalIndexFormat.write` only enforces its 
dictionary block size once the block `hasEntries()`, and 
`ChunkedDictionary.append` passes each chunk's first key through the chunk 
constructor rather than `tryAdd`.
   
   Nothing on the read side depends on a block fitting inside the limit. Block 
offsets accumulate from each block's real `serializedBytes`, the entry count 
written ahead of a block bounds it, and the block keys stay sorted, so 
`findBlock`'s binary search still lands on the right block. Inputs that used to 
serialize produce identical bytes, since an entry an empty block rejected could 
not produce a file at all before.
   
   One thing I left alone: now that an empty block never refuses, the `index 
fail` throw in `serialize` is unreachable. Removing it means restructuring that 
loop, which felt like more than this fix should carry, but I'm glad to fold it 
in if you would rather see it go.
   
   ### Tests
   
   `BitmapFileIndexTest.testV2EntryLargerThanBlockSize` builds an index over a 
20000-character value, a null and two short values at the default 16kb block 
size, then reads all four back through the reader. The two short keys share the 
first block, so the size check runs and admits the second one; the long key is 
rejected there and then accepted as the first entry of the next block. Both 
sides of the new condition run within one index.
   
   Against the unfixed writer the test errors with `RuntimeException: index 
fail` out of `BitmapFileIndex$Writer.serializedBytes`.
   
   `mvn -pl paimon-common -Dtest=BitmapFileIndexTest test` on JDK 8: 7 tests, 0 
failures. `spotless:check` and `checkstyle:check` on paimon-common are clean.
   


-- 
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]

Reply via email to