@@ -10,6 +10,7 @@ use vortex_array::IntoArray;
1010use vortex_array:: arrays:: BoolArray ;
1111use vortex_array:: validity:: Validity ;
1212use vortex_buffer:: BitBuffer ;
13+ use vortex_buffer:: ByteBuffer ;
1314use vortex_buffer:: ByteBufferMut ;
1415use vortex_error:: VortexExpect ;
1516use vortex_error:: VortexResult ;
@@ -38,7 +39,25 @@ pub fn transpose_validity(validity: &Validity, ctx: &mut ExecutionCtx) -> Vortex
3839
3940#[ inline]
4041pub fn transpose_bitbuffer ( bits : BitBuffer ) -> BitBuffer {
41- fastlanes_layout_apply ( bits, transpose_bits)
42+ let ( offset, len, bytes) = bits. into_inner ( ) ;
43+
44+ if bytes. len ( ) . is_multiple_of ( 128 ) {
45+ match bytes. try_into_mut ( ) {
46+ Ok ( mut bytes_mut) => {
47+ // We can ignore the spare trailer capacity that can be an artifact of allocator as we requested 128 multiple chunks
48+ let ( chunks, _) = bytes_mut. as_chunks_mut :: < 128 > ( ) ;
49+ let mut tmp = [ 0u8 ; 128 ] ;
50+ for chunk in chunks {
51+ transpose_bits ( chunk, & mut tmp) ;
52+ chunk. copy_from_slice ( & tmp) ;
53+ }
54+ BitBuffer :: new_with_offset ( bytes_mut. freeze ( ) . into_byte_buffer ( ) , len, offset)
55+ }
56+ Err ( bytes) => bits_op_with_copy ( bytes, len, offset, transpose_bits) ,
57+ }
58+ } else {
59+ bits_op_with_copy ( bytes, len, offset, transpose_bits)
60+ }
4261}
4362
4463pub fn untranspose_validity ( validity : & Validity , ctx : & mut ExecutionCtx ) -> VortexResult < Validity > {
@@ -62,12 +81,31 @@ pub fn untranspose_validity(validity: &Validity, ctx: &mut ExecutionCtx) -> Vort
6281
6382#[ inline]
6483pub fn untranspose_bitbuffer ( bits : BitBuffer ) -> BitBuffer {
65- fastlanes_layout_apply ( bits , untranspose_bits )
66- }
67-
68- fn fastlanes_layout_apply < F : Fn ( & [ u8 ; 128 ] , & mut [ u8 ; 128 ] ) > ( bits : BitBuffer , op : F ) -> BitBuffer {
84+ assert ! (
85+ bits . inner ( ) . len ( ) . is_multiple_of ( 128 ) ,
86+ "Transpose BitBuffer must be 128-byte aligned"
87+ ) ;
6988 let ( offset, len, bytes) = bits. into_inner ( ) ;
89+ match bytes. try_into_mut ( ) {
90+ Ok ( mut bytes_mut) => {
91+ let ( chunks, _) = bytes_mut. as_chunks_mut :: < 128 > ( ) ;
92+ let mut tmp = [ 0u8 ; 128 ] ;
93+ for chunk in chunks {
94+ untranspose_bits ( chunk, & mut tmp) ;
95+ chunk. copy_from_slice ( & tmp) ;
96+ }
97+ BitBuffer :: new_with_offset ( bytes_mut. freeze ( ) . into_byte_buffer ( ) , len, offset)
98+ }
99+ Err ( bytes) => bits_op_with_copy ( bytes, len, offset, untranspose_bits) ,
100+ }
101+ }
70102
103+ fn bits_op_with_copy < F : Fn ( & [ u8 ; 128 ] , & mut [ u8 ; 128 ] ) > (
104+ bytes : ByteBuffer ,
105+ len : usize ,
106+ offset : usize ,
107+ op : F ,
108+ ) -> BitBuffer {
71109 let output_len = bytes. len ( ) . next_multiple_of ( 128 ) ;
72110 let mut output = ByteBufferMut :: with_capacity ( output_len) ;
73111 let ( input_chunks, input_trailer) = bytes. as_chunks :: < 128 > ( ) ;
0 commit comments