44use arrow_array:: BooleanArray ;
55use vortex_buffer:: BitBuffer ;
66use vortex_buffer:: BitBufferMut ;
7- use vortex_buffer:: ByteBuffer ;
87use vortex_dtype:: DType ;
98use vortex_error:: VortexExpect ;
109use vortex_error:: VortexResult ;
@@ -49,12 +48,21 @@ use crate::validity::Validity;
4948#[ derive( Clone , Debug ) ]
5049pub struct BoolArray {
5150 pub ( super ) dtype : DType ,
52- pub ( super ) buffer : BitBuffer ,
51+ pub ( super ) bits : BitBuffer ,
5352 pub ( super ) validity : Validity ,
5453 pub ( super ) stats_set : ArrayStats ,
5554}
5655
5756impl BoolArray {
57+ /// Constructs a new `BoolArray`.
58+ ///
59+ /// # Panics
60+ ///
61+ /// Panics if the validity length is not equal to the bit buffer length.
62+ pub fn new ( bits : BitBuffer , validity : Validity ) -> Self {
63+ Self :: try_new ( bits, validity) . vortex_expect ( "Failed to create BoolArray" )
64+ }
65+
5866 /// Constructs a new `BoolArray`.
5967 ///
6068 /// See [`BoolArray::new_unchecked`] for more information.
@@ -63,80 +71,51 @@ impl BoolArray {
6371 ///
6472 /// Returns an error if the provided components do not satisfy the invariants documented in
6573 /// [`BoolArray::new_unchecked`].
66- pub fn try_new (
67- buffer : ByteBuffer ,
68- offset : usize ,
69- len : usize ,
70- validity : Validity ,
71- ) -> VortexResult < Self > {
72- Self :: validate ( & buffer, offset, len, & validity) ?;
73-
74- // SAFETY: validate ensures all invariants are met.
75- Ok ( unsafe { Self :: new_unchecked ( buffer, offset, len, validity) } )
74+ pub fn try_new ( bits : BitBuffer , validity : Validity ) -> VortexResult < Self > {
75+ let bits = bits. shrink_offset ( ) ;
76+ Self :: validate ( & bits, & validity) ?;
77+ Ok ( Self {
78+ dtype : DType :: Bool ( validity. nullability ( ) ) ,
79+ bits,
80+ validity,
81+ stats_set : ArrayStats :: default ( ) ,
82+ } )
7683 }
7784
7885 /// Creates a new [`BoolArray`] without validation from these components:
7986 ///
80- /// * `buffer` is a raw [`ByteBuffer`] holding the packed bits.
81- /// * `offset` is the number of bits in the start of the buffer that should be skipped when
82- /// looking up the i-th value.
83- /// * `len` is the length of the array, which should correspond to the number of bits.
84- /// * `validity` holds the null values.
85- ///
8687 /// # Safety
8788 ///
88- /// The caller must ensure all of the following invariants are satisfied:
89- ///
90- /// - `buffer` must contain at least `(offset + len).div_ceil(8)` bytes.
91- /// - `offset` must be less than 8 (it represents the bit offset within the first byte).
92- /// - If `validity` is `Validity::Array`, its length must exactly equal `len`.
93- pub unsafe fn new_unchecked (
94- buffer : ByteBuffer ,
95- offset : usize ,
96- len : usize ,
97- validity : Validity ,
98- ) -> Self {
99- #[ cfg( debug_assertions) ]
100- Self :: validate ( & buffer, offset, len, & validity)
101- . vortex_expect ( "[Debug Assertion]: Invalid `BoolArray` parameters" ) ;
102-
103- let buffer = BitBuffer :: new_with_offset ( buffer, len, offset) ;
104- let buffer = buffer. shrink_offset ( ) ;
105- Self {
106- dtype : DType :: Bool ( validity. nullability ( ) ) ,
107- buffer,
108- validity,
109- stats_set : ArrayStats :: default ( ) ,
89+ /// The caller must ensure that the validity length is equal to the bit buffer length.
90+ pub unsafe fn new_unchecked ( bits : BitBuffer , validity : Validity ) -> Self {
91+ if cfg ! ( debug_assertions) {
92+ Self :: new ( bits, validity)
93+ } else {
94+ Self {
95+ dtype : DType :: Bool ( validity. nullability ( ) ) ,
96+ bits,
97+ validity,
98+ stats_set : ArrayStats :: default ( ) ,
99+ }
110100 }
111101 }
112102
113103 /// Validates the components that would be used to create a [`BoolArray`].
114104 ///
115105 /// This function checks all the invariants required by [`BoolArray::new_unchecked`].
116- pub fn validate (
117- buffer : & ByteBuffer ,
118- offset : usize ,
119- len : usize ,
120- validity : & Validity ,
121- ) -> VortexResult < ( ) > {
122- vortex_ensure ! (
123- offset < 8 ,
124- "offset must be less than whole byte, was {offset} bits"
125- ) ;
126-
127- // Validate the buffer is large enough to hold all the bits
128- let required_bytes = offset. saturating_add ( len) . div_ceil ( 8 ) ;
106+ pub fn validate ( bits : & BitBuffer , validity : & Validity ) -> VortexResult < ( ) > {
129107 vortex_ensure ! (
130- buffer . len ( ) >= required_bytes ,
131- "BoolArray with offset={offset} len={len} cannot be built from buffer of size {}" ,
132- buffer . len ( )
108+ bits . offset ( ) < 8 ,
109+ "BitBuffer offset must be <8, got {}" ,
110+ bits . offset ( )
133111 ) ;
134112
135113 // Validate validity
136114 if let Some ( validity_len) = validity. maybe_len ( ) {
137115 vortex_ensure ! (
138- validity_len == len,
139- "BoolArray of size {len} cannot be built with validity of size {validity_len}"
116+ validity_len == bits. len( ) ,
117+ "BoolArray of size {} cannot be built with validity of size {validity_len}" ,
118+ bits. len( )
140119 ) ;
141120 }
142121
@@ -157,7 +136,7 @@ impl BoolArray {
157136 let buffer = buffer. shrink_offset ( ) ;
158137 Self {
159138 dtype : DType :: Bool ( validity. nullability ( ) ) ,
160- buffer,
139+ bits : buffer,
161140 validity,
162141 stats_set : ArrayStats :: default ( ) ,
163142 }
@@ -179,16 +158,16 @@ impl BoolArray {
179158 /// Returns the underlying [`BitBuffer`] of the array.
180159 pub fn bit_buffer ( & self ) -> & BitBuffer {
181160 assert ! (
182- self . buffer . offset( ) < 8 ,
161+ self . bits . offset( ) < 8 ,
183162 "Offset must be <8, did we forget to call shrink_offset? Found {}" ,
184- self . buffer . offset( )
163+ self . bits . offset( )
185164 ) ;
186- & self . buffer
165+ & self . bits
187166 }
188167
189168 /// Returns the underlying [`BitBuffer`] ofthe array
190169 pub fn into_bit_buffer ( self ) -> BitBuffer {
191- self . buffer
170+ self . bits
192171 }
193172
194173 pub fn to_mask ( & self ) -> Mask {
@@ -247,10 +226,7 @@ impl FromIterator<Option<bool>> for BoolArray {
247226
248227impl IntoArray for BitBuffer {
249228 fn into_array ( self ) -> ArrayRef {
250- let ( offset, len, buffer) = self . into_inner ( ) ;
251- BoolArray :: try_new ( buffer, offset, len, Validity :: NonNullable )
252- . vortex_expect ( "known correct" )
253- . into_array ( )
229+ BoolArray :: new ( self , Validity :: NonNullable ) . into_array ( )
254230 }
255231}
256232
0 commit comments