@@ -6,6 +6,7 @@ use std::iter::repeat_n;
66use arrow_array:: cast:: AsArray ;
77use vortex_buffer:: BitBuffer ;
88use vortex_buffer:: BufferMut ;
9+ use vortex_buffer:: read_u64_le;
910use vortex_error:: VortexResult ;
1011use vortex_error:: vortex_err;
1112use vortex_mask:: AllOr ;
@@ -37,11 +38,14 @@ use crate::scalar_fn::fns::binary::Binary;
3738use crate :: scalar_fn:: fns:: operators:: Operator ;
3839use crate :: validity:: Validity ;
3940
40- /// Trait for encoding-specific Kleene boolean kernels that operate in encoded space.
41+ /// Trait for encoding-specific boolean kernels that operate in encoded space.
4142///
4243/// Implementations receive the encoded array as the left operand. `rhs` may be any boolean array
4344/// encoding or a constant; implementations should return `Ok(None)` when they cannot handle that
4445/// operand without falling back to ordinary execution.
46+ ///
47+ /// Vortex's boolean [`Operator::And`] and [`Operator::Or`] variants use Kleene semantics; there is
48+ /// no separate two-valued boolean operator path to dispatch here.
4549pub trait BooleanKernel : VTable {
4650 /// Execute `lhs <operator> rhs` using Kleene boolean semantics.
4751 fn boolean (
@@ -268,7 +272,7 @@ pub fn boolean_buffers(
268272 Operator :: Or => lhs_values | & rhs_values,
269273 other => return Err ( vortex_err ! ( "Not a boolean operator: {other}" ) ) ,
270274 } ;
271- return Ok ( BoolArray :: try_new ( values, all_validity ( nullability) ) ?. into_array ( ) ) ;
275+ return Ok ( BoolArray :: try_new ( values, Validity :: from ( nullability) ) ?. into_array ( ) ) ;
272276 }
273277
274278 let lhs_valid = lhs_validity. execute_mask ( len, ctx) ?;
@@ -318,14 +322,14 @@ pub fn boolean_buffer_scalar(
318322 . bitand_not ( & Mask :: from_buffer ( values) ) ;
319323 BoolArray :: try_new (
320324 BitBuffer :: new_unset ( len) ,
321- mask_to_validity ( valid, nullability) ,
325+ Validity :: from_mask ( valid, nullability) ,
322326 ) ?
323327 }
324328 ( Operator :: Or , None ) => {
325329 let valid = validity. execute_mask ( len, ctx) ? & & Mask :: from_buffer ( values) ;
326330 BoolArray :: try_new (
327331 BitBuffer :: new_set ( len) ,
328- mask_to_validity ( valid, nullability) ,
332+ Validity :: from_mask ( valid, nullability) ,
329333 ) ?
330334 }
331335 ( other, _) => return Err ( vortex_err ! ( "Not a boolean operator: {other}" ) ) ,
@@ -430,16 +434,16 @@ fn fused_boolean_buffers_aligned(
430434 operator : Operator ,
431435 nullability : Nullability ,
432436) -> VortexResult < Option < ArrayRef > > {
433- let Some ( lhs_values) = word_source_from_bit_buffer ( lhs_values, len ) else {
437+ let Some ( lhs_values) = word_source_from_bit_buffer ( lhs_values) else {
434438 return Ok ( None ) ;
435439 } ;
436- let Some ( rhs_values) = word_source_from_bit_buffer ( rhs_values, len ) else {
440+ let Some ( rhs_values) = word_source_from_bit_buffer ( rhs_values) else {
437441 return Ok ( None ) ;
438442 } ;
439- let Some ( lhs_validity) = word_source_from_mask ( lhs_validity, len ) else {
443+ let Some ( lhs_validity) = word_source_from_mask ( lhs_validity) else {
440444 return Ok ( None ) ;
441445 } ;
442- let Some ( rhs_validity) = word_source_from_mask ( rhs_validity, len ) else {
446+ let Some ( rhs_validity) = word_source_from_mask ( rhs_validity) else {
443447 return Ok ( None ) ;
444448 } ;
445449
@@ -454,32 +458,18 @@ fn fused_boolean_buffers_aligned(
454458 ) ?) )
455459}
456460
457- fn word_source_from_bit_buffer ( buffer : & BitBuffer , len : usize ) -> Option < WordSource < ' _ > > {
458- if !buffer. offset ( ) . is_multiple_of ( 8 ) {
459- return None ;
460- }
461-
462- let n_bytes = len. div_ceil ( 8 ) ;
463- let start = buffer. offset ( ) / 8 ;
464- let end = start + n_bytes;
465- Some ( WordSource :: Bytes ( & buffer. inner ( ) . as_slice ( ) [ start..end] ) )
461+ fn word_source_from_bit_buffer ( buffer : & BitBuffer ) -> Option < WordSource < ' _ > > {
462+ buffer. byte_aligned_bytes ( ) . map ( WordSource :: Bytes )
466463}
467464
468- fn word_source_from_mask ( mask : & Mask , len : usize ) -> Option < WordSource < ' _ > > {
465+ fn word_source_from_mask ( mask : & Mask ) -> Option < WordSource < ' _ > > {
469466 match mask. bit_buffer ( ) {
470467 AllOr :: All => Some ( WordSource :: Fill ( u64:: MAX ) ) ,
471468 AllOr :: None => Some ( WordSource :: Fill ( 0 ) ) ,
472- AllOr :: Some ( buffer) => word_source_from_bit_buffer ( buffer, len ) ,
469+ AllOr :: Some ( buffer) => word_source_from_bit_buffer ( buffer) ,
473470 }
474471}
475472
476- fn read_u64_le ( bytes : & [ u8 ] ) -> u64 {
477- debug_assert ! ( bytes. len( ) <= 8 ) ;
478- let mut buf = [ 0 ; 8 ] ;
479- buf[ ..bytes. len ( ) ] . copy_from_slice ( bytes) ;
480- u64:: from_le_bytes ( buf)
481- }
482-
483473fn fused_boolean_word_sources (
484474 len : usize ,
485475 lhs_words : WordSource < ' _ > ,
@@ -581,7 +571,7 @@ fn finish_fused_boolean_words(
581571 validity. truncate ( n_bytes) ;
582572 Ok ( BoolArray :: try_new (
583573 BitBuffer :: new ( values. freeze ( ) , len) ,
584- mask_to_validity (
574+ Validity :: from_mask (
585575 Mask :: from_buffer ( BitBuffer :: new ( validity. freeze ( ) , len) ) ,
586576 nullability,
587577 ) ,
@@ -651,7 +641,7 @@ where
651641
652642 Ok ( BoolArray :: try_new (
653643 values,
654- mask_to_validity ( Mask :: from_buffer ( validity) , nullability) ,
644+ Validity :: from_mask ( Mask :: from_buffer ( validity) , nullability) ,
655645 ) ?
656646 . into_array ( ) )
657647}
@@ -677,23 +667,6 @@ fn boolean_nullability(lhs: &ArrayRef, rhs: &ArrayRef) -> Nullability {
677667 lhs. dtype ( ) . nullability ( ) | rhs. dtype ( ) . nullability ( )
678668}
679669
680- fn all_validity ( nullability : Nullability ) -> Validity {
681- match nullability {
682- Nullability :: NonNullable => Validity :: NonNullable ,
683- Nullability :: Nullable => Validity :: AllValid ,
684- }
685- }
686-
687- fn mask_to_validity ( mask : Mask , nullability : Nullability ) -> Validity {
688- match nullability {
689- Nullability :: NonNullable => {
690- debug_assert ! ( mask. all_true( ) ) ;
691- Validity :: NonNullable
692- }
693- Nullability :: Nullable => Validity :: from ( mask. into_bit_buffer ( ) ) ,
694- }
695- }
696-
697670#[ inline]
698671fn is_boolean_operator ( operator : Operator ) -> bool {
699672 matches ! ( operator, Operator :: And | Operator :: Or )
0 commit comments