From 06c1faade81ba2e32b86e0b445292d272d431c6f Mon Sep 17 00:00:00 2001 From: Joe Isaacs Date: Mon, 2 Feb 2026 14:58:55 +0000 Subject: [PATCH] feat[layout]: validate arrays written to flat layout Signed-off-by: Joe Isaacs --- fuzz/fuzz_targets/file_io.rs | 2 +- vortex-array/src/lib.rs | 1 + vortex-array/src/normalize.rs | 52 ++++++++++ vortex-bench/src/lib.rs | 2 +- vortex-file/src/strategy.rs | 117 +++++++++++++++++++--- vortex-file/src/tests.rs | 80 --------------- vortex-file/src/writer.rs | 7 +- vortex-layout/src/layouts/flat/writer.rs | 119 +++++++++++++++++++++++ vortex-layout/src/layouts/table.rs | 25 ++--- vortex-python/src/io.rs | 2 +- vortex/examples/tracing_vortex.rs | 2 +- vortex/src/lib.rs | 2 +- 12 files changed, 293 insertions(+), 118 deletions(-) create mode 100644 vortex-array/src/normalize.rs diff --git a/fuzz/fuzz_targets/file_io.rs b/fuzz/fuzz_targets/file_io.rs index 16ad9276f85..b508f6eccb2 100644 --- a/fuzz/fuzz_targets/file_io.rs +++ b/fuzz/fuzz_targets/file_io.rs @@ -61,7 +61,7 @@ fuzz_target!(|fuzz: FuzzFileAction| -> Corpus { let write_options = match compressor_strategy { CompressorStrategy::Default => SESSION.write_options(), CompressorStrategy::Compact => { - let strategy = WriteStrategyBuilder::new() + let strategy = WriteStrategyBuilder::default() .with_compressor(CompactCompressor::default()) .build(); SESSION.write_options().with_strategy(strategy) diff --git a/vortex-array/src/lib.rs b/vortex-array/src/lib.rs index d315de33d8b..7d355cc2ec3 100644 --- a/vortex-array/src/lib.rs +++ b/vortex-array/src/lib.rs @@ -50,6 +50,7 @@ pub mod mask; mod mask_future; pub mod matchers; mod metadata; +pub mod normalize; pub mod optimizer; mod partial_ord; pub mod patches; diff --git a/vortex-array/src/normalize.rs b/vortex-array/src/normalize.rs new file mode 100644 index 00000000000..c69919e9342 --- /dev/null +++ b/vortex-array/src/normalize.rs @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: Copyright the Vortex contributors + +use itertools::Itertools; +use vortex_error::VortexResult; +use vortex_error::vortex_bail; +use vortex_session::registry::Id; + +use crate::Array; +use crate::ArrayRef; +use crate::ArrayVisitor; +use crate::session::ArrayRegistry; + +/// Options for normalizing an array. +pub struct NormalizeOptions<'a> { + /// The set of allowed array encodings (in addition to the canonical ones) that are permitted + /// in the normalized array. + pub allowed: &'a ArrayRegistry, + /// The operation to perform when a non-allowed encoding is encountered. + pub operation: Operation, +} + +/// The operation to perform when a non-allowed encoding is encountered. +pub enum Operation { + Error, + // TODO(joe): add into canonical variant +} + +impl dyn Array + '_ { + /// Normalize the array according to given options. + /// + /// This operation performs a recursive traversal of the array. Any non-allowed encoding is + /// normalized per the configured operation. + pub fn normalize(self: ArrayRef, options: &mut NormalizeOptions) -> VortexResult { + let array_ids = options.allowed.ids().collect_vec(); + self.normalize_with_error(&array_ids)?; + // Note this takes ownership so we can at a later date remove non-allowed encodings. + Ok(self) + } + + fn normalize_with_error(self: &ArrayRef, allowed: &[Id]) -> VortexResult<()> { + if !allowed.contains(&self.encoding_id()) { + vortex_bail!(AssertionFailed: "normalize forbids encoding ({})", self.encoding_id()) + } + + for child in ArrayVisitor::children(self) { + let child: ArrayRef = child; + child.normalize_with_error(allowed)? + } + Ok(()) + } +} diff --git a/vortex-bench/src/lib.rs b/vortex-bench/src/lib.rs index fea3d15488d..5db8b34736e 100644 --- a/vortex-bench/src/lib.rs +++ b/vortex-bench/src/lib.rs @@ -212,7 +212,7 @@ impl CompactionStrategy { pub fn apply_options(&self, options: VortexWriteOptions) -> VortexWriteOptions { match self { CompactionStrategy::Compact => options.with_strategy( - WriteStrategyBuilder::new() + WriteStrategyBuilder::default() .with_compressor(CompactCompressor::default()) .build(), ), diff --git a/vortex-file/src/strategy.rs b/vortex-file/src/strategy.rs index d10500e9ed8..6f90864979f 100644 --- a/vortex-file/src/strategy.rs +++ b/vortex-file/src/strategy.rs @@ -4,8 +4,37 @@ //! This module defines the default layout strategy for a Vortex file. use std::sync::Arc; - +use std::sync::LazyLock; + +// Compressed encodings from encoding crates +use vortex_alp::ALPRDVTable; +use vortex_alp::ALPVTable; +// Canonical array encodings from vortex-array +use vortex_array::arrays::BoolVTable; +use vortex_array::arrays::ChunkedVTable; +use vortex_array::arrays::ConstantVTable; +use vortex_array::arrays::DecimalVTable; +use vortex_array::arrays::DictVTable; +use vortex_array::arrays::ExtensionVTable; +use vortex_array::arrays::FixedSizeListVTable; +use vortex_array::arrays::ListVTable; +use vortex_array::arrays::ListViewVTable; +use vortex_array::arrays::MaskedVTable; +use vortex_array::arrays::NullVTable; +use vortex_array::arrays::PrimitiveVTable; +use vortex_array::arrays::StructVTable; +use vortex_array::arrays::VarBinVTable; +use vortex_array::arrays::VarBinViewVTable; +use vortex_array::session::ArrayRegistry; +use vortex_bytebool::ByteBoolVTable; +use vortex_datetime_parts::DateTimePartsVTable; +use vortex_decimal_byte_parts::DecimalBytePartsVTable; use vortex_dtype::FieldPath; +use vortex_fastlanes::BitPackedVTable; +use vortex_fastlanes::DeltaVTable; +use vortex_fastlanes::FoRVTable; +use vortex_fastlanes::RLEVTable; +use vortex_fsst::FSSTVTable; use vortex_layout::LayoutStrategy; use vortex_layout::layouts::buffered::BufferedStrategy; use vortex_layout::layouts::chunked::writer::ChunkedLayoutStrategy; @@ -19,10 +48,64 @@ use vortex_layout::layouts::repartition::RepartitionWriterOptions; use vortex_layout::layouts::table::TableStrategy; use vortex_layout::layouts::zoned::writer::ZonedLayoutOptions; use vortex_layout::layouts::zoned::writer::ZonedStrategy; +use vortex_pco::PcoVTable; +use vortex_runend::RunEndVTable; +use vortex_sequence::SequenceVTable; +use vortex_sparse::SparseVTable; use vortex_utils::aliases::hash_map::HashMap; +use vortex_zigzag::ZigZagVTable; +#[cfg(feature = "zstd")] +use vortex_zstd::ZstdVTable; const ONE_MEG: u64 = 1 << 20; +/// Static registry of all allowed array encodings for file writing. +/// +/// This includes all canonical encodings from vortex-array plus all compressed +/// encodings from the various encoding crates. +pub static ALLOWED_ENCODINGS: LazyLock = LazyLock::new(|| { + let registry = ArrayRegistry::default(); + + // Canonical encodings from vortex-array + registry.register(NullVTable::ID, NullVTable); + registry.register(BoolVTable::ID, BoolVTable); + registry.register(PrimitiveVTable::ID, PrimitiveVTable); + registry.register(DecimalVTable::ID, DecimalVTable); + registry.register(VarBinVTable::ID, VarBinVTable); + registry.register(VarBinViewVTable::ID, VarBinViewVTable); + registry.register(ListVTable::ID, ListVTable); + registry.register(ListViewVTable::ID, ListViewVTable); + registry.register(FixedSizeListVTable::ID, FixedSizeListVTable); + registry.register(StructVTable::ID, StructVTable); + registry.register(ExtensionVTable::ID, ExtensionVTable); + registry.register(ChunkedVTable::ID, ChunkedVTable); + registry.register(ConstantVTable::ID, ConstantVTable); + registry.register(MaskedVTable::ID, MaskedVTable); + registry.register(DictVTable::ID, DictVTable); + + // Compressed encodings from encoding crates + registry.register(ALPVTable::ID, ALPVTable); + registry.register(ALPRDVTable::ID, ALPRDVTable); + registry.register(BitPackedVTable::ID, BitPackedVTable); + registry.register(ByteBoolVTable::ID, ByteBoolVTable); + registry.register(DateTimePartsVTable::ID, DateTimePartsVTable); + registry.register(DecimalBytePartsVTable::ID, DecimalBytePartsVTable); + registry.register(DeltaVTable::ID, DeltaVTable); + registry.register(FoRVTable::ID, FoRVTable); + registry.register(FSSTVTable::ID, FSSTVTable); + registry.register(PcoVTable::ID, PcoVTable); + registry.register(RLEVTable::ID, RLEVTable); + registry.register(RunEndVTable::ID, RunEndVTable); + registry.register(SequenceVTable::ID, SequenceVTable); + registry.register(SparseVTable::ID, SparseVTable); + registry.register(ZigZagVTable::ID, ZigZagVTable); + + #[cfg(feature = "zstd")] + registry.register(ZstdVTable::ID, ZstdVTable); + + registry +}); + /// Build a new [writer strategy][LayoutStrategy] to compress and reorganize chunks of a Vortex file. /// /// Vortex provides an out-of-the-box file writer that optimizes the layout of chunks on-disk, @@ -32,25 +115,23 @@ pub struct WriteStrategyBuilder { compressor: Option>, row_block_size: usize, field_writers: HashMap>, + allow_encodings: Option, } impl Default for WriteStrategyBuilder { + /// Create a new empty builder. It can be further configured, + /// and then finally built yielding the [`LayoutStrategy`]. fn default() -> Self { - Self::new() - } -} - -impl WriteStrategyBuilder { - /// Create a new empty builder. It can be further configured, and then finally built - /// yielding the [`LayoutStrategy`]. - pub fn new() -> Self { Self { compressor: None, row_block_size: 8192, field_writers: HashMap::new(), + allow_encodings: None, } } +} +impl WriteStrategyBuilder { /// Override the [compressor][CompressorPlugin] used for compressing chunks in the file. /// /// If not provided, this will use a BtrBlocks-style cascading compressor that tries to balance @@ -77,11 +158,23 @@ impl WriteStrategyBuilder { self } + /// Override the allowed array encodings for normalization. + pub fn with_allow_encodings(mut self, allow_encodings: ArrayRegistry) -> Self { + self.allow_encodings = Some(allow_encodings); + self + } + /// Builds the canonical [`LayoutStrategy`] implementation, with the configured overrides /// applied. pub fn build(self) -> Arc { + let flat = if let Some(allow_encodings) = self.allow_encodings { + FlatLayoutStrategy::default().with_allow_encodings(allow_encodings) + } else { + FlatLayoutStrategy::default() + }; + // 7. for each chunk create a flat layout - let chunked = ChunkedLayoutStrategy::new(FlatLayoutStrategy::default()); + let chunked = ChunkedLayoutStrategy::new(flat.clone()); // 6. buffer chunks so they end up with closer segment ids physically let buffered = BufferedStrategy::new(chunked, 2 * ONE_MEG); // 2MB // 5. compress each chunk @@ -110,9 +203,9 @@ impl WriteStrategyBuilder { // 2.1. | 3.1. compress stats tables and dict values. let compress_then_flat = if let Some(ref compressor) = self.compressor { - CompressingStrategy::new_opaque(FlatLayoutStrategy::default(), compressor.clone()) + CompressingStrategy::new_opaque(flat, compressor.clone()) } else { - CompressingStrategy::new_btrblocks(FlatLayoutStrategy::default(), false) + CompressingStrategy::new_btrblocks(flat, false) }; // 3. apply dict encoding or fallback diff --git a/vortex-file/src/tests.rs b/vortex-file/src/tests.rs index 5d5053f8372..81f7b29f7d0 100644 --- a/vortex-file/src/tests.rs +++ b/vortex-file/src/tests.rs @@ -50,7 +50,6 @@ use vortex_array::validity::Validity; use vortex_buffer::Buffer; use vortex_buffer::ByteBufferMut; use vortex_buffer::buffer; -use vortex_cuda_macros::cuda_tests; use vortex_dtype::DType; use vortex_dtype::DecimalDType; use vortex_dtype::ExtDType; @@ -1640,82 +1639,3 @@ async fn main_test() -> Result<(), Box> { Ok(()) } - -#[cuda_tests] -#[cfg(not(target_arch = "wasm32"))] -mod tests { - use std::sync::Arc; - - use futures::StreamExt; - use vortex_array::IntoArray; - use vortex_array::arrays::PrimitiveArray; - use vortex_cuda::CanonicalCudaExt; - use vortex_cuda::CopyDeviceReadAt; - use vortex_cuda::CudaSession; - use vortex_cuda::CudaSessionExt; - use vortex_cuda::executor::CudaArrayExt; - use vortex_error::VortexResult; - use vortex_io::file::std_file::FileReadAdapter; - use vortex_io::session::RuntimeSessionExt; - - use crate::OpenOptionsSessionExt; - use crate::WriteOptionsSessionExt; - use crate::tests::SESSION; - - #[tokio::test] - async fn gpu_scan() -> VortexResult<()> { - use vortex_alp::alp_encode; - - // Create an ALP-encoded array from primitive f64 values - let primitive = PrimitiveArray::from_iter((0..100).map(|i| i as f64 * 1.1)); - let alp_array = alp_encode(&primitive, None)?; - - // Write to a buffer, then to a temp file - let temp_path = std::env::temp_dir().join("gpu_scan_test.vortex"); - let mut buf = Vec::new(); - SESSION - .write_options() - .write(&mut buf, alp_array.to_array_stream()) - .await?; - std::fs::write(&temp_path, &buf)?; - - // Read back via GPU - let handle = SESSION.handle(); - let source = Arc::new(FileReadAdapter::open(&temp_path, handle)?); - let gpu_reader = - CopyDeviceReadAt::new(source.clone(), SESSION.cuda_session().new_stream()?); - let cpu_reader = source; - - let cpu_file = SESSION.open_options().open_read(cpu_reader).await?; - - let gpu_file = SESSION - .open_options() - .with_footer(cpu_file.footer) - .open_read(gpu_reader) - .await?; - - let mut cuda_ctx = CudaSession::create_execution_ctx(&SESSION)?; - - let mut res = Vec::new(); - let mut stream = gpu_file.scan()?.into_array_stream()?; - while let Some(a) = stream.next().await { - let a = a?; - let array = a - .execute_cuda(&mut cuda_ctx) - .await? - .into_host() - .await? - .into_array(); - res.push(array); - } - - for a in res { - println!("a {} ", a.display_tree()) - } - - // Cleanup - std::fs::remove_file(&temp_path)?; - - Ok(()) - } -} diff --git a/vortex-file/src/writer.rs b/vortex-file/src/writer.rs index 50c031e2223..789d692857a 100644 --- a/vortex-file/src/writer.rs +++ b/vortex-file/src/writer.rs @@ -69,9 +69,10 @@ pub struct VortexWriteOptions { pub trait WriteOptionsSessionExt: SessionExt { /// Create [`VortexWriteOptions`] for writing to a Vortex file. fn write_options(&self) -> VortexWriteOptions { + let session = self.session(); VortexWriteOptions { - session: self.session(), - strategy: WriteStrategyBuilder::new().build(), + strategy: WriteStrategyBuilder::default().build(), + session, exclude_dtype: false, file_statistics: PRUNING_STATS.to_vec(), max_variable_length_statistics_size: 64, @@ -84,8 +85,8 @@ impl VortexWriteOptions { /// Create a new [`VortexWriteOptions`] with the given session. pub fn new(session: VortexSession) -> Self { VortexWriteOptions { + strategy: WriteStrategyBuilder::default().build(), session, - strategy: WriteStrategyBuilder::new().build(), exclude_dtype: false, file_statistics: PRUNING_STATS.to_vec(), max_variable_length_statistics_size: 64, diff --git a/vortex-layout/src/layouts/flat/writer.rs b/vortex-layout/src/layouts/flat/writer.rs index 98151d7ba74..33f0cd7cc64 100644 --- a/vortex-layout/src/layouts/flat/writer.rs +++ b/vortex-layout/src/layouts/flat/writer.rs @@ -8,7 +8,10 @@ use vortex_array::ArrayContext; use vortex_array::expr::stats::Precision; use vortex_array::expr::stats::Stat; use vortex_array::expr::stats::StatsProvider; +use vortex_array::normalize::NormalizeOptions; +use vortex_array::normalize::Operation; use vortex_array::serde::SerializeOptions; +use vortex_array::session::ArrayRegistry; use vortex_dtype::DType; use vortex_error::VortexResult; use vortex_error::vortex_bail; @@ -31,6 +34,9 @@ pub struct FlatLayoutStrategy { pub include_padding: bool, /// Maximum length of variable length statistics pub max_variable_length_statistics_size: usize, + /// Optional set of allowed array encodings for normalization. + /// If None, then all are allowed. + pub allowed_encodings: Option, } impl Default for FlatLayoutStrategy { @@ -38,10 +44,31 @@ impl Default for FlatLayoutStrategy { Self { include_padding: true, max_variable_length_statistics_size: 64, + allowed_encodings: None, } } } +impl FlatLayoutStrategy { + /// Set whether to include padding for memory-mapped reads. + pub fn with_include_padding(mut self, include_padding: bool) -> Self { + self.include_padding = include_padding; + self + } + + /// Set the maximum length of variable length statistics. + pub fn with_max_variable_length_statistics_size(mut self, size: usize) -> Self { + self.max_variable_length_statistics_size = size; + self + } + + /// Set the allowed array encodings for normalization. + pub fn with_allow_encodings(mut self, allow_encodings: ArrayRegistry) -> Self { + self.allowed_encodings = Some(allow_encodings); + self + } +} + #[async_trait] impl LayoutStrategy for FlatLayoutStrategy { async fn write_stream( @@ -123,6 +150,15 @@ impl LayoutStrategy for FlatLayoutStrategy { _ => {} } + let chunk = if let Some(allowed) = &options.allowed_encodings { + chunk.normalize(&mut NormalizeOptions { + allowed, + operation: Operation::Error, + })? + } else { + chunk + }; + let buffers = chunk.serialize( &ctx, &SerializeOptions { @@ -166,7 +202,10 @@ mod tests { use vortex_array::MaskFuture; use vortex_array::ToCanonical; use vortex_array::arrays::BoolArray; + use vortex_array::arrays::DictArray; + use vortex_array::arrays::DictVTable; use vortex_array::arrays::PrimitiveArray; + use vortex_array::arrays::PrimitiveVTable; use vortex_array::arrays::StructArray; use vortex_array::builders::ArrayBuilder; use vortex_array::builders::VarBinViewBuilder; @@ -174,6 +213,7 @@ mod tests { use vortex_array::expr::stats::Precision; use vortex_array::expr::stats::Stat; use vortex_array::expr::stats::StatsProviderExt; + use vortex_array::session::ArrayRegistry; use vortex_array::validity::Validity; use vortex_buffer::BitBufferMut; use vortex_buffer::buffer; @@ -182,8 +222,10 @@ mod tests { use vortex_dtype::FieldNames; use vortex_dtype::Nullability; use vortex_error::VortexExpect; + use vortex_error::VortexResult; use vortex_io::runtime::single::block_on; use vortex_mask::AllOr; + use vortex_mask::Mask; use crate::LayoutStrategy; use crate::layouts::flat::writer::FlatLayoutStrategy; @@ -369,4 +411,81 @@ mod tests { ); }) } + + #[test] + fn flat_invalid_array_fails() -> VortexResult<()> { + block_on(|handle| async { + let prim: PrimitiveArray = (0..10).collect(); + let filter = prim.filter(Mask::from_indices(10, vec![2, 3]))?; + + let ctx = ArrayContext::empty(); + + // Write the array into a byte buffer. + let (layout, _segments) = { + let segments = Arc::new(TestSegments::default()); + let (ptr, eof) = SequenceId::root().split(); + // Only allow primitive encodings - filter arrays should fail. + let allowed = ArrayRegistry::default(); + allowed.register(PrimitiveVTable::ID, PrimitiveVTable); + let layout = FlatLayoutStrategy::default() + .with_allow_encodings(allowed) + .write_stream( + ctx, + segments.clone(), + filter.to_array_stream().sequenced(ptr), + eof, + handle, + ) + .await; + + (layout, segments) + }; + + let err = layout.expect_err("expected error"); + assert!( + err.to_string() + .contains("normalize forbids encoding (vortex.filter)"), + "unexpected error: {err}" + ); + + Ok(()) + }) + } + + #[test] + fn flat_valid_array_writes() -> VortexResult<()> { + block_on(|handle| async { + let codes: PrimitiveArray = (0u32..10).collect(); + let values: PrimitiveArray = (0..10).collect(); + let dict = DictArray::new(codes.into_array(), values.into_array()); + + let ctx = ArrayContext::empty(); + + // Write the array into a byte buffer. + let (layout, _segments) = { + let segments = Arc::new(TestSegments::default()); + let (ptr, eof) = SequenceId::root().split(); + // Only allow primitive encodings - filter arrays should fail. + let allowed = ArrayRegistry::default(); + allowed.register(PrimitiveVTable::ID, PrimitiveVTable); + allowed.register(DictVTable::ID, DictVTable); + let layout = FlatLayoutStrategy::default() + .with_allow_encodings(allowed) + .write_stream( + ctx, + segments.clone(), + dict.to_array_stream().sequenced(ptr), + eof, + handle, + ) + .await; + + (layout, segments) + }; + + assert!(layout.is_ok()); + + Ok(()) + }) + } } diff --git a/vortex-layout/src/layouts/table.rs b/vortex-layout/src/layouts/table.rs index 13ad7f8f51d..faff6190191 100644 --- a/vortex-layout/src/layouts/table.rs +++ b/vortex-layout/src/layouts/table.rs @@ -33,7 +33,6 @@ use vortex_utils::aliases::hash_set::HashSet; use crate::IntoLayout; use crate::LayoutRef; use crate::LayoutStrategy; -use crate::layouts::flat::writer::FlatLayoutStrategy; use crate::layouts::struct_::StructLayout; use crate::segments::SegmentSinkRef; use crate::sequence::SendableSequentialStream; @@ -53,18 +52,6 @@ pub struct TableStrategy { fallback: Arc, } -impl Default for TableStrategy { - fn default() -> Self { - let flat = Arc::new(FlatLayoutStrategy::default()); - - Self { - leaf_writers: HashMap::default(), - validity: flat.clone(), - fallback: flat, - } - } -} - impl TableStrategy { /// Create a new writer with the specified write strategies for validity, and for all leaf /// fields, with no overrides. @@ -73,7 +60,7 @@ impl TableStrategy { /// /// ## Example /// - /// ``` + /// ```ignore /// # use std::sync::Arc; /// # use vortex_layout::layouts::flat::writer::FlatLayoutStrategy; /// # use vortex_layout::layouts::table::TableStrategy; @@ -95,7 +82,7 @@ impl TableStrategy { /// /// ## Example /// - /// ```no_run + /// ```ignore /// # use std::sync::Arc; /// # use vortex_dtype::{field_path, Field, FieldPath}; /// # use vortex_layout::layouts::compact::CompactCompressor; @@ -389,7 +376,8 @@ mod tests { let flat = Arc::new(FlatLayoutStrategy::default()); // Success - let path = TableStrategy::default().with_field_writer(field_path!(a.b.c), flat.clone()); + let path = TableStrategy::new(flat.clone(), flat.clone()) + .with_field_writer(field_path!(a.b.c), flat.clone()); // Should panic right here. let _path = path.with_field_writer(field_path!(a.b), flat); @@ -400,7 +388,8 @@ mod tests { expected = "Do not set override as a root strategy, instead set the default strategy" )] fn test_root_override() { - let _strategy = TableStrategy::default() - .with_field_writer(FieldPath::root(), Arc::new(FlatLayoutStrategy::default())); + let flat = Arc::new(FlatLayoutStrategy::default()); + let _strategy = TableStrategy::new(flat.clone(), flat.clone()) + .with_field_writer(FieldPath::root(), flat); } } diff --git a/vortex-python/src/io.rs b/vortex-python/src/io.rs index 67bf253293a..22743e4828d 100644 --- a/vortex-python/src/io.rs +++ b/vortex-python/src/io.rs @@ -349,7 +349,7 @@ impl PyVortexWriteOptions { store: Option, ) -> PyVortexResult<()> { py.detach(|| { - let mut strategy = WriteStrategyBuilder::new(); + let mut strategy = WriteStrategyBuilder::default(); if let Some(compressor) = self.compressor.as_ref() { strategy = strategy.with_compressor(compressor.clone()) } diff --git a/vortex/examples/tracing_vortex.rs b/vortex/examples/tracing_vortex.rs index fb849fb4e5c..8fc428e8de9 100644 --- a/vortex/examples/tracing_vortex.rs +++ b/vortex/examples/tracing_vortex.rs @@ -388,7 +388,7 @@ async fn write_batch_to_vortex( // Use the write-optimized CompactCompressor for the telemetry files. let write_opts = session.write_options().with_strategy( - WriteStrategyBuilder::new() + WriteStrategyBuilder::default() .with_compressor(CompactCompressor::default()) .build(), ); diff --git a/vortex/src/lib.rs b/vortex/src/lib.rs index 986a432d7a9..abab751fa57 100644 --- a/vortex/src/lib.rs +++ b/vortex/src/lib.rs @@ -317,7 +317,7 @@ mod test { session .write_options() .with_strategy( - WriteStrategyBuilder::new() + WriteStrategyBuilder::default() .with_compressor(CompactCompressor::default()) .build(), )