From a1d2e1ee1556f88ac71ae58b13422c2637ed6a48 Mon Sep 17 00:00:00 2001 From: Robert Kruszewski Date: Wed, 6 May 2026 22:29:26 +0100 Subject: [PATCH 1/2] Slots are a Box<[...]> instead of Vec<...> Signed-off-by: Robert Kruszewski --- encodings/alp/public-api.lock | 4 ++-- encodings/alp/src/alp/array.rs | 6 +++--- encodings/alp/src/alp_rd/array.rs | 6 +++--- encodings/bytebool/src/array.rs | 4 ++-- encodings/datetime-parts/public-api.lock | 4 ++-- encodings/datetime-parts/src/array.rs | 4 ++-- .../src/decimal_byte_parts/mod.rs | 4 ++-- encodings/fastlanes/public-api.lock | 4 ++-- .../fastlanes/src/bitpacking/vtable/mod.rs | 4 ++-- encodings/fastlanes/src/delta/vtable/mod.rs | 4 ++-- encodings/fastlanes/src/for/vtable/mod.rs | 4 ++-- encodings/fastlanes/src/rle/vtable/mod.rs | 6 +++--- encodings/fsst/src/array.rs | 10 +++++----- encodings/parquet-variant/src/array.rs | 4 ++-- encodings/parquet-variant/src/vtable.rs | 4 ++-- encodings/pco/src/array.rs | 4 ++-- encodings/runend/src/array.rs | 10 +++++----- encodings/sparse/src/lib.rs | 6 +++--- encodings/zigzag/src/array.rs | 4 ++-- encodings/zstd/src/array.rs | 4 ++-- encodings/zstd/src/zstd_buffers.rs | 4 ++-- vortex-array-macros/src/lib.rs | 15 ++++++++------- vortex-array/public-api.lock | 18 +++++++++--------- vortex-array/src/array/erased.rs | 9 ++++----- vortex-array/src/array/mod.rs | 13 +++++++++---- vortex-array/src/array/typed.rs | 10 +++++----- vortex-array/src/arrays/bool/array.rs | 4 ++-- vortex-array/src/arrays/chunked/array.rs | 6 +++--- vortex-array/src/arrays/chunked/vtable/mod.rs | 2 +- vortex-array/src/arrays/decimal/array.rs | 4 ++-- vortex-array/src/arrays/dict/array.rs | 8 +++++--- vortex-array/src/arrays/dict/vtable/mod.rs | 2 +- vortex-array/src/arrays/extension/array.rs | 2 +- .../src/arrays/extension/vtable/mod.rs | 2 +- vortex-array/src/arrays/filter/array.rs | 4 ++-- .../src/arrays/fixed_size_list/array.rs | 4 ++-- vortex-array/src/arrays/list/array.rs | 6 +++--- vortex-array/src/arrays/listview/array.rs | 8 ++++---- vortex-array/src/arrays/masked/array.rs | 2 +- vortex-array/src/arrays/masked/vtable/mod.rs | 2 +- vortex-array/src/arrays/patched/array.rs | 9 +++++---- vortex-array/src/arrays/patched/vtable/mod.rs | 2 +- vortex-array/src/arrays/primitive/array/mod.rs | 4 ++-- vortex-array/src/arrays/shared/array.rs | 2 +- vortex-array/src/arrays/slice/array.rs | 4 ++-- vortex-array/src/arrays/struct_/array.rs | 4 ++-- vortex-array/src/arrays/varbin/array.rs | 4 ++-- vortex-array/src/arrays/varbinview/array.rs | 6 +++--- vortex-array/src/arrays/variant/mod.rs | 3 ++- vortex-array/src/arrays/variant/vtable/mod.rs | 2 +- vortex-array/src/normalize.rs | 2 +- vortex-array/src/optimizer/mod.rs | 2 +- 52 files changed, 139 insertions(+), 130 deletions(-) diff --git a/encodings/alp/public-api.lock b/encodings/alp/public-api.lock index aff512e0406..516dcc7838f 100644 --- a/encodings/alp/public-api.lock +++ b/encodings/alp/public-api.lock @@ -314,9 +314,9 @@ pub const vortex_alp::ALPSlots::PATCH_INDICES: usize pub const vortex_alp::ALPSlots::PATCH_VALUES: usize -pub fn vortex_alp::ALPSlots::from_slots(alloc::vec::Vec>) -> Self +pub fn vortex_alp::ALPSlots::from_slots(alloc::boxed::Box<[core::option::Option]>) -> Self -pub fn vortex_alp::ALPSlots::into_slots(self) -> alloc::vec::Vec> +pub fn vortex_alp::ALPSlots::into_slots(self) -> alloc::boxed::Box<[core::option::Option]> pub struct vortex_alp::ALPSlotsView<'a> diff --git a/encodings/alp/src/alp/array.rs b/encodings/alp/src/alp/array.rs index 9bc9461f2bd..5f476019864 100644 --- a/encodings/alp/src/alp/array.rs +++ b/encodings/alp/src/alp/array.rs @@ -410,7 +410,7 @@ impl ALP { } impl ALPData { - fn make_slots(encoded: &ArrayRef, patches: Option<&Patches>) -> Vec> { + fn make_slots(encoded: &ArrayRef, patches: Option<&Patches>) -> Box<[Option]> { let (patch_indices, patch_values, patch_chunk_offsets) = match patches { Some(p) => ( Some(p.indices().clone()), @@ -419,12 +419,12 @@ impl ALPData { ), None => (None, None, None), }; - vec![ + Box::new([ Some(encoded.clone()), patch_indices, patch_values, patch_chunk_offsets, - ] + ]) } #[inline] diff --git a/encodings/alp/src/alp_rd/array.rs b/encodings/alp/src/alp_rd/array.rs index 55e299172e0..fdf6320ca30 100644 --- a/encodings/alp/src/alp_rd/array.rs +++ b/encodings/alp/src/alp_rd/array.rs @@ -465,7 +465,7 @@ impl ALPRDData { left_parts: &ArrayRef, right_parts: &ArrayRef, patches: Option<&Patches>, - ) -> Vec> { + ) -> Box<[Option]> { let (pi, pv, pco) = match patches { Some(p) => ( Some(p.indices().clone()), @@ -474,13 +474,13 @@ impl ALPRDData { ), None => (None, None, None), }; - vec![ + Box::new([ Some(left_parts.clone()), Some(right_parts.clone()), pi, pv, pco, - ] + ]) } /// Return all the owned parts of the array diff --git a/encodings/bytebool/src/array.rs b/encodings/bytebool/src/array.rs index 610f0ae7f6c..9e343a6313b 100644 --- a/encodings/bytebool/src/array.rs +++ b/encodings/bytebool/src/array.rs @@ -263,8 +263,8 @@ impl ByteBoolData { Ok(()) } - fn make_slots(validity: &Validity, len: usize) -> Vec> { - vec![validity_to_child(validity, len)] + fn make_slots(validity: &Validity, len: usize) -> Box<[Option]> { + Box::new([validity_to_child(validity, len)]) } pub fn new(buffer: BufferHandle) -> Self { diff --git a/encodings/datetime-parts/public-api.lock b/encodings/datetime-parts/public-api.lock index f6845205964..b3ec37c8ab9 100644 --- a/encodings/datetime-parts/public-api.lock +++ b/encodings/datetime-parts/public-api.lock @@ -180,9 +180,9 @@ pub const vortex_datetime_parts::DateTimePartsSlots::SECONDS: usize pub const vortex_datetime_parts::DateTimePartsSlots::SUBSECONDS: usize -pub fn vortex_datetime_parts::DateTimePartsSlots::from_slots(alloc::vec::Vec>) -> Self +pub fn vortex_datetime_parts::DateTimePartsSlots::from_slots(alloc::boxed::Box<[core::option::Option]>) -> Self -pub fn vortex_datetime_parts::DateTimePartsSlots::into_slots(self) -> alloc::vec::Vec> +pub fn vortex_datetime_parts::DateTimePartsSlots::into_slots(self) -> alloc::boxed::Box<[core::option::Option]> pub struct vortex_datetime_parts::DateTimePartsSlotsView<'a> diff --git a/encodings/datetime-parts/src/array.rs b/encodings/datetime-parts/src/array.rs index 133348290e2..62f8bd66aa8 100644 --- a/encodings/datetime-parts/src/array.rs +++ b/encodings/datetime-parts/src/array.rs @@ -169,7 +169,7 @@ impl VTable for DateTimeParts { len, )?; - let slots = vec![Some(days), Some(seconds), Some(subseconds)]; + let slots = Box::new([Some(days), Some(seconds), Some(subseconds)]); let data = DateTimePartsData {}; Ok(ArrayParts::new(self.clone(), dtype.clone(), len, data).with_slots(slots)) } @@ -275,7 +275,7 @@ impl DateTimeParts { ) -> VortexResult { let len = days.len(); DateTimePartsData::validate(&dtype, &days, &seconds, &subseconds, len)?; - let slots = vec![Some(days), Some(seconds), Some(subseconds)]; + let slots = Box::new([Some(days), Some(seconds), Some(subseconds)]); let data = DateTimePartsData {}; Ok(unsafe { Array::from_parts_unchecked( diff --git a/encodings/decimal-byte-parts/src/decimal_byte_parts/mod.rs b/encodings/decimal-byte-parts/src/decimal_byte_parts/mod.rs index 608f0a2d2bd..98949d45f9c 100644 --- a/encodings/decimal-byte-parts/src/decimal_byte_parts/mod.rs +++ b/encodings/decimal-byte-parts/src/decimal_byte_parts/mod.rs @@ -144,7 +144,7 @@ impl VTable for DecimalByteParts { "lower_part_count > 0 not currently supported" ); - let slots = vec![Some(msp.clone())]; + let slots = Box::new([Some(msp.clone())]); let data = DecimalBytePartsData::try_new(msp.dtype(), msp.len(), *decimal_dtype)?; Ok(ArrayParts::new(self.clone(), dtype.clone(), len, data).with_slots(slots)) } @@ -262,7 +262,7 @@ impl DecimalByteParts { ) -> VortexResult { let len = msp.len(); let dtype = DType::Decimal(decimal_dtype, msp.dtype().nullability()); - let slots = vec![Some(msp.clone())]; + let slots = Box::new([Some(msp.clone())]); let data = DecimalBytePartsData::try_new(msp.dtype(), msp.len(), decimal_dtype)?; Ok(unsafe { Array::from_parts_unchecked( diff --git a/encodings/fastlanes/public-api.lock b/encodings/fastlanes/public-api.lock index a3d3528eae2..6644268228f 100644 --- a/encodings/fastlanes/public-api.lock +++ b/encodings/fastlanes/public-api.lock @@ -274,9 +274,9 @@ pub const vortex_fastlanes::BitPackedSlots::PATCH_VALUES: usize pub const vortex_fastlanes::BitPackedSlots::VALIDITY_CHILD: usize -pub fn vortex_fastlanes::BitPackedSlots::from_slots(alloc::vec::Vec>) -> Self +pub fn vortex_fastlanes::BitPackedSlots::from_slots(alloc::boxed::Box<[core::option::Option]>) -> Self -pub fn vortex_fastlanes::BitPackedSlots::into_slots(self) -> alloc::vec::Vec> +pub fn vortex_fastlanes::BitPackedSlots::into_slots(self) -> alloc::boxed::Box<[core::option::Option]> pub struct vortex_fastlanes::Delta diff --git a/encodings/fastlanes/src/bitpacking/vtable/mod.rs b/encodings/fastlanes/src/bitpacking/vtable/mod.rs index ede4cfae5be..d1056280b8e 100644 --- a/encodings/fastlanes/src/bitpacking/vtable/mod.rs +++ b/encodings/fastlanes/src/bitpacking/vtable/mod.rs @@ -233,7 +233,7 @@ impl VTable for BitPacked { None => (None, None, None), }; let validity_slot = validity_to_child(&validity, len); - vec![pi, pv, pco, validity_slot] + Box::new([pi, pv, pco, validity_slot]) }; let data = BitPackedData::try_new( packed, @@ -331,7 +331,7 @@ impl BitPacked { None => (None, None, None), }; let validity_slot = validity_to_child(&validity, len); - vec![pi, pv, pco, validity_slot] + Box::new([pi, pv, pco, validity_slot]) }; let data = BitPackedData::try_new(packed, patches, bit_width, offset)?; Array::try_from_parts(ArrayParts::new(BitPacked, dtype, len, data).with_slots(slots)) diff --git a/encodings/fastlanes/src/delta/vtable/mod.rs b/encodings/fastlanes/src/delta/vtable/mod.rs index aafdd40b37f..72bedda6b2c 100644 --- a/encodings/fastlanes/src/delta/vtable/mod.rs +++ b/encodings/fastlanes/src/delta/vtable/mod.rs @@ -168,7 +168,7 @@ impl VTable for Delta { let deltas = children.get(1, dtype, deltas_len)?; let data = DeltaData::try_new(metadata.offset as usize)?; - let slots = vec![Some(bases), Some(deltas)]; + let slots = Box::new([Some(bases), Some(deltas)]); Ok(ArrayParts::new(self.clone(), dtype.clone(), len, data).with_slots(slots)) } @@ -191,7 +191,7 @@ impl Delta { ) -> VortexResult { let dtype = bases.dtype().with_nullability(deltas.dtype().nullability()); let data = DeltaData::try_new(offset)?; - let slots = vec![Some(bases), Some(deltas)]; + let slots = Box::new([Some(bases), Some(deltas)]); Array::try_from_parts(ArrayParts::new(Delta, dtype, len, data).with_slots(slots)) } diff --git a/encodings/fastlanes/src/for/vtable/mod.rs b/encodings/fastlanes/src/for/vtable/mod.rs index 8c8eb9560a9..07fd744134b 100644 --- a/encodings/fastlanes/src/for/vtable/mod.rs +++ b/encodings/fastlanes/src/for/vtable/mod.rs @@ -132,7 +132,7 @@ impl VTable for FoR { let scalar_value = ScalarValue::from_proto_bytes(metadata, dtype, session)?; let reference = Scalar::try_new(dtype.clone(), scalar_value)?; let encoded = children.get(0, dtype, len)?; - let slots = vec![Some(encoded)]; + let slots = Box::new([Some(encoded)]); let data = FoRData::try_new(reference)?; Ok(ArrayParts::new(self.clone(), dtype.clone(), len, data).with_slots(slots)) @@ -173,7 +173,7 @@ impl FoR { let reference = reference.cast(&dtype)?; let len = encoded.len(); let data = FoRData::try_new(reference)?; - let slots = vec![Some(encoded)]; + let slots = Box::new([Some(encoded)]); Array::try_from_parts(ArrayParts::new(FoR, dtype, len, data).with_slots(slots)) } diff --git a/encodings/fastlanes/src/rle/vtable/mod.rs b/encodings/fastlanes/src/rle/vtable/mod.rs index d029f9b866d..e42757ad180 100644 --- a/encodings/fastlanes/src/rle/vtable/mod.rs +++ b/encodings/fastlanes/src/rle/vtable/mod.rs @@ -186,7 +186,7 @@ impl VTable for RLE { usize::try_from(metadata.values_idx_offsets_len)?, )?; - let slots = vec![Some(values), Some(indices), Some(values_idx_offsets)]; + let slots = Box::new([Some(values), Some(indices), Some(values_idx_offsets)]); let data = RLEData::try_new(metadata.offset as usize)?; Ok(ArrayParts::new(self.clone(), dtype.clone(), len, data).with_slots(slots)) } @@ -219,7 +219,7 @@ impl RLE { length: usize, ) -> VortexResult { let dtype = DType::Primitive(values.dtype().as_ptype(), indices.dtype().nullability()); - let slots = vec![Some(values), Some(indices), Some(values_idx_offsets)]; + let slots = Box::new([Some(values), Some(indices), Some(values_idx_offsets)]); let data = RLEData::try_new(offset)?; Array::try_from_parts(ArrayParts::new(RLE, dtype, length, data).with_slots(slots)) } @@ -236,7 +236,7 @@ impl RLE { length: usize, ) -> RLEArray { let dtype = DType::Primitive(values.dtype().as_ptype(), indices.dtype().nullability()); - let slots = vec![Some(values), Some(indices), Some(values_idx_offsets)]; + let slots = Box::new([Some(values), Some(indices), Some(values_idx_offsets)]); let data = unsafe { RLEData::new_unchecked(offset) }; unsafe { Array::from_parts_unchecked(ArrayParts::new(RLE, dtype, length, data).with_slots(slots)) diff --git a/encodings/fsst/src/array.rs b/encodings/fsst/src/array.rs index 93c62eeebf5..8f4e6ea361a 100644 --- a/encodings/fsst/src/array.rs +++ b/encodings/fsst/src/array.rs @@ -250,11 +250,11 @@ impl VTable for FSST { len, &mut ctx, )?; - let slots = vec![ + let slots = Box::new([ Some(uncompressed_lengths), Some(codes_offsets), validity_to_child(&codes_validity, len), - ]; + ]); let data = FSSTData::try_new(symbols, symbol_lengths, codes_bytes, len)?; return Ok(ArrayParts::new(self.clone(), dtype.clone(), len, data).with_slots(slots)); } @@ -479,8 +479,8 @@ impl FSST { } impl FSSTData { - fn make_slots(codes: &VarBinArray, uncompressed_lengths: &ArrayRef) -> Vec> { - vec![ + fn make_slots(codes: &VarBinArray, uncompressed_lengths: &ArrayRef) -> Box<[Option]> { + Box::new([ Some(uncompressed_lengths.clone()), Some(codes.offsets().clone()), validity_to_child( @@ -489,7 +489,7 @@ impl FSSTData { .vortex_expect("FSST codes validity should be derivable"), codes.len(), ), - ] + ]) } /// Build FSST data from a set of `symbols`, `symbol_lengths`, and compressed codes bytes. diff --git a/encodings/parquet-variant/src/array.rs b/encodings/parquet-variant/src/array.rs index 15c58b894c0..bab4597e6e2 100644 --- a/encodings/parquet-variant/src/array.rs +++ b/encodings/parquet-variant/src/array.rs @@ -95,12 +95,12 @@ impl ParquetVariant { &dtype, len, )?; - let slots = vec![ + let slots = Box::new([ validity_to_child(&validity, len), Some(metadata), value, typed_value, - ]; + ]); let data = ParquetVariantData; Array::try_from_parts(ArrayParts::new(ParquetVariant, dtype, len, data).with_slots(slots)) } diff --git a/encodings/parquet-variant/src/vtable.rs b/encodings/parquet-variant/src/vtable.rs index 84c440712ba..773cdc6bb5b 100644 --- a/encodings/parquet-variant/src/vtable.rs +++ b/encodings/parquet-variant/src/vtable.rs @@ -200,12 +200,12 @@ impl VTable for ParquetVariant { dtype, len, )?; - let slots = vec![ + let slots = Box::new([ validity_to_child(&validity, len), Some(variant_metadata), value, typed_value, - ]; + ]); let data = ParquetVariantData; Ok(ArrayParts::new(self.clone(), dtype.clone(), len, data).with_slots(slots)) } diff --git a/encodings/pco/src/array.rs b/encodings/pco/src/array.rs index 26b86555dec..99ae1e77979 100644 --- a/encodings/pco/src/array.rs +++ b/encodings/pco/src/array.rs @@ -206,7 +206,7 @@ impl VTable for Pco { .sum::(); vortex_ensure!(pages.len() == expected_n_pages); - let slots = vec![validity_to_child(&validity, len)]; + let slots = Box::new([validity_to_child(&validity, len)]); let data = PcoData::new(chunk_metas, pages, dtype.as_ptype(), metadata, len); Ok(ArrayParts::new(self.clone(), dtype.clone(), len, data).with_slots(slots)) } @@ -291,7 +291,7 @@ impl Pco { ) -> VortexResult { let len = data.len(); data.validate(&dtype, len, &validity)?; - let slots = vec![validity_to_child(&validity, data.unsliced_n_rows())]; + let slots = Box::new([validity_to_child(&validity, data.unsliced_n_rows())]); Ok(unsafe { Array::from_parts_unchecked(ArrayParts::new(Pco, dtype, len, data).with_slots(slots)) }) diff --git a/encodings/runend/src/array.rs b/encodings/runend/src/array.rs index 291afb1b954..09f3ce73be0 100644 --- a/encodings/runend/src/array.rs +++ b/encodings/runend/src/array.rs @@ -154,7 +154,7 @@ impl VTable for RunEnd { let values = children.get(1, dtype, runs)?; let offset = usize::try_from(metadata.offset).vortex_expect("Offset must be a valid usize"); - let slots = vec![Some(ends), Some(values)]; + let slots = Box::new([Some(ends), Some(values)]); let data = RunEndData::new(offset); Ok(ArrayParts::new(self.clone(), dtype.clone(), len, data).with_slots(slots)) } @@ -258,7 +258,7 @@ impl RunEnd { length: usize, ) -> RunEndArray { let dtype = values.dtype().clone(); - let slots = vec![Some(ends), Some(values)]; + let slots = Box::new([Some(ends), Some(values)]); let data = unsafe { RunEndData::new_unchecked(offset) }; unsafe { Array::from_parts_unchecked( @@ -276,7 +276,7 @@ impl RunEnd { let len = RunEndData::logical_len_from_ends(&ends, ctx)?; RunEndData::validate_parts(&ends, &values, 0, len, ctx)?; let dtype = values.dtype().clone(); - let slots = vec![Some(ends), Some(values)]; + let slots = Box::new([Some(ends), Some(values)]); let data = RunEndData::new(0); Array::try_from_parts(ArrayParts::new(RunEnd, dtype, len, data).with_slots(slots)) } @@ -291,7 +291,7 @@ impl RunEnd { ) -> VortexResult { RunEndData::validate_parts(&ends, &values, offset, length, ctx)?; let dtype = values.dtype().clone(); - let slots = vec![Some(ends), Some(values)]; + let slots = Box::new([Some(ends), Some(values)]); let data = RunEndData::new(offset); Array::try_from_parts(ArrayParts::new(RunEnd, dtype, length, data).with_slots(slots)) } @@ -308,7 +308,7 @@ impl RunEnd { let ends = ends.into_array(); let len = array.len(); let dtype = values.dtype().clone(); - let slots = vec![Some(ends), Some(values)]; + let slots = Box::new([Some(ends), Some(values)]); let data = unsafe { RunEndData::new_unchecked(0) }; Array::try_from_parts(ArrayParts::new(RunEnd, dtype, len, data).with_slots(slots)) } else { diff --git a/encodings/sparse/src/lib.rs b/encodings/sparse/src/lib.rs index 92d77ecd8a8..93a457a3cdf 100644 --- a/encodings/sparse/src/lib.rs +++ b/encodings/sparse/src/lib.rs @@ -324,12 +324,12 @@ impl SparseData { Ok(()) } - fn make_slots(patches: &Patches) -> Vec> { - vec![ + fn make_slots(patches: &Patches) -> Box<[Option]> { + Box::new([ Some(patches.indices().clone()), Some(patches.values().clone()), patches.chunk_offsets().clone(), - ] + ]) } /// Build a new SparseArray from an existing set of patches. diff --git a/encodings/zigzag/src/array.rs b/encodings/zigzag/src/array.rs index 10dee3c922d..512430a3a79 100644 --- a/encodings/zigzag/src/array.rs +++ b/encodings/zigzag/src/array.rs @@ -120,7 +120,7 @@ impl VTable for ZigZag { let encoded_type = DType::Primitive(ptype.to_unsigned(), dtype.nullability()); let encoded = children.get(0, &encoded_type, len)?; - let slots = vec![Some(encoded.clone())]; + let slots = Box::new([Some(encoded.clone())]); let data = ZigZagData::try_new(encoded.dtype())?; Ok(ArrayParts::new(self.clone(), dtype.clone(), len, data).with_slots(slots)) } @@ -201,7 +201,7 @@ impl ZigZag { pub fn try_new(encoded: ArrayRef) -> VortexResult { let dtype = ZigZagData::dtype_from_encoded_dtype(encoded.dtype())?; let len = encoded.len(); - let slots = vec![Some(encoded.clone())]; + let slots = Box::new([Some(encoded.clone())]); let data = ZigZagData::try_new(encoded.dtype())?; Ok(unsafe { Array::from_parts_unchecked(ArrayParts::new(ZigZag, dtype, len, data).with_slots(slots)) diff --git a/encodings/zstd/src/array.rs b/encodings/zstd/src/array.rs index 95206357e0a..816806ab435 100644 --- a/encodings/zstd/src/array.rs +++ b/encodings/zstd/src/array.rs @@ -220,7 +220,7 @@ impl VTable for Zstd { ) }; - let slots = vec![validity_to_child(&validity, len)]; + let slots = Box::new([validity_to_child(&validity, len)]); let data = ZstdData::new(dictionary_buffer, compressed_buffers, metadata, len); Ok(ArrayParts::new(self.clone(), dtype.clone(), len, data).with_slots(slots)) } @@ -257,7 +257,7 @@ impl Zstd { pub fn try_new(dtype: DType, data: ZstdData, validity: Validity) -> VortexResult { let len = data.len(); data.validate(&dtype, len, &validity)?; - let slots = vec![validity_to_child(&validity, data.unsliced_n_rows())]; + let slots = Box::new([validity_to_child(&validity, data.unsliced_n_rows())]); Ok(unsafe { Array::from_parts_unchecked(ArrayParts::new(Zstd, dtype, len, data).with_slots(slots)) }) diff --git a/encodings/zstd/src/zstd_buffers.rs b/encodings/zstd/src/zstd_buffers.rs index fb387f099b9..0f877ce281a 100644 --- a/encodings/zstd/src/zstd_buffers.rs +++ b/encodings/zstd/src/zstd_buffers.rs @@ -425,9 +425,9 @@ impl VTable for ZstdBuffers { let metadata = ZstdBuffersMetadata::decode(metadata)?; let compressed_buffers: Vec = buffers.to_vec(); - let slots: Vec> = (0..children.len()) + let slots: Box<[Option]> = (0..children.len()) .map(|i| children.get(i, dtype, len).map(Some)) - .collect::>>()?; + .collect::>>()?; let data = ZstdBuffersData { inner_encoding_id: array_id_from_string(&metadata.inner_encoding_id), diff --git a/vortex-array-macros/src/lib.rs b/vortex-array-macros/src/lib.rs index 7828a4ec5a6..92abe12bcce 100644 --- a/vortex-array-macros/src/lib.rs +++ b/vortex-array-macros/src/lib.rs @@ -51,11 +51,11 @@ use syn::spanned::Spanned; /// pub const COUNT: usize = 4; /// pub const NAMES: [&'static str; 4] = ["inner", "lane_offsets", "patch_indices", "patch_values"]; /// -/// /// Take ownership of slots from a `Vec>`. -/// pub fn from_slots(slots: Vec>) -> Self { ... } +/// /// Take ownership of slots from a `Box<[Option]>`. +/// pub fn from_slots(slots: Box<[Option]>) -> Self { ... } /// /// /// Convert back into storage order. -/// pub fn into_slots(self) -> Vec> { ... } +/// pub fn into_slots(self) -> Box<[Option]> { ... } /// } /// /// // --- Borrowed view with &ArrayRef / Option<&ArrayRef> fields --- @@ -92,7 +92,7 @@ use syn::spanned::Spanned; /// The ext trait accessor returns `Option<&ArrayRef>`. The view field is /// `Option<&'a ArrayRef>`. /// -/// The underlying storage is always `Vec>` — the field type only +/// The underlying storage is always `Box<[Option]>` — the field type only /// controls whether the macro inserts a `.vortex_expect()` unwrap or not. #[proc_macro_attribute] pub fn array_slots(attr: TokenStream, item: TokenStream) -> TokenStream { @@ -166,15 +166,16 @@ fn expand_array_slots( pub const NAMES: [&'static str; #slot_count] = [#(#slot_names),*]; #[doc = "Convert owned slot storage into an owned slot struct."] - pub fn from_slots(mut slots: Vec>) -> Self { + #[allow(clippy::boxed_local)] + pub fn from_slots(mut slots: ::std::boxed::Box<[Option<::vortex_array::ArrayRef>]>) -> Self { Self { #(#owned_from_slots,)* } } #[doc = "Convert this slot struct into storage order."] - pub fn into_slots(self) -> Vec> { - vec![#(#into_slots),*] + pub fn into_slots(self) -> ::std::boxed::Box<[Option<::vortex_array::ArrayRef>]> { + ::std::boxed::Box::new([#(#into_slots),*]) } } diff --git a/vortex-array/public-api.lock b/vortex-array/public-api.lock index 87eca1bb0c2..27831e32d24 100644 --- a/vortex-array/public-api.lock +++ b/vortex-array/public-api.lock @@ -2360,9 +2360,9 @@ pub const vortex_array::arrays::dict::DictSlots::NAMES: [&'static str; 2] pub const vortex_array::arrays::dict::DictSlots::VALUES: usize -pub fn vortex_array::arrays::dict::DictSlots::from_slots(alloc::vec::Vec>) -> Self +pub fn vortex_array::arrays::dict::DictSlots::from_slots(alloc::boxed::Box<[core::option::Option]>) -> Self -pub fn vortex_array::arrays::dict::DictSlots::into_slots(self) -> alloc::vec::Vec> +pub fn vortex_array::arrays::dict::DictSlots::into_slots(self) -> alloc::boxed::Box<[core::option::Option]> pub struct vortex_array::arrays::dict::DictSlotsView<'a> @@ -3444,9 +3444,9 @@ pub const vortex_array::arrays::masked::MaskedSlots::NAMES: [&'static str; 2] pub const vortex_array::arrays::masked::MaskedSlots::VALIDITY: usize -pub fn vortex_array::arrays::masked::MaskedSlots::from_slots(alloc::vec::Vec>) -> Self +pub fn vortex_array::arrays::masked::MaskedSlots::from_slots(alloc::boxed::Box<[core::option::Option]>) -> Self -pub fn vortex_array::arrays::masked::MaskedSlots::into_slots(self) -> alloc::vec::Vec> +pub fn vortex_array::arrays::masked::MaskedSlots::into_slots(self) -> alloc::boxed::Box<[core::option::Option]> pub trait vortex_array::arrays::masked::MaskedArrayExt: vortex_array::TypedArrayRef + vortex_array::arrays::masked::MaskedArraySlotsExt @@ -3708,9 +3708,9 @@ pub const vortex_array::arrays::patched::PatchedSlots::PATCH_INDICES: usize pub const vortex_array::arrays::patched::PatchedSlots::PATCH_VALUES: usize -pub fn vortex_array::arrays::patched::PatchedSlots::from_slots(alloc::vec::Vec>) -> Self +pub fn vortex_array::arrays::patched::PatchedSlots::from_slots(alloc::boxed::Box<[core::option::Option]>) -> Self -pub fn vortex_array::arrays::patched::PatchedSlots::into_slots(self) -> alloc::vec::Vec> +pub fn vortex_array::arrays::patched::PatchedSlots::into_slots(self) -> alloc::boxed::Box<[core::option::Option]> pub struct vortex_array::arrays::patched::PatchedSlotsView<'a> @@ -22446,7 +22446,7 @@ pub vortex_array::ArrayParts::dtype: vortex_array::dtype::DType pub vortex_array::ArrayParts::len: usize -pub vortex_array::ArrayParts::slots: alloc::vec::Vec> +pub vortex_array::ArrayParts::slots: alloc::boxed::Box<[core::option::Option]> pub vortex_array::ArrayParts::vtable: V @@ -22454,7 +22454,7 @@ impl vortex_array::ArrayParts pub fn vortex_array::ArrayParts::new(V, vortex_array::dtype::DType, usize, ::TypedArrayData) -> Self -pub fn vortex_array::ArrayParts::with_slots(self, alloc::vec::Vec>) -> Self +pub fn vortex_array::ArrayParts::with_slots(self, alloc::boxed::Box<[core::option::Option]>) -> Self pub struct vortex_array::ArrayRef(_) @@ -22560,7 +22560,7 @@ pub fn vortex_array::ArrayRef::validity(&self) -> vortex_error::VortexResult vortex_error::VortexResult -pub fn vortex_array::ArrayRef::with_slots(self, alloc::vec::Vec>) -> vortex_error::VortexResult +pub fn vortex_array::ArrayRef::with_slots(self, alloc::boxed::Box<[core::option::Option]>) -> vortex_error::VortexResult impl vortex_array::ArrayRef diff --git a/vortex-array/src/array/erased.rs b/vortex-array/src/array/erased.rs index cfc3e911c48..ac3365e5a57 100644 --- a/vortex-array/src/array/erased.rs +++ b/vortex-array/src/array/erased.rs @@ -462,7 +462,7 @@ impl ArrayRef { /// /// Takes ownership to allow in-place mutation when the refcount is 1. pub fn with_slot(self, slot_idx: usize, replacement: ArrayRef) -> VortexResult { - let slots = self.slots().to_vec(); + let mut slots: Box<[Option]> = self.slots().into(); let nslots = slots.len(); vortex_ensure!( slot_idx < nslots, @@ -487,7 +487,6 @@ impl ArrayRef { existing.len(), replacement.len() ); - let mut slots = slots; slots[slot_idx] = Some(replacement); self.with_slots(slots) } @@ -521,7 +520,7 @@ impl ArrayRef { .vortex_expect("take_slot_unchecked cannot take an absent slot") .clone(); - let mut new_slots = self.slots().to_vec(); + let mut new_slots: Box<[Option]> = self.slots().into(); new_slots[slot_idx] = None; // SAFETY: ensured by the caller — the None slot is either put back or driven to completion @@ -547,7 +546,7 @@ impl ArrayRef { return Ok(self); } - let mut slots = self.slots().to_vec(); + let mut slots: Box<[Option]> = self.slots().into(); slots[slot_idx] = Some(replacement); self.0.data.with_slots(&self, slots) } @@ -556,7 +555,7 @@ impl ArrayRef { /// /// This is only valid for physical rewrites: slot count, presence, logical `DType`, and /// logical `len` must remain unchanged. - pub fn with_slots(self, slots: Vec>) -> VortexResult { + pub fn with_slots(self, slots: Box<[Option]>) -> VortexResult { let old_slots = self.slots(); vortex_ensure!( old_slots.len() == slots.len(), diff --git a/vortex-array/src/array/mod.rs b/vortex-array/src/array/mod.rs index 4dc8607b1bc..e4f9df5bec3 100644 --- a/vortex-array/src/array/mod.rs +++ b/vortex-array/src/array/mod.rs @@ -118,7 +118,8 @@ pub(crate) trait DynArrayData: 'static + private::Sealed + Send + Sync + Debug { fn dyn_array_eq(&self, other: &ArrayRef, precision: crate::Precision) -> bool; /// Returns a new array with the given slots. - fn with_slots(&self, this: &ArrayRef, slots: Vec>) -> VortexResult; + fn with_slots(&self, this: &ArrayRef, slots: Box<[Option]>) + -> VortexResult; /// Returns a new array with the given slots, bypassing encoding-level validation. /// @@ -135,7 +136,7 @@ pub(crate) trait DynArrayData: 'static + private::Sealed + Send + Sync + Debug { unsafe fn with_slots_unchecked( &self, this: &ArrayRef, - slots: Vec>, + slots: Box<[Option]>, ) -> ArrayRef; /// Attempt to reduce the array to a simpler representation. @@ -353,7 +354,11 @@ impl DynArrayData for ArrayData { .is_some_and(|other_inner| self.data.array_eq(&other_inner.data, precision)) } - fn with_slots(&self, this: &ArrayRef, slots: Vec>) -> VortexResult { + fn with_slots( + &self, + this: &ArrayRef, + slots: Box<[Option]>, + ) -> VortexResult { let stats = this.statistics().to_owned(); Ok(Array::::try_from_parts( ArrayParts::new( @@ -371,7 +376,7 @@ impl DynArrayData for ArrayData { unsafe fn with_slots_unchecked( &self, this: &ArrayRef, - slots: Vec>, + slots: Box<[Option]>, ) -> ArrayRef { // SAFETY: we intentionally skip `V::validate` here. Caller guarantees that the resulting // array is either repaired or not externally observed. diff --git a/vortex-array/src/array/typed.rs b/vortex-array/src/array/typed.rs index 15dbb18a5f6..44aa60641fb 100644 --- a/vortex-array/src/array/typed.rs +++ b/vortex-array/src/array/typed.rs @@ -40,7 +40,7 @@ pub(crate) struct ArrayInner { pub(crate) len: usize, pub(crate) encoding_id: ArrayId, pub(crate) dtype: DType, - pub(crate) slots: Vec>, + pub(crate) slots: Box<[Option]>, pub(crate) stats: ArrayStats, pub(crate) data: D, // must be last for unsized coercion } @@ -51,7 +51,7 @@ pub struct ArrayParts { pub dtype: DType, pub len: usize, pub data: V::TypedArrayData, - pub slots: Vec>, + pub slots: Box<[Option]>, } impl ArrayParts { @@ -61,11 +61,11 @@ impl ArrayParts { dtype, len, data, - slots: Vec::new(), + slots: Box::default(), } } - pub fn with_slots(mut self, slots: Vec>) -> Self { + pub fn with_slots(mut self, slots: Box<[Option]>) -> Self { self.slots = slots; self } @@ -125,7 +125,7 @@ impl ArrayInner> { len: usize, dtype: DType, data: V::TypedArrayData, - slots: Vec>, + slots: Box<[Option]>, stats: ArrayStats, ) -> Self { ArrayInner { diff --git a/vortex-array/src/arrays/bool/array.rs b/vortex-array/src/arrays/bool/array.rs index 0cfc55869b1..138339f0aaf 100644 --- a/vortex-array/src/arrays/bool/array.rs +++ b/vortex-array/src/arrays/bool/array.rs @@ -144,8 +144,8 @@ impl BoolData { } } - pub(crate) fn make_slots(validity: &Validity, len: usize) -> Vec> { - vec![validity_to_child(validity, len)] + pub(crate) fn make_slots(validity: &Validity, len: usize) -> Box<[Option]> { + Box::new([validity_to_child(validity, len)]) } } diff --git a/vortex-array/src/arrays/chunked/array.rs b/vortex-array/src/arrays/chunked/array.rs index 6ec93d3aefb..abf0ef201d0 100644 --- a/vortex-array/src/arrays/chunked/array.rs +++ b/vortex-array/src/arrays/chunked/array.rs @@ -137,7 +137,7 @@ impl ChunkedData { pub(super) fn make_slots( chunk_offsets: &[usize], chunks: &[ArrayRef], - ) -> Vec> { + ) -> Box<[Option]> { let mut chunk_offsets_buf = BufferMut::::with_capacity(chunk_offsets.len()); for &offset in chunk_offsets { let offset = u64::try_from(offset) @@ -150,7 +150,7 @@ impl ChunkedData { PrimitiveArray::new(chunk_offsets_buf.freeze(), Validity::NonNullable).into_array(), )); slots.extend(chunks.iter().map(|c| Some(c.clone()))); - slots + slots.into_boxed_slice() } /// Validates the components that would be used to create a `ChunkedArray`. @@ -182,7 +182,7 @@ impl Array { unsafe { Array::from_parts_unchecked( ArrayParts::new(Chunked, self.dtype().clone(), self.len(), data) - .with_slots(self.slots().to_vec()), + .with_slots(self.slots().into()), ) } .with_stats_set(stats) diff --git a/vortex-array/src/arrays/chunked/vtable/mod.rs b/vortex-array/src/arrays/chunked/vtable/mod.rs index 6acad15e2a6..7614afb5c26 100644 --- a/vortex-array/src/arrays/chunked/vtable/mod.rs +++ b/vortex-array/src/arrays/chunked/vtable/mod.rs @@ -216,7 +216,7 @@ impl VTable for Chunked { len, ChunkedData::new(chunk_offsets_usize), ) - .with_slots(slots)) + .with_slots(slots.into_boxed_slice())) } fn append_to_builder( diff --git a/vortex-array/src/arrays/decimal/array.rs b/vortex-array/src/arrays/decimal/array.rs index eb461337752..baf005d87b7 100644 --- a/vortex-array/src/arrays/decimal/array.rs +++ b/vortex-array/src/arrays/decimal/array.rs @@ -175,8 +175,8 @@ impl> DecimalArrayExt for T {} impl DecimalData { /// Build the slots vector for this array. - pub(super) fn make_slots(validity: &Validity, len: usize) -> Vec> { - vec![validity_to_child(validity, len)] + pub(super) fn make_slots(validity: &Validity, len: usize) -> Box<[Option]> { + Box::new([validity_to_child(validity, len)]) } /// Creates a new [`DecimalArray`] using a host-native buffer. diff --git a/vortex-array/src/arrays/dict/array.rs b/vortex-array/src/arrays/dict/array.rs index eafbc9f6642..ce130b81547 100644 --- a/vortex-array/src/arrays/dict/array.rs +++ b/vortex-array/src/arrays/dict/array.rs @@ -237,7 +237,8 @@ impl Array { let len = codes.len(); let data = DictData::try_new(codes.dtype())?; Array::try_from_parts( - ArrayParts::new(Dict, dtype, len, data).with_slots(vec![Some(codes), Some(values)]), + ArrayParts::new(Dict, dtype, len, data) + .with_slots(Box::new([Some(codes), Some(values)])), ) } @@ -254,7 +255,8 @@ impl Array { let data = unsafe { DictData::new_unchecked() }; unsafe { Array::from_parts_unchecked( - ArrayParts::new(Dict, dtype, len, data).with_slots(vec![Some(codes), Some(values)]), + ArrayParts::new(Dict, dtype, len, data) + .with_slots(Box::new([Some(codes), Some(values)])), ) } } @@ -267,7 +269,7 @@ impl Array { pub unsafe fn set_all_values_referenced(self, all_values_referenced: bool) -> Self { let dtype = self.dtype().clone(); let len = self.len(); - let slots = self.slots().to_vec(); + let slots: Box<[Option]> = self.slots().into(); let data = unsafe { self.into_data() .set_all_values_referenced(all_values_referenced) diff --git a/vortex-array/src/arrays/dict/vtable/mod.rs b/vortex-array/src/arrays/dict/vtable/mod.rs index 4893be5c7ed..006154594fa 100644 --- a/vortex-array/src/arrays/dict/vtable/mod.rs +++ b/vortex-array/src/arrays/dict/vtable/mod.rs @@ -161,7 +161,7 @@ impl VTable for Dict { Ok(ArrayParts::new(self.clone(), dtype.clone(), len, unsafe { DictData::new_unchecked().set_all_values_referenced(all_values_referenced) }) - .with_slots(vec![Some(codes), Some(values)])) + .with_slots(Box::new([Some(codes), Some(values)]))) } fn slot_name(_array: ArrayView<'_, Self>, idx: usize) -> String { diff --git a/vortex-array/src/arrays/extension/array.rs b/vortex-array/src/arrays/extension/array.rs index b42f7b63603..e751cf9daf7 100644 --- a/vortex-array/src/arrays/extension/array.rs +++ b/vortex-array/src/arrays/extension/array.rs @@ -59,7 +59,7 @@ impl Array { let len = storage_array.len(); let parts = ArrayParts::new(Extension, dtype, len, EmptyArrayData) - .with_slots(vec![Some(storage_array)]); + .with_slots(Box::new([Some(storage_array)])); Ok(unsafe { Array::from_parts_unchecked(parts) }) } diff --git a/vortex-array/src/arrays/extension/vtable/mod.rs b/vortex-array/src/arrays/extension/vtable/mod.rs index 1a25a1a9ef1..c7710e01544 100644 --- a/vortex-array/src/arrays/extension/vtable/mod.rs +++ b/vortex-array/src/arrays/extension/vtable/mod.rs @@ -163,7 +163,7 @@ impl VTable for Extension { let storage = children.get(0, ext_dtype.storage_dtype(), len)?; Ok( ArrayParts::new(self.clone(), dtype.clone(), len, EmptyArrayData) - .with_slots(vec![Some(storage)]), + .with_slots(Box::new([Some(storage)])), ) } diff --git a/vortex-array/src/arrays/filter/array.rs b/vortex-array/src/arrays/filter/array.rs index 8367c8009e9..69102ccdbe0 100644 --- a/vortex-array/src/arrays/filter/array.rs +++ b/vortex-array/src/arrays/filter/array.rs @@ -95,7 +95,7 @@ impl Array { let data = FilterData::new(mask); unsafe { Array::from_parts_unchecked( - ArrayParts::new(Filter, dtype, len, data).with_slots(vec![Some(array)]), + ArrayParts::new(Filter, dtype, len, data).with_slots(Box::new([Some(array)])), ) } } @@ -107,7 +107,7 @@ impl Array { let data = FilterData::try_new(array.len(), mask)?; Ok(unsafe { Array::from_parts_unchecked( - ArrayParts::new(Filter, dtype, len, data).with_slots(vec![Some(array)]), + ArrayParts::new(Filter, dtype, len, data).with_slots(Box::new([Some(array)])), ) }) } diff --git a/vortex-array/src/arrays/fixed_size_list/array.rs b/vortex-array/src/arrays/fixed_size_list/array.rs index e885ecce0f4..4353c9b68a6 100644 --- a/vortex-array/src/arrays/fixed_size_list/array.rs +++ b/vortex-array/src/arrays/fixed_size_list/array.rs @@ -111,8 +111,8 @@ impl FixedSizeListData { elements: &ArrayRef, validity: &Validity, len: usize, - ) -> Vec> { - vec![Some(elements.clone()), validity_to_child(validity, len)] + ) -> Box<[Option]> { + Box::new([Some(elements.clone()), validity_to_child(validity, len)]) } /// Creates a new `FixedSizeListArray`. diff --git a/vortex-array/src/arrays/list/array.rs b/vortex-array/src/arrays/list/array.rs index 140b112ff39..22768b68ba1 100644 --- a/vortex-array/src/arrays/list/array.rs +++ b/vortex-array/src/arrays/list/array.rs @@ -117,12 +117,12 @@ impl ListData { offsets: &ArrayRef, validity: &Validity, len: usize, - ) -> Vec> { - vec![ + ) -> Box<[Option]> { + Box::new([ Some(elements.clone()), Some(offsets.clone()), validity_to_child(validity, len), - ] + ]) } /// Creates a new `ListArray`. diff --git a/vortex-array/src/arrays/listview/array.rs b/vortex-array/src/arrays/listview/array.rs index e22809cf4c7..9e15f0ea93a 100644 --- a/vortex-array/src/arrays/listview/array.rs +++ b/vortex-array/src/arrays/listview/array.rs @@ -154,13 +154,13 @@ impl ListViewData { sizes: &ArrayRef, validity: &Validity, len: usize, - ) -> Vec> { - vec![ + ) -> Box<[Option]> { + Box::new([ Some(elements.clone()), Some(offsets.clone()), Some(sizes.clone()), validity_to_child(validity, len), - ] + ]) } /// Creates a new `ListViewArray`. @@ -470,7 +470,7 @@ impl Array { } let dtype = self.dtype().clone(); let len = self.len(); - let slots = self.slots().to_vec(); + let slots: Box<[Option]> = self.slots().into(); let data = unsafe { self.into_data().with_zero_copy_to_list(is_zctl) }; unsafe { Array::from_parts_unchecked( diff --git a/vortex-array/src/arrays/masked/array.rs b/vortex-array/src/arrays/masked/array.rs index ce828020111..9ea089ec5b6 100644 --- a/vortex-array/src/arrays/masked/array.rs +++ b/vortex-array/src/arrays/masked/array.rs @@ -86,7 +86,7 @@ impl Array { Ok(unsafe { Array::from_parts_unchecked( ArrayParts::new(Masked, dtype, len, data) - .with_slots(vec![Some(child), validity_slot]), + .with_slots(Box::new([Some(child), validity_slot])), ) }) } diff --git a/vortex-array/src/arrays/masked/vtable/mod.rs b/vortex-array/src/arrays/masked/vtable/mod.rs index f244c322823..3e8a6ef19b6 100644 --- a/vortex-array/src/arrays/masked/vtable/mod.rs +++ b/vortex-array/src/arrays/masked/vtable/mod.rs @@ -154,7 +154,7 @@ impl VTable for Masked { )?; Ok( crate::array::ArrayParts::new(self.clone(), dtype.clone(), len, data) - .with_slots(vec![Some(child), validity_slot]), + .with_slots(Box::new([Some(child), validity_slot])), ) } diff --git a/vortex-array/src/arrays/patched/array.rs b/vortex-array/src/arrays/patched/array.rs index 910409cb919..8530847fd76 100644 --- a/vortex-array/src/arrays/patched/array.rs +++ b/vortex-array/src/arrays/patched/array.rs @@ -237,7 +237,7 @@ impl Patched { pub(crate) unsafe fn new_unchecked( dtype: DType, len: usize, - slots: Vec>, + slots: Box<[Option]>, n_lanes: usize, offset: usize, ) -> Array { @@ -382,7 +382,8 @@ mod tests { let required = PrimitiveArray::new(buffer![1u8, 2, 3], Validity::NonNullable).into_array(); let optional = PrimitiveArray::new(buffer![4u8, 5, 6], Validity::NonNullable).into_array(); - let slot_vec = vec![Some(required.clone()), Some(optional.clone())]; + let slot_vec: Box<[Option]> = + Box::new([Some(required.clone()), Some(optional.clone())]); let view = OptionalPatchedSlotsView::from_slots(&slot_vec); assert_eq!(view.required.len(), 3); assert_eq!(view.maybe.expect("optional slot").len(), 3); @@ -391,12 +392,12 @@ mod tests { assert_eq!(cloned.required.len(), required.len()); assert_eq!(cloned.maybe.expect("optional clone").len(), optional.len()); - let rebuilt = PatchedSlots::from_slots(vec![ + let rebuilt = PatchedSlots::from_slots(Box::new([ Some(required.clone()), Some(optional.clone()), Some(required.clone()), Some(optional.clone()), - ]); + ])); assert_eq!(rebuilt.inner.len(), required.len()); assert_eq!(rebuilt.patch_values.len(), optional.len()); } diff --git a/vortex-array/src/arrays/patched/vtable/mod.rs b/vortex-array/src/arrays/patched/vtable/mod.rs index 531b89cd22e..f9c1968d94e 100644 --- a/vortex-array/src/arrays/patched/vtable/mod.rs +++ b/vortex-array/src/arrays/patched/vtable/mod.rs @@ -625,7 +625,7 @@ mod tests { let array = make_patched_array(vec![0u16; 1024], &[1, 2, 3], &[10, 20, 30])?; // Get original children via accessor methods - let slots = PatchedSlots::from_slots(array.as_array().slots().to_vec()); + let slots = PatchedSlots::from_slots(array.as_array().slots().into()); let view = PatchedSlotsView::from_slots(array.as_array().slots()); assert_eq!(view.inner.len(), array.inner().len()); diff --git a/vortex-array/src/arrays/primitive/array/mod.rs b/vortex-array/src/arrays/primitive/array/mod.rs index 254c4b0baee..75477e64950 100644 --- a/vortex-array/src/arrays/primitive/array/mod.rs +++ b/vortex-array/src/arrays/primitive/array/mod.rs @@ -246,8 +246,8 @@ impl> PrimitiveArrayExt for T {} // TODO(connor): There are a lot of places where we could be using `new_unchecked` in the codebase. impl PrimitiveData { /// Build the slots vector for this array. - pub(super) fn make_slots(validity: &Validity, len: usize) -> Vec> { - vec![validity_to_child(validity, len)] + pub(super) fn make_slots(validity: &Validity, len: usize) -> Box<[Option]> { + Box::new([validity_to_child(validity, len)]) } /// Create a new array from a buffer handle. diff --git a/vortex-array/src/arrays/shared/array.rs b/vortex-array/src/arrays/shared/array.rs index 5e90aece98e..bf0c3ed9ce3 100644 --- a/vortex-array/src/arrays/shared/array.rs +++ b/vortex-array/src/arrays/shared/array.rs @@ -115,7 +115,7 @@ impl Array { unsafe { Array::from_parts_unchecked( ArrayParts::new(Shared, dtype, len, SharedData::new()) - .with_slots(vec![Some(source)]), + .with_slots(Box::new([Some(source)])), ) } } diff --git a/vortex-array/src/arrays/slice/array.rs b/vortex-array/src/arrays/slice/array.rs index b1121e2604a..c2ec241068b 100644 --- a/vortex-array/src/arrays/slice/array.rs +++ b/vortex-array/src/arrays/slice/array.rs @@ -88,7 +88,7 @@ impl Array { let data = SliceData::try_new(child.len(), range)?; Ok(unsafe { Array::from_parts_unchecked( - ArrayParts::new(Slice, dtype, len, data).with_slots(vec![Some(child)]), + ArrayParts::new(Slice, dtype, len, data).with_slots(Box::new([Some(child)])), ) }) } @@ -100,7 +100,7 @@ impl Array { let data = SliceData::new(range); unsafe { Array::from_parts_unchecked( - ArrayParts::new(Slice, dtype, len, data).with_slots(vec![Some(child)]), + ArrayParts::new(Slice, dtype, len, data).with_slots(Box::new([Some(child)])), ) } } diff --git a/vortex-array/src/arrays/struct_/array.rs b/vortex-array/src/arrays/struct_/array.rs index 02df75aa659..7b55969a9e5 100644 --- a/vortex-array/src/arrays/struct_/array.rs +++ b/vortex-array/src/arrays/struct_/array.rs @@ -165,7 +165,7 @@ pub(super) fn make_struct_slots( fields: &[ArrayRef], validity: &Validity, length: usize, -) -> Vec> { +) -> Box<[Option]> { once(validity_to_child(validity, length)) .chain(fields.iter().cloned().map(Some)) .collect() @@ -415,7 +415,7 @@ impl Array { .as_ref() .vortex_expect("StructArray field slot") .clone(); - let new_slots: Vec> = self + let new_slots: Box<[Option]> = self .slots() .iter() .enumerate() diff --git a/vortex-array/src/arrays/varbin/array.rs b/vortex-array/src/arrays/varbin/array.rs index 805eb68aaa2..34de3b6f986 100644 --- a/vortex-array/src/arrays/varbin/array.rs +++ b/vortex-array/src/arrays/varbin/array.rs @@ -85,8 +85,8 @@ impl VarBinData { offsets: ArrayRef, validity: &Validity, len: usize, - ) -> Vec> { - vec![Some(offsets), validity_to_child(validity, len)] + ) -> Box<[Option]> { + Box::new([Some(offsets), validity_to_child(validity, len)]) } /// Constructs a new `VarBinArray`. diff --git a/vortex-array/src/arrays/varbinview/array.rs b/vortex-array/src/arrays/varbinview/array.rs index 06256bfa77c..e11dd2138c0 100644 --- a/vortex-array/src/arrays/varbinview/array.rs +++ b/vortex-array/src/arrays/varbinview/array.rs @@ -124,8 +124,8 @@ impl VarBinViewData { } /// Build the slots vector for this array. - pub(super) fn make_slots(validity: &Validity, len: usize) -> Vec> { - vec![validity_to_child(validity, len)] + pub(super) fn make_slots(validity: &Validity, len: usize) -> Box<[Option]> { + Box::new([validity_to_child(validity, len)]) } /// Creates a new `VarBinViewArray`. @@ -554,7 +554,7 @@ impl Array { fn from_prevalidated_data( dtype: DType, data: VarBinViewData, - slots: Vec>, + slots: Box<[Option]>, ) -> Self { let len = data.len(); unsafe { diff --git a/vortex-array/src/arrays/variant/mod.rs b/vortex-array/src/arrays/variant/mod.rs index 06b8a8437a8..ad84c6e747a 100644 --- a/vortex-array/src/arrays/variant/mod.rs +++ b/vortex-array/src/arrays/variant/mod.rs @@ -34,7 +34,8 @@ impl Array { let stats = child.statistics().to_owned(); unsafe { Array::from_parts_unchecked( - ArrayParts::new(Variant, dtype, len, EmptyArrayData).with_slots(vec![Some(child)]), + ArrayParts::new(Variant, dtype, len, EmptyArrayData) + .with_slots(Box::new([Some(child)])), ) } .with_stats_set(stats) diff --git a/vortex-array/src/arrays/variant/vtable/mod.rs b/vortex-array/src/arrays/variant/vtable/mod.rs index 666dd0c42ab..409e4ebcfcf 100644 --- a/vortex-array/src/arrays/variant/vtable/mod.rs +++ b/vortex-array/src/arrays/variant/vtable/mod.rs @@ -119,7 +119,7 @@ impl VTable for Variant { let child = children.get(0, dtype, len)?; Ok( crate::array::ArrayParts::new(self.clone(), dtype.clone(), len, EmptyArrayData) - .with_slots(vec![Some(child)]), + .with_slots(Box::new([Some(child)])), ) } diff --git a/vortex-array/src/normalize.rs b/vortex-array/src/normalize.rs index 2833bf467d6..e251947d1e2 100644 --- a/vortex-array/src/normalize.rs +++ b/vortex-array/src/normalize.rs @@ -83,7 +83,7 @@ impl ArrayRef { } if any_slot_changed { - normalized = normalized.with_slots(normalized_slots)?; + normalized = normalized.with_slots(normalized_slots.into_boxed_slice())?; } Ok(normalized) diff --git a/vortex-array/src/optimizer/mod.rs b/vortex-array/src/optimizer/mod.rs index f991dbb2c1d..adc2614d837 100644 --- a/vortex-array/src/optimizer/mod.rs +++ b/vortex-array/src/optimizer/mod.rs @@ -153,7 +153,7 @@ fn try_optimize_recursive( } if any_slot_optimized { - current_array = current_array.with_slots(new_slots)?; + current_array = current_array.with_slots(new_slots.into_boxed_slice())?; any_optimizations = true; } From 99b4a4a2f5d1e9d806a289827ca5a143f58770d7 Mon Sep 17 00:00:00 2001 From: Robert Kruszewski Date: Thu, 7 May 2026 10:57:04 +0100 Subject: [PATCH 2/2] test