Repository navigation
feat(scan): run the V2 executor on the segment IO protocol - #10527
joseph-isaacs wants to merge 1 commit into
Conversation
Merging this PR will degrade performance by 7.83%4 warnings, 1 note
Warning Please fix the performance issues or acknowledge them on CodSpeed. Performance Changes
Tip Investigate this regression by commenting Comparing Footnotes
|
24ef18f to
8e2defb
Compare
7002056 to
a5654f2
Compare
|
CodSpeed Performance Analysis flags regressions on
No fix is needed, and I can't re-run CodSpeed from here. #10569 runs the same tree, so this applies to its CodSpeed report too. Generated by Claude Code |
Switches the planner-driven scan from the byte-range `vortex_io::request` protocol to `vortex_io::segments`, and serves it with a session-wide `FileSegmentIo` that reads through files' v1 segment sources. - vortex-scan: `Planner` and `Morsel` drop the `IoConsumer` supertrait, publish `NeedsIO(Vec<IoRequest>)`, and receive `deliver(key, result)` once per successful fetch. `Run`/`Driver` submit each root's requests to its `SegmentIoSession` and hold the handles; each item's fetches finish through its own `FuturesUnordered`, so a `poll_ready` report yields exactly the finished fetches. Fetches in flight are counted per session, since spawned roots share one. `Run::poll_io` replaces `Run::complete`. The scripted harness is a recording `SegmentIoSession`. - vortex-layout: `ScanAdaptor` fetches each segment once by `IoKey::segment` while any scan read of it is outstanding, and hands the result to every waiting read. Prune and filter hints name segment keys. `ScanFile` and `PreparedScan` carry the file's `RegisteredSource`, and `PreparedScan::io` is its service. `SegmentScanIo` and the cached byte-range index it needed are removed. - vortex-file: `FileSegmentIo`, one per `VortexSession`. Size requests are answered at submit; segment requests call `SegmentSource::request`, so they share the file's segment cache, request sharing and coalescing read driver. `VortexFile::scan_file` registers the file's segment source, and a caching file keeps one registration in its scan cache, renewed with its segment source. The V2 scan driver reads through `SegmentIoSession`. - vortex-datafusion, vortex-duckdb: their V2 drivers read through `SegmentIoSession`; the DataFusion opener shares a file's segment source across partitions through `VortexFile::with_segment_source`. - vortex-io: `request` is removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N4PmceDHg8rFe5bgkhGFU9 Signed-off-by: Claude <noreply@anthropic.com>
8e2defb to
75bbf20
Compare
a5654f2 to
054036d
Compare
Summary
Stacked on #10568, which adds the segment IO protocol (
vortex_io::segments).This PR moves the planner-driven V2 scan from the byte-range
vortex_io::requestprotocol onto the new protocol, then removesrequest. It serves the protocol withFileSegmentIo, which reads through each file's existing v1 segment source.V1 scans are unchanged. At runtime, V2 reads share the file's segment cache, request sharing and coalescing read driver, and no task or thread is added.
The branch is rebased onto
develop's planner-chain V2 executor (#10706, #10707, #10708): prune and chunk planners, spawned chunks, and DataFusion and DuckDB drivers.Changes
vortex-scanPlannerandMorseldrop theIoConsumersupertrait. They publishNeedsIO(Vec<IoRequest>)and receivedeliver(key, result)once per successful fetch.RunandDriversubmit each root's requests to that root'sSegmentIoSession, and hold the handles.FuturesUnordered, so apoll_readyreport yields exactly the fetches that finished.Run::poll_ioreplacesRun::complete.SegmentIoSession.vortex-layoutScanAdaptorfetches each segment once byIoKey::segmentwhile any scan read of it is outstanding, and hands the result to every waiting read.ScanFileandPreparedScancarry the file'sRegisteredSource, andPreparedScan::ioreturns its service.SegmentScanIois removed, along with the byte-range index thatScanCachekept for it.vortex-file:segment_io::FileSegmentIo, one perVortexSession.SegmentSource::request.VortexFile::scan_fileregisters the file. A caching file keeps one registration in its scan cache, andwith_segment_sourcerenews it.SegmentIoSession.vortex-datafusion,vortex-duckdbSegmentIoSession.VortexFile::with_segment_source, and still shares itsScanCache.vortex-io:requestis removed.Performance
Measured in CI with manually dispatched
PR SQL Benchmarksruns on dedicated runners, comparing against the base commit, three runs per side. Numbers are for DataFusion on Vortex (the V2 scan); DuckDB on Vortex is unaffected and serves as a control.The result is neutral on NVMe, with about 1% gained on SF10. S3 is within its own run-to-run noise. Locally (TPC-H SF1, 22 queries), physical reads drop 14% against the old IO (1143 → 984).
Checks
cargo clippy -p vortex-io -p vortex-scan -p vortex-layout -p vortex-file -p vortex-datafusion --all-targets --all-features -- -D warningscargo clippy -p compress-bench -p vortex-bench -p datafusion-bench --all-targets -- -D warningscargo +nightly-2026-09-10 fmton those crates andvortex-duckdbRUSTDOCFLAGS="-D warnings --cfg docsrs" cargo doc --no-deps -p vortex-io -p vortex-scan -p vortex-layout -p vortex-file --all-featurescargo test --lib:vortex-io(109),vortex-scan(59),vortex-layout(664),vortex-file(197),vortex-datafusion(778)typosNot run locally:
vortex-duckdbdoesn't build here because the DuckDB source download is blocked. Its change is the samedeliverswap as the other planners, and CI builds it.API Changes
vortex_io::requestis removed.PlannerandMorseldropIoConsumerand gaindeliver(IoKey, SourceResult).NeedsIOcarriesVec<IoRequest>.ScanFile.segmentsis replaced byScanFile.segment_io: RegisteredSource.PreparedScan::ioreturnsArc<dyn SegmentIoService>.vortex_file::segment_io::FileSegmentIo.🤖 Generated with Claude Code
https://claude.ai/code/session_01N4PmceDHg8rFe5bgkhGFU9