Repository navigation
Conversation
BsoBird
force-pushed
the
vectored-read-opt
branch
from
October 12, 2026 12:27
0172058 to
d67b0df
Compare
…tolerance When vectored I/O is active (Hadoop >= 3.3.5, zero-copy disabled), readDiskRangesVectored built one FileRange per BufferChunk with no merging: orc.min.disk.seek.size was silently ignored (TestMinSeekSize fails on Hadoop >= 3.3.5, reading 5.26% of the file instead of ~106%), its tolerance was not applied (gap bytes stayed resident in range buffers), contiguous/overlapping ranges paid per-range async overhead, and single-range batches paid readVectored dispatch cost with no parallelism benefit. - Coalesce BufferChunks through a new pure coalesceRanges helper that merges contiguous/overlapping ranges and, when minSeekSize > 0, folds in small gaps (nextOffset - currentEnd <= minSeekSize), matching the sync path's findSingleRead semantics so vectored I/O no longer regresses on minSeekSize-bounded workloads - Enforce a hard per-range cap and compute merged spans in long arithmetic, flushing the in-flight FileRange when it would exceed the cap so offsets near Integer.MAX_VALUE no longer wrap to negative/truncated int lengths - Treat already-filled chunks (hasData()) as merge barriers so the vectored path never re-reads in-memory data, and backfill original chunks with a single O(chunks + ranges) forward pass - Apply minSeekSizeTolerance as a post-read memory bound: merged ranges whose extra-bytes fraction exceeds the tolerance are compacted into tightly-sized buffers, mirroring the sync path's ChunkReader.populateChunksReduceSize - Short-circuit single-range batches to a synchronous positioned readFully instead of submitting one FileRange to readVectored - Reference RecordReaderUtils.MAX_ARRAY_SIZE (moved from IOUtils by ORC-2049) so the code compiles on main With default configuration (minSeekSize=0, minSeekSizeTolerance=0.0) exactly the same bytes are read as before. Local benchmark (2M rows, 1954 stripes of ~1k rows, ZLIB/NONE, warm page cache, Hadoop 3.4.1, median of 15 iterations, ORC 2.1.2 before -> after): full scan 216.9 -> 187.8 ms, projection 129.7 -> 105.4 ms, SARG filter 51.3 -> 28.2 ms, projection+filter 34.1 -> 16.8 ms; identical read bytes and row counts in every cell. Tests: TestMinSeekSize now passes on Hadoop 3.4.1; 18 new unit tests in TestRecordReaderUtils; TestRecordReaderImpl.testHadoopVectoredIO updated (full scans now coalesce to a single range) plus a new test asserting single-range batches never call readVectored; full java/core suite 1562 tests, 0 failures, 0 errors (21 skipped) on main.
BsoBird
force-pushed
the
vectored-read-opt
branch
from
October 18, 2026 11:23
d67b0df to
8e5b1f1
Compare
This branch has not been deployed
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 changes were proposed in this pull request?
RecordReaderUtils.readDiskRangesVectoredto coalesceBufferChunks through a new purecoalesceRangeshelper that merges contiguous/overlapping ranges and, whenminSeekSize > 0, also folds in small gaps (nextOffset - currentEnd <= minSeekSize), matching the sync path'sfindSingleReadsemantics so vectored I/O no longer regresses on minSeekSize-bounded workloadsIOUtils.MAX_ARRAY_SIZEand compute merged spans in long arithmetic, flushing the in-flightFileRangewhen it would exceed the cap so offsets nearInteger.MAX_VALUEno longer wrap to negative/truncated int lengthshasData() == true) as merge barriers so the vectored path never re-reads data that is already in memory, and backfill original chunks from merged range buffers with a single O(chunks + ranges) forward passreadFullyinstead of submitting oneFileRangetoreadVectored, avoiding executor task +CompletableFutureoverhead where no parallelism is possibleminSeekSizeup front (IllegalArgumentException) instead of failing later with a misleading errorminSeekSize,hasDataboundaries, the size cap, negative input rejection, the single-range short-circuit, andminSeekSize=0equivalence; reworktestHadoopVectoredIOto keep exercisingreadVectored(a full scan now coalesces to one range)The non-vectored (sync) read path is unchanged. With default configuration (
minSeekSize=0) exactly the same bytes are read as before.Why are the changes needed?
When vectored I/O is active (Hadoop >= 3.3.5, zero-copy disabled), the vectored read path builds one
FileRangeperBufferChunkwith no merging:orc.min.disk.seek.sizeis silently ignored. The sync path merges ranges whose gap is withinminSeekSize(findSingleRead); the vectored path does not.TestMinSeekSize.readAlternateColumnsWMinSeekSizefails on Hadoop 3.4.1 (reads 5.26% of the file instead of ~106%); it passes on Hadoop 3.3.4, where vectored I/O is disabled — confirming the vectored path as the cause.Local benchmark (2M rows, 1954 stripes of ~1k rows, ZLIB/NONE, warm page cache, Hadoop 3.4.1, median of 15 iterations, before → after):
Read bytes and row counts are identical in every cell; after the fix the vectored path matches the non-vectored path (and 1.5.3) on this workload.
How was this patch tested?
TestMinSeekSizenow passes with Hadoop 3.4.1 (previously failing; see above for reproduction via-Dhadoop.version=3.3.4vs3.4.1).TestRecordReaderUtilsforcoalesceRanges(positive + negative cases listed above) and a newTestRecordReaderImpl.testHadoopVectoredIOSingleRangeUsesSyncReadasserting single-range batches never callreadVectored.java/coresuite on main: 1558 tests, 0 failures, 0 errors (21 skipped):cd java && ./mvnw -pl core testread_bytesandrows_readbetween vectored and non-vectored paths.Was this patch authored or co-authored using generative AI tooling?
co-authored-by: Kimi K3 via OpenCode