Repository navigation
Add selection planners and ListLayout scans to V2 - #10537
joseph-isaacs wants to merge 18 commits into
Conversation
Merging this PR will improve performance by 25.45%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ⚡ | Simulation | take_map[(0.1, 1.0)] |
352.2 µs | 221.2 µs | +59.22% |
| ⚡ | WallTime | filter_neon[8] |
1,382 ns | 909 ns | +52.04% |
| ⚡ | WallTime | threshold_neon[8] |
1.9 µs | 1.4 µs | +41.78% |
| ⚡ | WallTime | filter_neon[64] |
2.2 µs | 1.7 µs | +25.72% |
| ⚡ ℹ️ | Simulation | test_repeated_scan_scalar_at[int_float] |
490.9 µs | 392.2 µs | +25.17% |
| ⚡ | Simulation | take_map[(0.1, 0.5)] |
182.6 µs | 146.4 µs | +24.72% |
| ⚡ | WallTime | bitpack_blocked_compress_avx512 |
5.7 µs | 4.7 µs | +20.64% |
| ⚡ | WallTime | threshold_neon[64] |
3 µs | 2.5 µs | +20.31% |
| ⚡ | WallTime | filter_neon[80] |
2.9 µs | 2.6 µs | +12.98% |
| ⚡ | Simulation | take_map[(0.1, 0.05)] |
87 µs | 77.4 µs | +12.42% |
| ⚡ | WallTime | threshold_neon[80] |
3.7 µs | 3.3 µs | +10.9% |
| ⚡ | WallTime | words_gather_dispatch_neon[65536] |
2.3 µs | 2 µs | +10.35% |
Tip
Curious why performance improved? Comment @codspeedbot explain why performance improved on this PR, or directly use the CodSpeed MCP with your agent.
Comparing ji/decompression-v2-scan (8442d46) with develop (27c6b0d)
Footnotes
-
12 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
6b97c79 to
15f2fed
Compare
Start from 740e1ef and retain its explicit V2 ScanBuilder, fixed row chunks sized by serialized bytes, ScanAdaptor, and one output per work chunk. SelectionPlanner hands its selected rows to the existing ProjectionPlanner. Add ListPack compilation that reads selected boundaries/validity before scanning element ranges. This replaces the follow-up at ad83fcb; that history is preserved by ji/scan-v2-before-pr10540 locally and by the existing ji/scan-v2-regression-ci remote branch. The shared ancestor is 7b15cfc. Reconstructing the compatible additions avoids resurrecting files removed or replaced by the new base. Deviations resolved in favor of PR #10540 before benchmarking: - Keep its explicit API; drop the V1-builder environment gate. - Keep its 8,192-row multiples, at most 65,536 rows, and 8 MiB serialized target; drop the stored-chunk/list-element sparse splitter and separate 32 MiB list-work admission cap. - Keep its ScanAdaptor and aggregate output; drop the alternate ScanGraph, direct point morsel, and per-split streaming channels. - Keep its I/O implementation; drop sparse range lookup, eager request registration/coalescing heuristics, and ready-completion shortcuts. - Keep its file and plan lifetime; drop persistent preparation, support caches, and dictionary retention across file scans. - Keep its scheduler, ValueCache, lowering, and pipeline activation; drop inline ready queues, deferred concat producers, and capacity knobs. - Keep its sharing traversal; drop Reach::Selected/Reach::Ranges pruning. List elements still use exact offset-derived ranges for correctness. - Drop the grouped-list two-range overlap heuristic pending measurements. - Keep the base's documentation deletion and compress-bench V2 selection. The initial diff is 14 files, +1493/-26 including tests and benchmark infrastructure, down from 34 files, +4593/-259. Removed diagnostic modes that depended on the old builder's mapping API. No removed optimization has been restored without post-rebase measurements. The dedicated CI workflow on ji/scan-v2-pr10540 compares the original ad83fcb V2, this V2, and current V1 using identical data and compiler flags. It retains all 48 cases, full Arrow decode/drop, three seeds, alternating order, and longer reruns. Results are pending at this commit. Validation: release_debug selection/rewrite examples built; 573 layout and 65 scan unit tests passed; 72 real-file V1 full-scan-plus-take checks passed across all six benchmark datasets, one and 30 cores, empty, singleton, clustered, uniform, larger, and full selections. Pinned format, Ruff, strict workflow yamllint, and diff whitespace checks passed. No workspace-wide checks, Clippy, or doctests were run. Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
Deviation from PR #10540 retained after the rebase: PackSource already knows the number of consumed rows, but assemble derived it from the first field. A nullable struct with no fields has only a validity inlet, leaving no field from which to recover its length. Pass the consumed length through the existing private helper. This does not restore the old point-projection executor or its assembly API. The regression test failed before the fix: 0 rows instead of 20 for all rows, and 0 instead of 10 for every-other selection. Both pass afterward. Validation: 578 vortex-layout and 65 vortex-scan unit tests passed in the current worktree; no workspace-wide checks or Clippy were run. Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
Measured deviation from PR #10540: remove the recursive supports_layout preflight. The explicit V2 builder has no fallback to select, and lower already reports unsupported layouts. Keep unrelated layout children lazy instead of deserializing every child before a sparse scan can start. Unknown roots and reached unknown chunks still fail. A chunk outside the requested row range can now remain unsupported and unread; tests cover both outcomes. No persistent file/support cache is restored. After rebasing, one-core clustered feature-vector reopen scans made about 26,100 allocations vs 1,400 before the rebase. In three-seed alternating 64-query runs, removing the walk improved 3.262 ms to 1.252 ms. Thirty-core 64 KiB list clustered reopen improved 1.192 ms to 0.428 ms (previous V2: 0.420 ms). Taxi remained about 31 ms vs 14 ms because fixed work chunks request 133 MB vs 48 MB of unique segment data, a separate issue. The initial base-preferred dedicated CI run 38931231485 completed all 48 cases and 38 longer confirmations; 35 confirmed cases exceed +3% versus ad83fcb. Passing workflow status is not a performance-regression gate. Local raw results and deviations are under random-access-v2/rebase-10540 on /mnt/vortex-ssd/vortex-scanning-v2. This change's focused comparison is lazy-validation-comparison; final full-matrix results are pending. Validation: 578 vortex-layout and 65 vortex-scan unit tests passed, including unsupported-layout cases and the prior nullable-struct fix. Release_debug example built; diff whitespace check passed. Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
Measured deviation from PR #10540: its 65,536-row ceiling repeatedly reads large stored segments when sparse selections span adjacent work chunks. Preserve fixed aligned chunks, the 8 MiB serialized-byte target, and the base executor. For at most 1/16 selected rows, allow larger power-of-two multiples while targeting four work chunks per worker. Dense scans, non-identity projections, and wide-row sizing are unchanged. This replaces the old stored-layout/list-element splitter with about 20 lines of sizing logic; no additional execution or cache path is added. Three-seed alternating full Arrow decode/drop comparisons after rebasing: - Taxi, 1 core, uniform cached: 31.743 -> 13.950 ms; previous V2 13.598. - Taxi, 1 core, uniform reopen: 32.428 -> 14.737 ms; previous V2 14.433. - Nested structs, 1 core, uniform cached: 6.652 -> 4.324 ms; previous 4.538. Instrumented queries confirm the cause: taxi requests fall from 825 / 133 MB to 327 / 48 MB; nested structs fall from 96 / 71 MB to 48 / 36 MB. Taxi peak live allocation increases from about 18 MB to 40 MB, below the prior implementation's measured peak. The byte target is an estimate of serialized work, not a hard bound on live heap or decoded values. A simpler byte-only variant improved 30-core uniform reads but worsened 30-core clustered taxi by about 9% relative to this worker-limited variant; it was rejected. Keep the base's multi-core sizing in those cases. Other pre-rebase optimizations remain omitted, so this is not a no-regression claim. The final dedicated 48-case comparison is pending publication. Validation: 583 vortex-layout and 65 vortex-scan unit tests passed; 72 real-file full-scan-plus-take checks passed across six datasets, 1/30 cores, empty/singleton/clustered/uniform/larger/full selections. Built instrumented and uninstrumented examples; pinned formatting and diff whitespace checks passed. No workspace-wide checks, Clippy, or doctests. Artifacts: /mnt/vortex-ssd/vortex-scanning-v2/random-access-v2/rebase-10540/ (sparse-budget-comparison, byte-budget-only-comparison, final-diagnostics, final-correctness). Original work remains on ji/scan-v2-before-pr10540 locally and ji/scan-v2-regression-ci remotely. Rebase update: PR #10540 merged as d3bac42. Replay on develop preserves every incoming base change, including the new BitPacked/FSST take paths and writer defaults. The merged base tree equals a9e2601, so the replay has no additional code conflicts. Earlier timing figures above describe the 740e1ef checkpoint; new-base results are pending. Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
The final branch now extends develop at d3bac42 (#10540), preserving the base's merged BitPacked/FSST changes and writer defaults. Cancel older runs of this experiment branch when a newer head is published, so the benchmark runner validates the intended source instead of queuing behind a superseded checkpoint. Other branches use different concurrency groups. The 740e1ef base-preferred run 38931231485 is complete and archived. Run 38935258274 targets the previous 15f2fed checkpoint and can be superseded. Its results must not be described as the merged-base comparison. Validation: strict yamllint for the changed workflow and diff whitespace check passed. This commit changes no Rust behavior. Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
15f2fed to
02119f6
Compare
CI run 38936290519 failed before timing: rewrite_list_layout still called WriteStrategyBuilder::with_list_layout(), removed by upstream #10563 and inherited through the merged #10540 base. Keep the base's edition-driven writer policy and adapt the benchmark helper instead of restoring the API. Enable the experimental list edition only for list/list-elements modes. Flat mode leaves it disabled, preserving the flat control. Drop the obsolete environment guard and explicit writer toggle. Scanner runtime is unchanged, so the completed local 48-case merged-comparison remains applicable. Validation: built both release_debug examples with --locked; rewrote all 1,000,000 rows in flat, list, list-elements/1 MiB and list-elements/64 KiB modes; all four full Arrow equality and layout-kind checks passed, as did four V2 selection comparisons against full V1 scans followed by take. Pinned formatting and diff whitespace checks passed. No new Rust-library checks were needed for this example-only API adaptation. Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
The standard and CUDA lint jobs rejected the variable-bound u64-to-usize cast in rows_per_chunk. Use a checked conversion with the existing byte budget invariant: at least one byte per row bounds the count to 1024 blocks. Chunk sizes and scheduling behavior are unchanged. Use explicit Arc clones and a cached static layout id in the new tests, following the merged base's lint rules without adding suppressions. Validation: vortex-layout Clippy with all targets/all features and with no default features; all 70 V2 scan tests; pinned formatting and patch whitespace checks passed. The dedicated CI benchmark will run again on this head. Known random-access regressions remain documented in the draft. Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
Keep SelectionPlanner composable: its successor receives a scope and mask that retain absolute row coordinates. Trim unselected edges when the surviving span has at least 1/16 selected rows. Empty selections still stop without constructing a successor; widely scattered selections preserve the aligned input scope. Unrestricted trimming improved clustered feature-vector scans but slowed one-core uniform taxi by 17%. Trimming changes encoded-array slice bounds, so keep the aligned sparse gather path. The compact-only variant improves feature-vector clustered scans by 9-13% in 18 paired local comparisons and leaves taxi uniform scans within 2%; no tested case regressed beyond 3%. These are three-seed alternating full Arrow decode/drop measurements, not a claim of completing the goal of outperforming V1 on every workload. The first scope tests failed before this change; the full layout/scan suite passed for unrestricted trimming (651 tests), then all 69 scan tests passed for the guarded variant. All 72 real-file checks passed for the first variant. Targeted all-feature/all-target scan Clippy, pinned formatting and whitespace checks passed. Full-matrix validation will follow subsequent list planning experiments. No wider workspace checks were run. Baseline: 5f2965a. Artifacts: random-access-v2/post-rebase/{trim,compact}-comparison on /mnt/vortex-ssd/vortex-scanning-v2. Both rejected and accepted executables and raw samples are preserved for backtracking. Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
ListSource supplies disjoint offset-derived element ranges to Scan. The merged-base sharing walk took their bounding range and eagerly lowered unread chunks between those ranges. Walk the union of sorted disjoint ranges instead, merging adjacent ranges to preserve the dense-scan path. Keep the existing bounding walk for overlapping or unordered splits. This restores only the measured gap pruning benefit from the original pre-#10540 branch, without changing its scheduler, projection morsels, sharing implementation, or cache lifetimes. Selection planners still hand selected row scopes to projection planners. Two lazy-gap regression cases fail before this change and pass after it. Additional cases cover gaps, overlaps, unordered/empty ranges, FIFO/LIFO completion, and shared segments read once across active split counts. 601 vortex-layout and 69 vortex-scan unit tests pass, as do 72 real-file checks against V1 full scan plus take. Layout all-target/all-feature Clippy with -D warnings, pinned format, and diff whitespace checks pass. The uninstrumented local comparison against ad47e105d uses the same six stored datasets, 3 seeds, and 2 alternating rounds of 64 queries. In its 14 targeted cases, uniform 64 KiB lists improve 12.1/25.5 percent with one core (cached/reopen) and 20.3/33.0 percent with 30 cores. No case regresses more than 0.9 percent. Separate diagnostics reduce 30-core uniform-reopen allocations from 20,636 to 11,143 with requested bytes unchanged at 11.55 MB. These are local measurements, not the earlier native CI comparison. Results: /mnt/vortex-ssd/vortex-scanning-v2/random-access-v2/post-rebase/ gaps-comparison/results.json and gaps-diagnostics/summary.json. Full 48-case comparison is next. Five of these 14 cases remain over 3 percent slower than V1; this checkpoint does not establish the all-cases performance goal or fix repeated I/O across independent projection tasks. Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
A projection morsel runs one physical split with a selection mask. The sharing walk still lowered every chunk in its bounding range, even though compilation later skipped chunks with no selected rows. Carry the mask through linear row mappings and skip such children before lowering them. Preserve full reads when a child changes row domains, including dictionary values and list offsets. Dense and multiple-split scans keep their existing sharing walk. Use cached indices or bitmap range counts without making a new sliced mask for each child. This is a measured restoration of selected reach pruning from the original pre-#10540 branch; it does not restore its splitter, executor, or persistent caches. SelectionPlanner still returns ProjectionPlanner with absolute row coordinates. The preceding published checkpoint is 26aa0be. Four masked-gap regression cases fail before this change. Eight cases now cover nested/nonzero ranges, empty masks, and cached/uncached indices, and all 609 layout unit tests pass. All 72 real-file full-scan-plus-take checks pass. Layout all-target/all-feature Clippy with -D warnings, pinned format, and whitespace checks pass. No wider workspace checks or doctests ran. In separate instrumented runs, uniform feature-vector allocation counts fall about 19 percent cached and 31 percent reopening. Requested bytes stay at 85.02 MB; peak memory varies, so no general peak-memory win is claimed. The 20-case uninstrumented comparison uses three seeds and two alternating rounds of 64 queries, full Arrow decode/drop, one and 30 pinned cores. Feature-vector uniform reopen improves 5.6 percent on one core and 11.2 percent on 30 cores against 26aa0be. No tested case regresses more than 1.8 percent. Five cases remain over 3 percent slower than V1, including clustered lists; the all-random-access performance goal remains open. Artifacts: /mnt/vortex-ssd/vortex-scanning-v2/random-access-v2/post-rebase/ mask-comparison/results.json and mask-diagnostics/summary.json. The standard random-access harness also needs explicit V2 coverage; that benchmark-only switch is a separate follow-up, not part of this checkpoint. Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
Add --scan-v2 to route Vortex accessors through the explicit V2 builder. Keep the V1 default and canonical-array materialization path, dataset and index generators, cache/open modes, and timing method. This closes the coverage gap between the diagnostic example (100 exact uniform indices and full Arrow output) and the standard suite (Poisson-distributed indices, canonical-array output, and the legacy six-index taxi lookup). The option is benchmark-only and supports both local and object-store accessors; no production builder environment gate is introduced. Document separate output files because benchmark measurement names remain unchanged. Vortex-only all-target Clippy for vortex-bench and random-access-bench passes with -D warnings, as do pinned formatting and whitespace checks. All-feature Clippy cannot finish because optional lance-encoding needs an unavailable protoc binary. The release binary build and standard-suite V1/V2 timing comparison are next; no performance claim is made here. Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
The merged base rebuilds an offset/length hash map for every query. Phase measurements put this at about 15 us for clustered feature-vector reads. Reuse the location Arc and binary-search sorted tables; retain the indexed fallback for arbitrary segment order. Preserve exact range matching and the last-entry rule for duplicates, including zero-length segments. This measured deviation changes only the range lookup, keeping the base I/O service and planner lifetimes. No persistent cache or executor path is added. Original optimized V2 remains on ji/scan-v2-before-pr10540. Two alternating 2-second standard benchmark rounds, 18 cases on 1/30 cores: feature-vector clustered cached improves 2.1%/3.5% versus published 3cc4384; maximum slowdown is 2.73% (30-core clustered nested lists). Taxi 1-core uniform cached/reopen changes -0.45%/-2.49%. Remaining V1 regressions include 30-core six-row taxi +17.9% and 1-core clustered nested lists +9.2%. These are local canonical-array measurements, not the full Arrow CI suite. Validation: 613 layout unit tests, 72 real-file V1 full-scan-plus-take checks, layout all-target/all-feature Clippy -D warnings, pinned formatting, and whitespace checks pass. Standard benchmark and check example built. No workspace-wide checks or doctests. Artifacts and exact commands: /mnt/vortex-ssd/vortex-scanning-v2/random-access-v2/post-rebase/ (ranges-standard-comparison, ranges-correctness, phase-diagnostics). Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
The existing 48-case CI matrix always selects 100 rows and materializes Arrow batches. It misses the standard benchmark's six-row taxi lookup, which still regresses against V1, and its canonical-array output path. Retain that complete matrix and its original-V2 reruns. Additionally run all 36 standard targets with one/30 pinned cores, V1/V2 from the same binary, two alternating five-second rounds, and the built-in seed 42. Preserve per-run JSONL/logs, binary hash, commands, medians, and a separate summary so standard and full-Arrow measurements cannot be conflated. Assert paired names/counts to detect silently omitted benchmark targets. Freeze the current standard binary before the original branch is built. Validation: Ruff formatting/check, strict workflow yamllint, and diff whitespace checks pass. Full standard execution is queued after the current local timing comparison; this commit does not assert performance success. Existing completed CI run 38953694179 excludes this extension: 15/48 effective cases exceed +3% versus original V2; its first pass has 16/48 above +3% versus V1. The PR remains a draft. Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
Cap the four-tasks-per-worker sizing target by the number of selected rows. A six-row taxi lookup on 30 cores otherwise makes three projection tasks, including two that can read overlapping stored segments. Larger aligned chunks group the nearby rows into one task, leaving two useful tasks. The existing 8 MiB serialized-byte estimate and row alignment still apply; this estimate is not a hard decoded-memory bound. Non-identity projections and dense scans keep their existing sizing. Selection still emits the composable projection planner through Next<SelectedRows>. The new regression test reads two rows from a single stored segment. It fails before the change with two reads and passes afterward with one, while verifying both returned values. All 614 layout tests and 72 real-file V1 full-scan-plus-take checks pass. Layout all-target/all-feature Clippy -D warnings, pinned formatting, whitespace, and release builds pass. No workspace-wide checks or doctests. Sixteen standard cases compared against lookup checkpoint 06f4ad7b3 using two alternating two-second rounds. Two suspected >3% regressions were repeated on both core counts with four alternating five-second rounds: - 30-core six-row taxi cached: 0.3973 -> 0.3730 ms (-6.1%). - 30-core six-row taxi reopen: 0.6270 -> 0.6020 ms (-4.0%). - 30-core clustered taxi cached: +0.95%, rather than initial +4.2%. - 1-core clustered taxi reopen: +0.58%, rather than initial +5.3%. The effective 16-case comparison has maximum slowdown +1.45%. Six-row taxi cached remains 11.8% behind V1 on 30 cores; the full all-cases V1 performance goal is not met. Broader standard/Arrow CI remains pending. Artifacts: /mnt/vortex-ssd/vortex-scanning-v2/random-access-v2/post-rebase/ (tiny-standard-comparison, tiny-standard-confirmation, tiny-correctness, tiny-before-tests.log, tiny-tests.log). The previous implementation is preserved in the parent commits and frozen benchmark binaries. Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
Sampled allocation stacks identify Work::priority as 8-12% of V2 allocation calls on clustered feature-vector and list reads: cloning a Vec and then pushing often allocates twice on every ready-queue insertion. Store the common root/selection/projection/continuation path in SmallVec<[u64;4]>. Deeper compositions spill to the heap and keep lexicographic DFS ordering. Keep the existing BTreeMap, ownership lookup, I/O protocol, and scheduler. This is a measured deviation from the merged base's path representation, not restoration of the original alternate ready queue or executor. Instrumented before/after queries have identical read counts and bytes. Clustered feature-vector/nested-list allocations fall 8-10.5%; other cases improve less, and peak memory varies. Do not treat probe timing as latency. The allocation-stack probe was temporary and is absent from this commit. Full Arrow list comparison: 16 cases, three seeds, two alternating rounds of 64 queries; four borderline cases repeated with four rounds of 128. Effective maximum increase against published c441b53 is 1.1%. One-core 64KiB clustered cached improves 3.1%; most cases are effectively unchanged. The apparent 30-core 1MiB clustered cached gain did not survive a longer rerun (+1.1%), and the initial reopen regression reversed to -1.2%. Large V1 clustered-list regressions remain. An 18-case standard benchmark comparison and two longer nested-list reruns have now completed: maximum effective slowdown versus c441b53 is 1.46%, with none above 3%. The initial 3.2% nested-list reopen slowdown shrank to 0.72% on the longer run. This change makes no all-cases V1 speedup claim. Validation: 614 layout + 73 scan unit tests and 72 real-file comparisons pass; new depth 1/3/8/16 cases preserve sibling order through nested planners. Both crates pass all-target/all-feature Clippy -D warnings; pinned formatting, whitespace, and instrumented/uninstrumented release builds pass. No workspace-wide checks or doctests. The existing workspace SmallVec is the only added direct dependency; Cargo.lock has no package version changes. Artifacts: /mnt/vortex-ssd/vortex-scanning-v2/random-access-v2/post-rebase/ (allocation-stacks, priority-diagnostics, priority-list-comparison, priority-list-confirmation, priority-correctness). Frozen standard and example binaries are named random-access-bench-priority/selection-scan-priority. Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
Copy the already validated chunk start offsets into the existing Concat Arc instead of repeatedly asking the layout for each child's row count. Keep V1's offset storage and the base planner/scheduler unchanged. This is a measured deviation from PR #10540, isolated for comparison with 5231b70. Four regression cases cover regular, empty, absent, and zero-row chunks; three fail before the change. No child layouts are materialized to lower the boundaries. Production change is +7/-10 lines in two files. Local four-round, five-second standard comparisons show clustered feature vectors improving 8.0% cached / 3.5% reopen on one core and 17.1% / 4.9% on 30 cores. The initial taxi cached +6.4% reduced to +0.8% in the longer run. Nested-struct reopen is still +4.9%; identical-binary controls vary up to 7.8%, so that result is unresolved rather than dismissed as noise. Sixteen full-Arrow list cases initially show at most +2.01% slowdown; longer list confirmation and isolated parent CI remain pending. Repeated memory checks show no increase in taxi maximum live allocation, and median requested read counts/bytes are unchanged. No all-cases V1 win is claimed. Validation: 618 layout tests, all-target/all-feature layout Clippy with -D warnings, pinned formatting, whitespace, release benchmark builds, and 72 real-file V1 full-scan-plus-take correctness comparisons passed. No workspace-wide checks or doctests were run. Keep separate from the draft PR until the exact-parent CI comparison is assessed. Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
CI-only experiment wrapper; runtime source is identical to 7507307. Use 5231b70 as the exact baseline and compare both binaries in V1 and V2 modes. Preserve all 36 standard and 48 Arrow cases, alternating order, longer Arrow reruns, compiler settings, and shared datasets. Record binary hashes and both V1/V2 parent deltas to expose control drift. Do not carry this experiment-specific baseline into the draft PR. Validation: Ruff format/check, strict workflow YAML, and 24 subprocess smoke runs covering default and parent comparisons passed. Each smoke comparison checks all 36 paired results and expected percentage changes. Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
Runtime source is identical to local 95fda7fc8a92490ef55e7916b61c91e93c441520. Includes 76ef2cf32 and 95fda7fc8 on top of the validated-offset source. The source tree intentionally excludes the CI-only comparison wrapper. List range overlap is gated by an 8 MiB whole fixed-width chunk estimate, including validity. Unknown/oversized work and one-core scans stay serial. This is not independent CPU scheduling or a hard query heap bound. 630 layout tests, strict Clippy, formatting, both release builds and 72 real-file V1 oracle checks pass. Long local 30-core clustered 1 MiB tests improve 7.2% cached and 14.4% reopen vs76ef2cf32. The maximum effective list slowdown is 1.90%; 12 standard controls have a maximum slowdown of 1.52%. One memory repeat raises median peak live bytes 5.10 to 6.03 MB, with the observed maximum still about 6.16 MB; retained medians and reads match. The prior isolated offset-copy CI run has one unresolved +5.2% Arrow confirmation (1 MiB, one core, clustered reopen). Run the combined candidate against5231b7091 before accepting it into the draft PR. The V1 goal is unmet. Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
Run the unchanged full 48-case Arrow comparison and 36-case standard suite, including parent and candidate V1 controls for the standard suite. Use the same CI-only wrapper as ccbe15b and baseline 5231b70. Runtime source is 8442d46, tree-equivalent to local 95fda7fc8. The previous run 38972129118 is complete. It confirmed the offset-copy feature-vector improvements but retained one +5.2% Arrow rerun. This run checks the combined offset-copy, generated-offset-statistics, and guarded list-overlap changes. Keep PR #10537 draft; this run is not a merge gate. Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
Adds composable selection planning and ListLayout execution to the explicit V2 scan API. A selection planner passes its surviving row scope and mask to the projection planner. Lists resolve selected offsets and validity before scanning exact element ranges, preserving nullable and nested-list behavior.
Based on merged #10540 (
d3bac42ef). This keeps the base's explicit API, ScanAdaptor, aligned row partitions, scheduler, and one output per work chunk. The follow-up is 31 files, +2,566/−141, including tests and benchmark tooling, versus the original 34 files, +4,593/−259. Original V2 remains atad83fcbfconji/scan-v2-regression-ci.The implementation includes these correctness fixes and measured changes:
The original stored-layout splitter, alternate executor, persistent preparation cache, and 32 MiB list-work admission budget remain omitted. The new estimates are not hard heap limits, and overlapping two ranges does not provide independent CPU scheduling. Signed-off commits document the deviations from the base.
Draft: the all-cases V1 performance goal remains unmet.
The completed combined CI comparison tests runtime
8442d4695(tree-identical to local95fda7fc8) against the previous PR head5231b7091. The benchmark wrapper is991c0dd33. Its artifact was checksum-verified.Standard CI uses its existing generators, canonical-array output, cached/reopen modes, six-row taxi lookup, and two alternating five-second rounds with both parent/current V1 controls. Arrow comparisons use 100 selected rows, warm local disk, full Arrow decode/drop, three seeds, two alternating 64-query rounds, and four 128-query rounds for flagged cases; warmups are discarded. CI uses native ARM compiler settings. Local timing values use different files/compiler settings and are not combined with this table. Workflow success means the experiment completed, not that V1 was beaten everywhere.
Validation: 630 layout unit tests, 73 scan unit tests, and 72 real-file V1 full-scan-plus-take comparisons pass. Strict all-target/all-feature Clippy for the affected layout/scan crates, pinned formatting, whitespace, release benchmark builds, Ruff, and strict workflow YAML checks pass. Tests cover empty/null/nested lists, malformed offsets, FIFO/LIFO completion, shared segments, chunk-boundary validation, and priority ordering. Optional all-feature benchmark Clippy previously required an unavailable
protoc; no local workspace-wide checks or doctests ran.Two isolated list experiments remain outside this PR's validated runtime. Their full dedicated CI comparisons are complete, and all downloaded artifacts were SHA256-verified:
9c82c79cd/ publishede3d88b5ab)02f33ea52/ published69448718c)Arrow counts replace matching initial measurements with longer reruns (four mask reruns, ten null-payload reruns). Maximum parent slowdowns are +1.63%/+1.31% for mask Arrow/standard, and +11.18%/+1.20% for null-payload Arrow/standard. The remaining null-payload flag is one-core cached clustered 64 KiB lists, 0.366907 -> 0.407918 ms. A focused eight-case native comparison on
ji/scan-v2-list-control-cicompares the exact mask/null-payload runtime checkpoints, both V1 controls, three seeds, four 4096-query rounds with 512 warmups, and all cached/reopen, one/30-core, 64 KiB/1 MiB clustered controls. Its runtime excludes the early-admission experiment.Both original jobs also completed 128 large-fixture correctness commands and 96 timing cases. Their initial effective results each had three >3% parent flags. The completed long singleton confirmation compares all three exact runtime checkpoints in one job, with four 4096-query rounds per seed and all V1 controls. None of those six earlier flags reproduces across the five distinct affected cases. The previously flagged skewed primitive singleton changes by -0.07% for masks and +0.09% for null-payload retention. All eight generated fixture hashes match the earlier runs. This confirmation does not cover the separate original-list flag above.
These gains hold, but the final times remain 11.3% and 8.0% behind V1. Null-payload retention only applies to dense fixed-width spans in fully selected local scopes under an 8 MiB decoded-span estimate. The candidate passes 650 layout tests, strict Clippy, 200 real-file comparisons, and five malformed-selector checks. Original large-run correctness filenames collided for empty/100-row uniform selections: all 128 commands passed but only 112 result JSONs survived. The long confirmation fixes the filenames and preserves all 128 results.
Peak memory is not uniformly improved. Local null-payload allocation checks show matching request counts/bytes and median retained bytes across 32 cases; the large nested 1 MiB singleton drops 13.1% in median peak allocation, while some grouped large cases rise 4-5%. Longer original-list checks leave a 64 KiB cached seed42 median-peak increase of 23.4% (p95 +1.55%, observed max +0.33%). That non-null-list control does not take the new payload path, so attribution remains open. Independently scheduled large-row CPU work and the all-cases V1 goal remain outstanding.