Skip to content

Commit bf7ca36

Browse files
committed
Store enabled editions on the session and gate the writer through it
Rework after review feedback: - The first-party edition declarations stay in the `vortex` facade (`vortex::editions`); the earlier move into `vortex-edition` is reverted. `vortex-edition` again holds only the types, the session variable, and the test harness. - `EditionSession` now stores the set of enabled editions alongside the declarations: `enable()` (validated, at most one edition per family), `enabled()`, and `enabled_encodings()` — the resolved union of the enabled editions' encoding sets. `register_default_editions` declares the editions and enables the default write editions: core2026.07.0, plus the newest unstable draft under the `unstable_encodings` feature. - The writer resolves its allow set from the session at write time: the flat leaf writer's normalize-with-error validation, the writer's pre-populated ArrayContext, and the compressor's scheme selection (via `CascadingCompressor::with_enabled_editions_gating`, resolved from the execution context per compression) all use the session's enabled encodings, falling back to the static `ALLOWED_ENCODINGS` registry for sessions with no enabled editions. Explicit `with_allow_encodings` sets still override everything. - `Scheme::produced_encodings` is now a required method returning `Vec<ArrayId>` (empty means the scheme only rearranges canonical arrays); all schemes, including test schemes and the tensor L2Denorm scheme, implement it. Signed-off-by: Claude <noreply@anthropic.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CK2nCuXnyd2g3mNHQC8Lz2
1 parent e8a8601 commit bf7ca36

58 files changed

Lines changed: 768 additions & 477 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.lock

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vortex-btrblocks/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ insta = { workspace = true }
4444
rstest = { workspace = true }
4545
test-with = { workspace = true }
4646
vortex-array = { workspace = true, features = ["_test-harness"] }
47-
vortex-edition = { workspace = true }
4847
vortex-session = { workspace = true }
4948

5049
[features]

vortex-btrblocks/src/builder.rs

Lines changed: 23 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,14 @@ pub const ALL_SCHEMES: &[&dyn Scheme] = &[
9191
#[derive(Debug, Clone)]
9292
pub struct BtrBlocksCompressorBuilder {
9393
schemes: Vec<&'static dyn Scheme>,
94+
gate_by_enabled_editions: bool,
9495
}
9596

9697
impl Default for BtrBlocksCompressorBuilder {
9798
fn default() -> Self {
9899
Self {
99100
schemes: ALL_SCHEMES.to_vec(),
101+
gate_by_enabled_editions: false,
100102
}
101103
}
102104
}
@@ -108,6 +110,7 @@ impl BtrBlocksCompressorBuilder {
108110
pub fn empty() -> Self {
109111
Self {
110112
schemes: Vec::new(),
113+
gate_by_enabled_editions: false,
111114
}
112115
}
113116

@@ -209,32 +212,38 @@ impl BtrBlocksCompressorBuilder {
209212
self
210213
}
211214

212-
/// Retains only schemes whose declared produced encodings all belong to `allowed`.
213-
///
214-
/// Schemes that do not declare their produced encodings (see
215-
/// [`Scheme::produced_encodings`]) are removed as well: the compressor cannot prove
216-
/// their output stays within the allowed set. The file writer uses this to restrict
217-
/// compression to the encodings of its configured editions.
215+
/// Retains only schemes whose declared produced encodings (see
216+
/// [`Scheme::produced_encodings`]) all belong to `allowed`. The file writer uses this
217+
/// to restrict compression to an explicitly configured allow set.
218218
pub fn retain_allowed_encodings(mut self, allowed: &HashSet<ArrayId>) -> Self {
219-
self.schemes.retain(|s| {
220-
s.produced_encodings()
221-
.is_some_and(|ids| ids.iter().all(|id| allowed.contains(id)))
222-
});
219+
self.schemes
220+
.retain(|s| s.produced_encodings().iter().all(|id| allowed.contains(id)));
221+
self
222+
}
223+
224+
/// Gate scheme selection by the session's enabled editions at compression time.
225+
///
226+
/// See [`CascadingCompressor::with_enabled_editions_gating`]. The file writer enables
227+
/// this by default so compression only chooses encodings from the session's enabled
228+
/// editions.
229+
pub fn gate_by_enabled_editions(mut self) -> Self {
230+
self.gate_by_enabled_editions = true;
223231
self
224232
}
225233

226234
/// Builds the configured [`BtrBlocksCompressor`].
227235
pub fn build(self) -> BtrBlocksCompressor {
228-
BtrBlocksCompressor(CascadingCompressor::new(self.schemes))
236+
let mut compressor = CascadingCompressor::new(self.schemes);
237+
if self.gate_by_enabled_editions {
238+
compressor = compressor.with_enabled_editions_gating();
239+
}
240+
BtrBlocksCompressor(compressor)
229241
}
230242
}
231243

232244
#[cfg(test)]
233245
mod tests {
234246
use vortex_array::VTable;
235-
use vortex_edition::declarations::CORE_2026_07_0;
236-
use vortex_edition::declarations::UNSTABLE_2026_06_0;
237-
use vortex_edition::declarations::encodings_in_editions;
238247
use vortex_fastlanes::FoR;
239248

240249
use super::*;
@@ -251,17 +260,6 @@ mod tests {
251260
assert_eq!(builder.schemes.len(), ALL_SCHEMES.len());
252261
}
253262

254-
#[test]
255-
fn all_schemes_declare_produced_encodings() {
256-
for scheme in ALL_SCHEMES {
257-
assert!(
258-
scheme.produced_encodings().is_some(),
259-
"scheme {} must declare its produced encodings",
260-
scheme.id()
261-
);
262-
}
263-
}
264-
265263
#[test]
266264
fn retain_allowed_encodings_filters_schemes() {
267265
let allowed: HashSet<ArrayId> = [FoR.id()].into_iter().collect();
@@ -273,20 +271,6 @@ mod tests {
273271
assert!(none.schemes.is_empty());
274272
}
275273

276-
/// Every default scheme must produce only encodings covered by the writer's default
277-
/// editions, otherwise the default file writer would silently drop it.
278-
#[test]
279-
fn default_schemes_stay_within_default_editions() {
280-
let editions = if cfg!(feature = "unstable_encodings") {
281-
vec![CORE_2026_07_0, UNSTABLE_2026_06_0]
282-
} else {
283-
vec![CORE_2026_07_0]
284-
};
285-
let allowed: HashSet<ArrayId> = encodings_in_editions(&editions).into_iter().collect();
286-
let builder = BtrBlocksCompressorBuilder::default().retain_allowed_encodings(&allowed);
287-
assert_eq!(builder.schemes.len(), ALL_SCHEMES.len());
288-
}
289-
290274
#[test]
291275
fn cuda_compatible_excludes_alprd() {
292276
let builder = BtrBlocksCompressorBuilder::default().only_cuda_compatible();

vortex-btrblocks/src/schemes/binary/zstd.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ impl Scheme for ZstdScheme {
3131
canonical.dtype().is_binary()
3232
}
3333

34-
fn produced_encodings(&self) -> Option<Vec<ArrayId>> {
35-
Some(vec![vortex_zstd::Zstd.id()])
34+
fn produced_encodings(&self) -> Vec<ArrayId> {
35+
vec![vortex_zstd::Zstd.id()]
3636
}
3737

3838
fn expected_compression_ratio(

vortex-btrblocks/src/schemes/binary/zstd_buffers.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ impl Scheme for ZstdBuffersScheme {
3131
canonical.dtype().is_binary()
3232
}
3333

34-
fn produced_encodings(&self) -> Option<Vec<ArrayId>> {
35-
Some(vec![vortex_zstd::ZstdBuffers.id()])
34+
fn produced_encodings(&self) -> Vec<ArrayId> {
35+
vec![vortex_zstd::ZstdBuffers.id()]
3636
}
3737

3838
fn expected_compression_ratio(

vortex-btrblocks/src/schemes/decimal.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ impl Scheme for DecimalScheme {
4040
matches!(canonical, Canonical::Decimal(_))
4141
}
4242

43-
fn produced_encodings(&self) -> Option<Vec<ArrayId>> {
44-
Some(vec![DecimalByteParts.id()])
43+
fn produced_encodings(&self) -> Vec<ArrayId> {
44+
vec![DecimalByteParts.id()]
4545
}
4646

4747
/// Children: primitive=0.

vortex-btrblocks/src/schemes/float/alp.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ impl Scheme for ALPScheme {
4242
canonical.dtype().is_float()
4343
}
4444

45-
fn produced_encodings(&self) -> Option<Vec<ArrayId>> {
45+
fn produced_encodings(&self) -> Vec<ArrayId> {
4646
let mut encodings = vec![ALP.id()];
4747
if use_experimental_patches() {
4848
encodings.push(Patched.id());
4949
}
50-
Some(encodings)
50+
encodings
5151
}
5252

5353
/// Children: encoded_ints=0.

vortex-btrblocks/src/schemes/float/alprd.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ impl Scheme for ALPRDScheme {
3939
canonical.dtype().is_float()
4040
}
4141

42-
fn produced_encodings(&self) -> Option<Vec<ArrayId>> {
43-
Some(vec![vortex_alp::ALPRD.id()])
42+
fn produced_encodings(&self) -> Vec<ArrayId> {
43+
vec![vortex_alp::ALPRD.id()]
4444
}
4545

4646
fn expected_compression_ratio(

vortex-btrblocks/src/schemes/float/pco.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ impl Scheme for PcoScheme {
3131
canonical.dtype().is_float()
3232
}
3333

34-
fn produced_encodings(&self) -> Option<Vec<ArrayId>> {
35-
Some(vec![vortex_pco::Pco.id()])
34+
fn produced_encodings(&self) -> Vec<ArrayId> {
35+
vec![vortex_pco::Pco.id()]
3636
}
3737

3838
fn expected_compression_ratio(

vortex-btrblocks/src/schemes/float/rle.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ impl Scheme for FloatRLEScheme {
3838
canonical.dtype().is_float()
3939
}
4040

41-
fn produced_encodings(&self) -> Option<Vec<ArrayId>> {
42-
Some(vec![RLE.id()])
41+
fn produced_encodings(&self) -> Vec<ArrayId> {
42+
vec![RLE.id()]
4343
}
4444

4545
/// Children: values=0, indices=1, offsets=2.

0 commit comments

Comments
 (0)