feat[file]: gate the writer on the session's enabled editions#8946
feat[file]: gate the writer on the session's enabled editions#8946joseph-isaacs wants to merge 5 commits into
Conversation
Adds a required `Scheme::produced_encodings` method returning the array encodings a scheme may itself introduce into its compressed output. Cascaded children are compressed by other schemes, which declare their own encodings, so only encodings constructed directly by `compress` belong here. `BtrBlocksCompressorBuilder::retain_allowed_encodings` uses the declarations to drop any scheme that could produce an encoding outside a permitted set, so an encoding policy can be enforced before compression rather than rejected after it. Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
Introduces `EnabledEditions`, a session variable recording the editions a writer is permitted to emit — at most one per family, with a newer or older edition from the same family replacing the previous selection. This is deliberately separate from `EditionSession`: registration describes what a session knows how to reason about, while enabling is the explicit writer policy. `EditionSessionExt` gains: - `enabled_editions` — access the (lazily installed) selection. - `register_edition` / `enable_edition` — enabling an unregistered edition errors, so a typo or unavailable third-party declaration cannot silently produce an empty writable set. - `enabled_encoding_ids` — resolve the union of encodings across all enabled editions; empty when nothing is enabled. The default `vortex` session now enables the newest frozen `core` edition (and the newest unstable edition under `unstable_encodings`) via `editions::enable_default_editions`. No writer behavior changes yet: this only records the selection on the session. A follow-up PR consumes `enabled_encoding_ids` to gate the file writer. Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
The file writer previously drew its permitted encodings from a static `ALLOWED_ENCODINGS` set in `vortex-file`. That set was compiled in, so the only way to write a narrower or wider encoding set was to override the write strategy by hand, and the writer's policy was disconnected from the editions the session had registered. Encoding policy now comes from the session's enabled editions: - `VortexWriteOptions::new` resolves `enabled_encoding_ids` and applies it both to the write strategy and to the `ArrayContext`, so a replacement strategy cannot widen the policy. - `WriteStrategyBuilder::with_allow_encodings` now also filters the BtrBlocks compressor via `retain_allowed_encodings`, in either configuration order, so forbidden encodings are never produced rather than being rejected after the fact. - `ALLOWED_ENCODINGS` is removed. `register_default_encodings` still registers everything for reading; the default session's write policy comes from the editions enabled by `enable_default_editions`. Sessions without an `EnabledEditions` variable permit no edition encodings, so lower-level test sessions in `vortex-file`, `vortex-layout` and `vortex-parquet-variant` opt in explicitly (a shared `enable_all_registered_array_encodings` test helper). Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
Move `retain_allowed_encodings` out of the `with_allow_encodings` and `with_btrblocks_builder` setters and into `build()`, applying it once to the compressor before it is used for the data, stats, and defaulted probe compressors. This drops the order-dependence between configuring the builder and the allowed-encodings policy: whichever order they are set, the filter is applied to every compressor derived from the builder. Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
…tions Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk> # Conflicts: # vortex-jni/src/writer.rs # vortex-layout/src/layouts/struct_/reader.rs # vortex-layout/src/layouts/table.rs # vortex-layout/src/test.rs
Polar Signals Profiling ResultsLatest Run
Powered by Polar Signals Cloud |
Benchmarks: PolarSignals Profiling 📖Vortex (geomean): 1.009x ➖ How to read Verdict and Engines
datafusion / vortex-file-compressed (1.009x ➖, 0↑ 0↓)
File Size Changes (1 files changed, +0.0% overall, 1↑ 0↓)
Totals:
|
Benchmarks: FineWeb NVMe 📖Verdict: No clear signal (low confidence) How to read Verdict and Engines
datafusion / vortex-file-compressed (1.031x ➖, 0↑ 1↓)
datafusion / vortex-compact (1.035x ➖, 0↑ 1↓)
datafusion / parquet (1.004x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed (1.059x ➖, 0↑ 2↓)
duckdb / vortex-compact (1.011x ➖, 0↑ 0↓)
duckdb / parquet (0.997x ➖, 1↑ 0↓)
File Size Changes (2 files changed, +0.0% overall, 2↑ 0↓)
Totals:
|
Benchmarks: TPC-H SF=1 on NVME 📖Verdict: No clear signal (low confidence) How to read Verdict and Engines
datafusion / vortex-file-compressed (1.001x ➖, 0↑ 0↓)
datafusion / vortex-compact (1.007x ➖, 0↑ 0↓)
datafusion / parquet (1.026x ➖, 0↑ 2↓)
datafusion / arrow (1.013x ➖, 0↑ 1↓)
duckdb / vortex-file-compressed (1.030x ➖, 0↑ 0↓)
duckdb / vortex-compact (1.027x ➖, 0↑ 0↓)
duckdb / parquet (1.004x ➖, 0↑ 1↓)
duckdb / duckdb (1.029x ➖, 0↑ 0↓)
File Size Changes (18 files changed, +0.0% overall, 18↑ 0↓)
Totals:
|
Benchmarks: Vortex queries 📖Verdict: No clear signal (low confidence) How to read Verdict and Engines
datafusion / vortex-file-compressed (0.844x ✅, 2↑ 0↓)
datafusion / parquet (0.886x ✅, 2↑ 0↓)
duckdb / vortex-file-compressed (0.916x ➖, 1↑ 0↓)
duckdb / parquet (0.938x ➖, 0↑ 0↓)
File Size Changes (1 files changed, +0.0% overall, 1↑ 0↓)
Totals:
|
Benchmarks: TPC-DS SF=1 on NVME 📖Verdict: No clear signal (low confidence) How to read Verdict and Engines
datafusion / vortex-file-compressed (1.039x ➖, 0↑ 7↓)
datafusion / vortex-compact (1.037x ➖, 0↑ 8↓)
datafusion / parquet (1.036x ➖, 0↑ 5↓)
duckdb / vortex-file-compressed (1.030x ➖, 0↑ 7↓)
duckdb / vortex-compact (1.038x ➖, 1↑ 6↓)
duckdb / parquet (1.007x ➖, 1↑ 0↓)
duckdb / duckdb (1.038x ➖, 0↑ 3↓)
File Size Changes (48 files changed, +0.0% overall, 48↑ 0↓)
Totals:
|
Benchmarks: FineWeb S3 📖Verdict: No clear signal (low confidence) How to read Verdict and Engines
datafusion / vortex-file-compressed (1.001x ➖, 0↑ 0↓)
datafusion / vortex-compact (0.980x ➖, 0↑ 0↓)
datafusion / parquet (1.042x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed (1.069x ➖, 0↑ 0↓)
duckdb / vortex-compact (1.065x ➖, 0↑ 0↓)
duckdb / parquet (1.017x ➖, 0↑ 0↓)
|
Benchmarks: Statistical and Population Genetics 📖Verdict: No clear signal (low confidence) How to read Verdict and Engines
duckdb / vortex-file-compressed (0.996x ➖, 0↑ 0↓)
duckdb / vortex-compact (0.998x ➖, 0↑ 0↓)
duckdb / parquet (0.993x ➖, 0↑ 0↓)
File Size Changes (2 files changed, +0.0% overall, 2↑ 0↓)
Totals:
|
Benchmarks: Clickbench Sorted on NVME 📖Verdict: No clear signal (low confidence) How to read Verdict and Engines
datafusion / vortex-file-compressed (1.006x ➖, 1↑ 2↓)
datafusion / parquet (0.950x ➖, 1↑ 0↓)
duckdb / vortex-file-compressed (0.991x ➖, 1↑ 1↓)
duckdb / parquet (0.984x ➖, 0↑ 0↓)
duckdb / duckdb (0.973x ➖, 0↑ 0↓)
File Size Changes (201 files changed, +0.0% overall, 100↑ 101↓)
Totals:
|
Benchmarks: TPC-H SF=10 on NVME 📖Verdict: No clear signal (low confidence) How to read Verdict and Engines
datafusion / vortex-file-compressed (0.757x ✅, 22↑ 0↓)
datafusion / vortex-compact (0.770x ✅, 22↑ 0↓)
datafusion / parquet (0.801x ✅, 21↑ 0↓)
datafusion / arrow (0.763x ✅, 22↑ 0↓)
duckdb / vortex-file-compressed (0.803x ✅, 22↑ 0↓)
duckdb / vortex-compact (0.819x ✅, 22↑ 0↓)
duckdb / parquet (0.893x ✅, 15↑ 0↓)
duckdb / duckdb (0.864x ✅, 18↑ 0↓)
File Size Changes (48 files changed, +0.0% overall, 48↑ 0↓)
Totals:
|
Benchmarks: Clickbench on NVME 📖Verdict: No clear signal (low confidence) How to read Verdict and Engines
datafusion / vortex-file-compressed (1.013x ➖, 0↑ 1↓)
datafusion / parquet (1.004x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed (0.991x ➖, 6↑ 1↓)
duckdb / parquet (0.996x ➖, 1↑ 0↓)
duckdb / duckdb (1.002x ➖, 0↑ 0↓)
File Size Changes (201 files changed, -0.0% overall, 200↑ 1↓)
Totals:
|
Benchmarks: Random Access 📖Vortex (geomean): 0.964x ➖ How to read Verdict and Engines
unknown / unknown (0.994x ➖, 1↑ 1↓)
|
Benchmarks: TPC-H SF=1 on S3 📖Verdict: No clear signal (environment too noisy confidence) How to read Verdict and Engines
datafusion / vortex-file-compressed (1.005x ➖, 0↑ 0↓)
datafusion / vortex-compact (1.029x ➖, 0↑ 2↓)
datafusion / parquet (1.046x ➖, 0↑ 1↓)
duckdb / vortex-file-compressed (1.027x ➖, 0↑ 0↓)
duckdb / vortex-compact (1.014x ➖, 0↑ 0↓)
duckdb / parquet (1.017x ➖, 0↑ 0↓)
|
4a21a9f to
16b2711
Compare
Benchmarks: Appian on NVME 📖Verdict: No clear signal (low confidence) How to read Verdict and Engines
datafusion / vortex-file-compressed (0.994x ➖, 0↑ 0↓)
datafusion / parquet (0.995x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed (0.989x ➖, 0↑ 0↓)
duckdb / parquet (0.994x ➖, 0↑ 0↓)
duckdb / duckdb (0.995x ➖, 0↑ 0↓)
File Size Changes (19 files changed, -0.0% overall, 18↑ 1↓)
Totals:
|
Benchmarks: TPC-H SF=10 on S3 📖Verdict: No clear signal (low confidence) How to read Verdict and Engines
datafusion / vortex-file-compressed (1.011x ➖, 0↑ 0↓)
datafusion / vortex-compact (1.022x ➖, 0↑ 0↓)
datafusion / parquet (0.965x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed (0.959x ➖, 0↑ 0↓)
duckdb / vortex-compact (0.934x ➖, 0↑ 0↓)
duckdb / parquet (0.994x ➖, 0↑ 0↓)
|
Benchmarks: Compression 📖Vortex (geomean): 1.000x ➖ How to read Verdict and Engines
unknown / unknown (0.999x ➖, 0↑ 0↓)
|
Summary
The file writer previously drew its permitted encodings from a static
ALLOWED_ENCODINGSset compiled intovortex-file. The only way to write a narrower or wider set was to override the write strategy by hand, and the writer's policy was disconnected from the editions the session had registered. This PR makes the writer's encoding policy come from the session's enabled editions.Final PR in the stack, on top of #8945 (
add enabled-editions selection to the session) and #8944 (require schemes to declare their produced encodings).Changes
VortexWriteOptions::newresolvesenabled_encoding_idsand applies it both to the write strategy and to theArrayContext, so a replacement strategy cannot widen the policy.WriteStrategyBuilder::with_allow_encodingsnow also filters the BtrBlocks compressor viaretain_allowed_encodings(from feat[compressor]: require schemes to declare their produced encodings #8944), in either configuration order, so forbidden encodings are never produced rather than being rejected after the fact.ALLOWED_ENCODINGSis removed.register_default_encodingsstill registers everything for reading; the default session's write policy comes from the editions enabled byenable_default_editions.EnabledEditionsvariable permit no edition encodings, so lower-level test sessions invortex-file,vortex-layoutandvortex-parquet-variantopt in explicitly via a sharedenable_all_registered_array_encodingstest helper.The
vortex/src/editions/tests.rsround-trip tests exercise every writer customization path (default strategy, replacement builders, opaque/probe compressors, custom flat strategies and field writers) to confirm none can emit an encoding outside the enabled editions.Testing
cargo nextest run -p vortex-file -p vortex-layout -p vortex -p vortex-parquet-variant— 410 passedcargo clippy --all-targets --all-features -p vortex-file -p vortex-layout -p vortex -p vortex-jni -p vortex-parquet-variant— cleancargo +nightly fmt --all🤖 Generated with Claude Code