@@ -29,7 +29,7 @@ use vortex_array::vtable::VTable;
2929use vortex_array:: vtable:: ValidityVTable ;
3030use vortex_array:: vtable:: child_to_validity;
3131use vortex_array:: vtable:: validity_to_child;
32- use vortex_buffer:: BitBuffer ;
32+ use vortex_buffer:: BitBufferMut ;
3333use vortex_buffer:: ByteBuffer ;
3434use vortex_error:: VortexResult ;
3535use vortex_error:: vortex_bail;
@@ -131,7 +131,7 @@ impl VTable for ByteBool {
131131 }
132132 let buffer = buffers[ 0 ] . clone ( ) ;
133133
134- let data = ByteBoolData :: new ( buffer, validity . clone ( ) ) ;
134+ let data = ByteBoolData :: new ( buffer) ;
135135 let slots = ByteBoolData :: make_slots ( & validity, len) ;
136136 Ok ( ArrayParts :: new ( self . clone ( ) , dtype. clone ( ) , len, data) . with_slots ( slots) )
137137 }
@@ -149,7 +149,8 @@ impl VTable for ByteBool {
149149 }
150150
151151 fn execute ( array : Array < Self > , _ctx : & mut ExecutionCtx ) -> VortexResult < ExecutionResult > {
152- let boolean_buffer = BitBuffer :: from ( array. as_slice ( ) ) ;
152+ // convert truthy values to set/unset bits
153+ let boolean_buffer = BitBufferMut :: from ( array. truthy_bytes ( ) ) . freeze ( ) ;
153154 let validity = array. validity ( ) ?;
154155 Ok ( ExecutionResult :: done (
155156 BoolArray :: new ( boolean_buffer, validity) . into_array ( ) ,
@@ -198,9 +199,17 @@ pub struct ByteBool;
198199
199200impl ByteBool {
200201 pub fn new ( buffer : BufferHandle , validity : Validity ) -> ByteBoolArray {
202+ if let Some ( len) = validity. maybe_len ( ) {
203+ assert_eq ! (
204+ buffer. len( ) ,
205+ len,
206+ "ByteBool validity and bytes must have same length"
207+ ) ;
208+ }
201209 let dtype = DType :: Bool ( validity. nullability ( ) ) ;
210+
202211 let slots = ByteBoolData :: make_slots ( & validity, buffer. len ( ) ) ;
203- let data = ByteBoolData :: new ( buffer, validity ) ;
212+ let data = ByteBoolData :: new ( buffer) ;
204213 let len = data. len ( ) ;
205214 unsafe {
206215 Array :: from_parts_unchecked (
@@ -212,29 +221,22 @@ impl ByteBool {
212221 /// Construct a [`ByteBoolArray`] from a `Vec<bool>` and validity.
213222 pub fn from_vec < V : Into < Validity > > ( data : Vec < bool > , validity : V ) -> ByteBoolArray {
214223 let validity = validity. into ( ) ;
215- let data = ByteBoolData :: from_vec ( data, validity. clone ( ) ) ;
216- let dtype = DType :: Bool ( validity. nullability ( ) ) ;
217- let len = data. len ( ) ;
218- let slots = ByteBoolData :: make_slots ( & validity, len) ;
219- unsafe {
220- Array :: from_parts_unchecked (
221- ArrayParts :: new ( ByteBool , dtype, len, data) . with_slots ( slots) ,
222- )
223- }
224+ // NOTE: this will not cause allocation on release builds
225+ let bytes: Vec < u8 > = data. into_iter ( ) . map ( |b| b as u8 ) . collect ( ) ;
226+ let handle = BufferHandle :: new_host ( ByteBuffer :: from ( bytes) ) ;
227+ ByteBool :: new ( handle, validity)
224228 }
225229
226230 /// Construct a [`ByteBoolArray`] from optional bools.
227231 pub fn from_option_vec ( data : Vec < Option < bool > > ) -> ByteBoolArray {
228232 let validity = Validity :: from_iter ( data. iter ( ) . map ( |v| v. is_some ( ) ) ) ;
229- let data = ByteBoolData :: from ( data) ;
230- let dtype = DType :: Bool ( validity. nullability ( ) ) ;
231- let len = data. len ( ) ;
232- let slots = ByteBoolData :: make_slots ( & validity, len) ;
233- unsafe {
234- Array :: from_parts_unchecked (
235- ArrayParts :: new ( ByteBool , dtype, len, data) . with_slots ( slots) ,
236- )
237- }
233+ // NOTE: this will not cause allocation on release builds
234+ let bytes: Vec < u8 > = data
235+ . into_iter ( )
236+ . map ( |b| b. unwrap_or_default ( ) as u8 )
237+ . collect ( ) ;
238+ let handle = BufferHandle :: new_host ( ByteBuffer :: from ( bytes) ) ;
239+ ByteBool :: new ( handle, validity)
238240 }
239241}
240242
@@ -265,17 +267,7 @@ impl ByteBoolData {
265267 vec ! [ validity_to_child( validity, len) ]
266268 }
267269
268- pub fn new ( buffer : BufferHandle , validity : Validity ) -> Self {
269- let length = buffer. len ( ) ;
270- if let Some ( vlen) = validity. maybe_len ( )
271- && length != vlen
272- {
273- vortex_panic ! (
274- "Buffer length ({}) does not match validity length ({})" ,
275- length,
276- vlen
277- ) ;
278- }
270+ pub fn new ( buffer : BufferHandle ) -> Self {
279271 Self { buffer }
280272 }
281273
@@ -289,21 +281,15 @@ impl ByteBoolData {
289281 self . buffer . len ( ) == 0
290282 }
291283
292- // TODO(ngates): deprecate construction from vec
293- pub fn from_vec < V : Into < Validity > > ( data : Vec < bool > , validity : V ) -> Self {
294- let validity = validity. into ( ) ;
295- // SAFETY: we are transmuting a Vec<bool> into a Vec<u8>
296- let data: Vec < u8 > = unsafe { std:: mem:: transmute ( data) } ;
297- Self :: new ( BufferHandle :: new_host ( ByteBuffer :: from ( data) ) , validity)
298- }
299-
300284 pub fn buffer ( & self ) -> & BufferHandle {
301285 & self . buffer
302286 }
303287
304- pub fn as_slice ( & self ) -> & [ bool ] {
305- // Safety: The internal buffer contains byte-sized bools
306- unsafe { std:: mem:: transmute ( self . buffer ( ) . as_host ( ) . as_slice ( ) ) }
288+ /// Get access to the underlying 8-bit truthy values.
289+ ///
290+ /// The zero byte indicates `false`, and any non-zero byte is a `true`.
291+ pub fn truthy_bytes ( & self ) -> & [ u8 ] {
292+ self . buffer ( ) . as_host ( ) . as_slice ( )
307293 }
308294}
309295
@@ -326,23 +312,6 @@ impl OperationsVTable<ByteBool> for ByteBool {
326312 }
327313}
328314
329- impl From < Vec < bool > > for ByteBoolData {
330- fn from ( value : Vec < bool > ) -> Self {
331- Self :: from_vec ( value, Validity :: AllValid )
332- }
333- }
334-
335- impl From < Vec < Option < bool > > > for ByteBoolData {
336- fn from ( value : Vec < Option < bool > > ) -> Self {
337- let validity = Validity :: from_iter ( value. iter ( ) . map ( |v| v. is_some ( ) ) ) ;
338-
339- // This doesn't reallocate, and the compiler even vectorizes it
340- let data = value. into_iter ( ) . map ( Option :: unwrap_or_default) . collect ( ) ;
341-
342- Self :: from_vec ( data, validity)
343- }
344- }
345-
346315#[ cfg( test) ]
347316mod tests {
348317 use vortex_array:: ArrayContext ;
0 commit comments