linliu-code opened a new pull request, #686:
URL: https://github.com/apache/hudi-rs/pull/686

   > **Stacked on #682, which is stacked on #678. Review those first.** This 
targets `main`, so it shows their 11 commits alongside its own 1. The delta 
that belongs to this PR is the last commit: 4 files, +300/-6.
   
   First slice of #684. Does not close it: the header walk is still 
synchronous, so the blocking bridge stays for now.
   
   ## Description
   
   Pass 3 issued one ranged read per admitted log block, serially, through the 
blocking bridge. By that point the gates have already chosen the set, so every 
range is known before any byte is read and they can go out together. 
`get_ranges` coalesces ranges that sit close together, so a run of adjacent 
blocks costs one round trip rather than one each. Nothing in the crate called 
`get_ranges` or `get_byte_ranges` before this.
   
   The fetch moves into the async layer and Pass 3 keeps doing no I/O. That 
split is not only tidiness: making Pass 3 itself `async` held the record buffer 
across an await, and `HoodieFileGroupRecordBuffer` is not `Sync`, so the scan 
future stopped being `Send`. Fetching in the caller and passing the bytes down 
avoids that entirely.
   
   Batches are bounded by `hoodie.memory.dfs.buffer.max.size` rather than 
issued all at once. Reading a whole slice's admitted log content up front would 
give back the peak-memory property #682 was justified on (+200 MB to +40 MB on 
a 91 MB file). A block larger than the budget still goes out on its own, since 
its content has to be whole to decode.
   
   Ranges are grouped per file before batching, because a `LogBlockFetcher` 
reads one file.
   
   ## How are the changes test-covered
   
   - [ ] N/A
   - [x] Automated tests (unit and/or integration tests)
   - [ ] Manual tests
     - [ ] Details are described below
   
   Two tests, and they exist because of a specific hazard: output is identical 
whether the prefetch works or not, since Pass 3 falls back to fetching per 
block. Stubbing the prefetch to return nothing passed all 1309 existing tests. 
So the batching needed tests that assert the mechanism rather than the result.
   
   - `test_read_contents_matches_reading_each_range_alone` asserts a batched 
read is byte-identical to reading the same ranges one at a time. Fewer round 
trips must not mean different bytes.
   - `test_prefetch_returns_content_for_every_admitted_block` asserts every 
admitted block comes back with exactly its own range. This is the one that 
kills the stub-it-out mutation.
   
   Both need a log file with more than one block, and no shipped fixture has 
one: every file under `crates/core/tests/data/log_files` holds exactly one. 
They concatenate a one-block fixture with itself, which is a valid two-block 
file since log blocks are self-contained.
   
   Verified: `cargo fmt --check`, clippy with and without default features, 
1311 lib tests, 1291 with `--no-default-features`, the gold parity sweep green 
across all fixtures and both reader versions, and `hudi-cpp` plus `hudi-python` 
still compile.
   
   ## What is not covered
   
   The round-trip saving itself is **not measured**. `memory_bench` measures 
memory, not latency, and a local filesystem will not show the win at all, since 
it is a round-trip cost. Quoting a number needs a benchmark against real object 
storage, which is worth doing before this is claimed as a performance 
improvement rather than a structural one.
   


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