From 6d1740ee9d915939c061476b4de72556a838c10a Mon Sep 17 00:00:00 2001 From: Connor Tsui Date: Fri, 24 Oct 2025 12:26:45 -0400 Subject: [PATCH] add more constructors Signed-off-by: Connor Tsui --- vortex-vector/src/bool/vector.rs | 30 ++++++++++++++- vortex-vector/src/bool/vector_mut.rs | 43 ++++++++++++++++++--- vortex-vector/src/primitive/generic.rs | 44 +++++++++++++++++++++ vortex-vector/src/primitive/generic_mut.rs | 45 ++++++++++++++++++++++ 4 files changed, 154 insertions(+), 8 deletions(-) diff --git a/vortex-vector/src/bool/vector.rs b/vortex-vector/src/bool/vector.rs index 15f5e1f9d36..a6e3e925aa9 100644 --- a/vortex-vector/src/bool/vector.rs +++ b/vortex-vector/src/bool/vector.rs @@ -4,6 +4,7 @@ //! Definition and implementation of [`BoolVector`]. use vortex_buffer::BitBuffer; +use vortex_error::{VortexExpect, VortexResult, vortex_ensure}; use vortex_mask::Mask; use super::BoolVectorMut; @@ -30,11 +31,36 @@ impl BoolVector { /// /// Panics if the length of the validity mask does not match the length of the bits. pub fn new(bits: BitBuffer, validity: Mask) -> Self { - assert_eq!( + Self::try_new(bits, validity) + .vortex_expect("`BoolVector` validity mask must have the same length as bits") + } + + /// Tries to create a new [`BoolVector`] from the given bits and validity mask. + /// + /// # Errors + /// + /// Returns an error if the length of the validity mask does not match the length of the bits. + pub fn try_new(bits: BitBuffer, validity: Mask) -> VortexResult { + vortex_ensure!( + validity.len() == bits.len(), + "`BoolVector` validity mask must have the same length as bits" + ); + + Ok(Self { bits, validity }) + } + + /// Creates a new [`BoolVector`] from the given bits and validity mask without validation. + /// + /// # Safety + /// + /// The caller must ensure that the validity mask has the same length as the bits. + pub fn new_unchecked(bits: BitBuffer, validity: Mask) -> Self { + debug_assert_eq!( validity.len(), bits.len(), - "BoolVector validity mask must have the same length as bits" + "`BoolVector` validity mask must have the same length as bits" ); + Self { bits, validity } } diff --git a/vortex-vector/src/bool/vector_mut.rs b/vortex-vector/src/bool/vector_mut.rs index 3d4bab4cc33..2c478bbdc8f 100644 --- a/vortex-vector/src/bool/vector_mut.rs +++ b/vortex-vector/src/bool/vector_mut.rs @@ -4,6 +4,7 @@ //! Definition and implementation of [`BoolVectorMut`]. use vortex_buffer::BitBufferMut; +use vortex_error::{VortexExpect, VortexResult, vortex_ensure}; use vortex_mask::MaskMut; use super::BoolVector; @@ -71,15 +72,45 @@ pub struct BoolVectorMut { } impl BoolVectorMut { - /// Create a mutable vector from the given parts, without checking lengths or capacities. + /// Creates a new [`BoolVectorMut`] from the given bits and validity mask. /// - /// # SAFETY + /// # Panics /// - /// The caller must ensure both parts have the same length and capacity. Ideally they are - /// taken from `into_parts`, mutated in a way that doesn't re-allocate, and then passed back - /// to this function. + /// Panics if the length of the validity mask does not match the length of the bits. + pub fn new(bits: BitBufferMut, validity: MaskMut) -> Self { + Self::try_new(bits, validity) + .vortex_expect("`BoolVector` validity mask must have the same length as bits") + } + + /// Tries to create a new [`BoolVectorMut`] from the given bits and validity mask. + /// + /// # Errors + /// + /// Returns an error if the length of the validity mask does not match the length of the bits. + pub fn try_new(bits: BitBufferMut, validity: MaskMut) -> VortexResult { + vortex_ensure!( + validity.len() == bits.len(), + "`BoolVector` validity mask must have the same length as bits" + ); + + Ok(Self { bits, validity }) + } + + /// Creates a new [`BoolVectorMut`] from the given bits and validity mask without validation. + /// + /// # Safety + /// + /// The caller must ensure that the validity mask has the same length as the bits. + /// + /// Ideally, they are taken from `into_parts`, mutated in a way that doesn't re-allocate, and + /// then passed back to this function. pub unsafe fn new_unchecked(bits: BitBufferMut, validity: MaskMut) -> Self { - debug_assert_eq!(bits.len(), validity.len()); + debug_assert_eq!( + bits.len(), + validity.len(), + "`BoolVector` validity mask must have the same length as bits" + ); + Self { bits, validity } } diff --git a/vortex-vector/src/primitive/generic.rs b/vortex-vector/src/primitive/generic.rs index 236f29ed12b..9b1b8a24ab2 100644 --- a/vortex-vector/src/primitive/generic.rs +++ b/vortex-vector/src/primitive/generic.rs @@ -5,6 +5,7 @@ use vortex_buffer::Buffer; use vortex_dtype::NativePType; +use vortex_error::{VortexExpect, VortexResult, vortex_ensure}; use vortex_mask::Mask; use crate::{PVectorMut, VectorOps}; @@ -26,6 +27,49 @@ pub struct PVector { pub(super) validity: Mask, } +impl PVector { + /// Creates a new [`PVector`] from the given elements buffer and validity mask. + /// + /// # Panics + /// + /// Panics if the length of the validity mask does not match the length of the elements buffer. + pub fn new(elements: Buffer, validity: Mask) -> Self { + Self::try_new(elements, validity) + .vortex_expect("`PVector` validity mask must have the same length as elements") + } + + /// Tries to create a new [`PVector`] from the given elements buffer and validity mask. + /// + /// # Errors + /// + /// Returns an error if the length of the validity mask does not match the length of the + /// elements buffer. + pub fn try_new(elements: Buffer, validity: Mask) -> VortexResult { + vortex_ensure!( + validity.len() == elements.len(), + "`PVector` validity mask must have the same length as elements" + ); + + Ok(Self { elements, validity }) + } + + /// Creates a new [`PVector`] from the given elements buffer and validity mask without + /// validation. + /// + /// # Safety + /// + /// The caller must ensure that the validity mask has the same length as the elements buffer. + pub fn new_unchecked(elements: Buffer, validity: Mask) -> Self { + debug_assert_eq!( + validity.len(), + elements.len(), + "`PVector` validity mask must have the same length as elements" + ); + + Self { elements, validity } + } +} + impl VectorOps for PVector { type Mutable = PVectorMut; diff --git a/vortex-vector/src/primitive/generic_mut.rs b/vortex-vector/src/primitive/generic_mut.rs index 8bec5d9edb5..3fc7e602bbb 100644 --- a/vortex-vector/src/primitive/generic_mut.rs +++ b/vortex-vector/src/primitive/generic_mut.rs @@ -5,6 +5,7 @@ use vortex_buffer::BufferMut; use vortex_dtype::NativePType; +use vortex_error::{VortexExpect, VortexResult, vortex_ensure}; use vortex_mask::MaskMut; use crate::{PVector, VectorMutOps, VectorOps}; @@ -107,6 +108,50 @@ pub struct PVectorMut { } impl PVectorMut { + /// Creates a new [`PVectorMut`] from the given elements buffer and validity mask. + /// + /// # Panics + /// + /// Panics if the length of the validity mask does not match the length of the elements buffer. + pub fn new(elements: BufferMut, validity: MaskMut) -> Self { + Self::try_new(elements, validity) + .vortex_expect("`PVectorMut` validity mask must have the same length as elements") + } + + /// Tries to create a new [`PVectorMut`] from the given elements buffer and validity mask. + /// + /// # Errors + /// + /// Returns an error if the length of the validity mask does not match the length of the + /// elements buffer. + pub fn try_new(elements: BufferMut, validity: MaskMut) -> VortexResult { + vortex_ensure!( + validity.len() == elements.len(), + "`PVectorMut` validity mask must have the same length as elements" + ); + + Ok(Self { elements, validity }) + } + + /// Creates a new [`PVectorMut`] from the given elements buffer and validity mask without + /// validation. + /// + /// # Safety + /// + /// The caller must ensure that the validity mask has the same length as the elements buffer. + /// + /// Ideally, they are taken from `into_parts`, mutated in a way that doesn't re-allocate, and + /// then passed back to this function. + pub unsafe fn new_unchecked(elements: BufferMut, validity: MaskMut) -> Self { + debug_assert_eq!( + elements.len(), + validity.len(), + "`PVectorMut` validity mask must have the same length as elements" + ); + + Self { elements, validity } + } + /// Create a new mutable primitive vector with the given capacity. pub fn with_capacity(capacity: usize) -> Self { Self {