Skip index write interface - #9413
Conversation
ce89894 to
8c2bdfd
Compare
Merging this PR will regress 2 benchmarks
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Simulation | allocate_drop_arrow[0] |
402.7 ns | 456.9 ns | -11.86% |
| ❌ | WallTime | mul_u32_nonnull_avx512 |
5.6 µs | 6.3 µs | -10.23% |
| ⚡ | WallTime | arrow_checked_add_u32_neon[16384] |
20.3 µs | 13.3 µs | +52.74% |
| ⚡ | Simulation | decompress[u64, (4000, 1024)] |
85.6 µs | 70.4 µs | +21.59% |
| ⚡ | WallTime | arrow_checked_add_u32_avx512[16384] |
21.3 µs | 17.6 µs | +21.11% |
| ⚡ | WallTime | add_shapes_neon[(128, PerRowPerRow)] |
2 µs | 1.8 µs | +10.64% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing joacoc:skip-index-writer-integration (97fa19c) with develop (4afdbd4)
Footnotes
-
206 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. ↩
69ae560 to
868debd
Compare
931fc7e to
635ad9d
Compare
Signed-off-by: Connor Tsui <connor.tsui20@gmail.com> Signed-off-by: Joaquin Colacci <joaquincolacci@gmail.com>
Signed-off-by: Joaquin Colacci <joaquincolacci@gmail.com>
Signed-off-by: Joaquin Colacci <joaquincolacci@gmail.com>
Signed-off-by: Joaquin Colacci <joaquincolacci@gmail.com>
This is just a cleanup of the bloom filter code that is being addressed in another pull request. Signed-off-by: Joaquin Colacci <joaquincolacci@gmail.com>
…t objects Initially the `dtype` was necessary when declaring the `SkipIndex/Options`, but this requires the caller to carry (or get) the target zone column `dtype` and instantiating multiple indexes, but we can defer this behaviour to the zone writer, so that when the zone writer initializes the default aggregation fns, also initializes the index aggregation fns. At this point, we can get the `dtype` from the writer column `stream`. So, this transforms the interface from: Before: `.with_skip_index(&index, dtype, session)` After: `.with_skip_index(Arc::new(index))` But to have this behaviour, I had to update `.with_skip_index()` to store indexes as `Arc<dyn SkipIndex>` instead of trying to build on call. Also, I had to add to the zone writer the list of `SkipIndex` that should init and use during writes. Still need to dedupe `skip_indexes` when pushing (left a TODO), and since skip indexes are now shared via `Arc`, I want to double check there's no internal mutability creeping in that would make that sharing unsafe. Signed-off-by: Joaquin Colacci <joaquincolacci@gmail.com>
This commit adds one new type SkipIndexRef (Arc<dyn SkipIndex>) to have more freedom handling the skip index. Also added a new trait called `SkipIndexSessionExt` that the idea is to do `session.register_skip_index(skip_index);`. But having something like `session.register(skip_index)` would be more ideal. Also the mutation from strategy was removed, the writer was updated to handle the user fns correctly, and also the test was updated to use the new bounded expressions. Signed-off-by: Joaquin Colacci <joaquincolacci@gmail.com>
Signed-off-by: Joaquin Colacci <joaquincolacci@gmail.com>
One of the pending TODOs was to remove duplicate skip indexes or aggregate functions. This relies on the implementation retrieving the underlying aggregate function ID. In the future, this could be an "index ID". Also document the two new module files. Signed-off-by: Joaquin Colacci <joaquincolacci@gmail.com>
Signed-off-by: Joaquin Colacci <joaquincolacci@gmail.com>
Skip-index duplicate detection was removed. I could have retained the code that checks if the same index is added twice, but it would have made the implementation more complex. At the end, configuring duplicate skip indexes is undesired, but it affects performance rather than correctness. Signed-off-by: Joaquin Colacci <joaquincolacci@gmail.com>
635ad9d to
113e6b4
Compare
…writer This commit is mostly about integrating the Bloom filter with the skip index trait and zoned writer. But, getting this integration right requires using the aggregate function options serialized in the file. To make those options available to rewrite rules, this commit adds `aggregate_fns` to `StatsRewriteCtx`. During pruning, `pruning.rs` now adds the aggregate functions deserialized from the file to the rewrite context before calling `falsify`. This removes the need for a rewrite rule to store options when it is registered. Also, this commit also includes an end-to-end test to assert that a skip index can be read without declaring any options on the reader, as it should. Index registration now requires only the skip index type. Before, it required a configured instance. The instance is now needed only during writes, where it defines the options persisted in the file. Signed-off-by: Joaquin Colacci <joaquincolacci@gmail.com>
|
One part I'd highlight for review are the changes to rewrite.rs and pruning.rs. I needed a way to pass the serialized aggregate fn options from the file to StatsRewriteRule during pruning. Passing the aggregate functions through The interface ended up like this: let session = VortexSession::default();
let index = BloomSkipIndex::new(BloomOptions::default());
// Registration (enough for reads)
session.register_skip_index(&index);
// Configuration for writes
let strategy = WriteStrategyBuilder::default()
.with_field_aggregates(field_path!(id), [index.aggregate_fn()])
.build();
session
.write_options()
// Required because Bloom filters are not currently part of any edition
.disable_editions()
.with_strategy(strategy); |
The biggest change in this commit is how the skip index trait works. Now it defines two types, Aggregate and Scalar, and I assume that a skip index will only require one AggregateFnVTable and one ScalarFnVTable, but potentially multiple rewrite rules. So, for anyone implementing a skip index, the trait already defines the limits and registers everything in a session. This commit also updates the writer. Given that the index's underlying aggregate_fn is the only piece that interacts with the writer, only that function is passed down, and the rest remains outside it. This also avoids having to pass an unnecessary new type (SkipIndex) down into the writer. At the same time, it means that an index will behave the same way as aggregation fns behave with unsupported types (by omitting the unsupported aggregate). Signed-off-by: Joaquin Colacci <joaquincolacci@gmail.com>
Use repartition block size using writer block size rather than zone options block size. Signed-off-by: Joaquin Colacci <joaquincolacci@gmail.com>
Signed-off-by: Joaquin Colacci <joaquincolacci@gmail.com>
Zone layout options for the write strategy builder were introduced just to pass the aggregate fn for a field, so what if we just passed that aggregate fn rather than the layout options, and kept the options configuration as it was before? That's the idea of this commit. It simplifies aggregate fn handling and reduces complexity, but is less expressive for layout options. Signed-off-by: Joaquin Colacci <joaquincolacci@gmail.com>
|
What is the intended difference between this and ZonedLayout ( ).That is also a skip index. |
|
@joseph-isaacs this hooks into zoned layout (it explains this in the description). I think this is generally the right direction, we want a nicer interface for aggregations that we know are going to be treated as indexes specifically and not just statistics |
Rationale for this change
This PR contains the implementation for the skip index write interface. Based on the previous PR #8933, which already had a working example on a Bloom filter prototype. So, this PR removes the Bloom filter bits (except for the file/skip-index integration test) and consolidates the skip-index interface.
ZonedLayout#8901What changes are included in this PR?
This PR carries over the following from #8933, with some changes:
SkipIndextrait, which provides anaggregate_fnand registers its required components with a session.WriteStrategyBuilder::with_field_zoned_options.aggregatesdir, where other skipping-index aggregate functions can live.This PR also adds the following notable changes:
SkipIndexRefandSkipIndexSessionExtfor simpler registration and handling.ZonedLayoutOptionsandZonedStrategyso that they store configured skipping indexes and resolve their aggregates while writing, rather than during configuration.StatsRewriteCtxand zoned pruning so rewrite rules can access the aggregate functions, and allow them to use the serialized aggregate options.What APIs are changed? Are there any user-facing changes?
Yes. This PR contains the following user-facing changes:
WriteStrategyBuilderaddswith_field_zoned_options, which configures zoned-layout options for a field.SkipIndexSessionExtadds skipping-index registration methods toVortexSession.ZonedLayoutOptionsaddswith_skip_index, which configures a skipping index for the zoned layout.