44use itertools:: Itertools as _;
55use num_traits:: AsPrimitive ;
66use vortex_buffer:: BitBuffer ;
7+ use vortex_buffer:: BitBufferMut ;
78use vortex_buffer:: BitBufferView ;
89use vortex_buffer:: get_bit;
910use vortex_error:: VortexResult ;
@@ -15,12 +16,17 @@ use crate::array::ArrayView;
1516use crate :: arrays:: Bool ;
1617use crate :: arrays:: BoolArray ;
1718use crate :: arrays:: ConstantArray ;
19+ use crate :: arrays:: PiecewiseSequential ;
1820use crate :: arrays:: PrimitiveArray ;
1921use crate :: arrays:: bool:: BoolArrayExt ;
2022use crate :: arrays:: dict:: TakeExecute ;
23+ use crate :: arrays:: piecewise_sequential:: execute_index_arrays;
24+ use crate :: arrays:: piecewise_sequential:: index_value_to_usize;
25+ use crate :: arrays:: piecewise_sequential:: validate_index_ranges;
2126use crate :: builtins:: ArrayBuiltins ;
2227use crate :: executor:: ExecutionCtx ;
2328use crate :: match_each_integer_ptype;
29+ use crate :: match_each_unsigned_integer_ptype;
2430use crate :: scalar:: Scalar ;
2531
2632impl TakeExecute for Bool {
@@ -29,6 +35,10 @@ impl TakeExecute for Bool {
2935 indices : & ArrayRef ,
3036 ctx : & mut ExecutionCtx ,
3137 ) -> VortexResult < Option < ArrayRef > > {
38+ if let Some ( piecewise_indices) = indices. as_opt :: < PiecewiseSequential > ( ) {
39+ return take_piecewise_sequential ( array, piecewise_indices, indices, ctx) . map ( Some ) ;
40+ }
41+
3242 let indices_nulls_zeroed = match indices. validity ( ) ?. execute_mask ( indices. len ( ) , ctx) ? {
3343 Mask :: AllTrue ( _) => indices. clone ( ) ,
3444 Mask :: AllFalse ( _) => {
@@ -55,6 +65,27 @@ impl TakeExecute for Bool {
5565 }
5666}
5767
68+ fn take_piecewise_sequential (
69+ array : ArrayView < ' _ , Bool > ,
70+ indices : ArrayView < ' _ , PiecewiseSequential > ,
71+ indices_ref : & ArrayRef ,
72+ ctx : & mut ExecutionCtx ,
73+ ) -> VortexResult < ArrayRef > {
74+ let ( starts, lengths) = execute_index_arrays ( indices, ctx) ?;
75+ let buffer = match_each_unsigned_integer_ptype ! ( starts. ptype( ) , |S | {
76+ match_each_unsigned_integer_ptype!( lengths. ptype( ) , |L | {
77+ take_piecewise_bits(
78+ & array. to_bit_buffer( ) ,
79+ starts. as_slice:: <S >( ) ,
80+ lengths. as_slice:: <L >( ) ,
81+ indices_ref. len( ) ,
82+ ) ?
83+ } )
84+ } ) ;
85+
86+ Ok ( BoolArray :: new ( buffer, array. validity ( ) ?. take ( indices_ref) ?) . into_array ( ) )
87+ }
88+
5889fn take_valid_indices < I : AsPrimitive < usize > > ( bools : BitBufferView < ' _ > , indices : & [ I ] ) -> BitBuffer {
5990 // For boolean arrays that roughly fit into a single page (at least, on Linux), it's worth
6091 // the overhead to convert to a Vec<bool>.
@@ -82,6 +113,28 @@ fn take_bool_impl<I: AsPrimitive<usize>>(bools: BitBufferView<'_>, indices: &[I]
82113 } )
83114}
84115
116+ fn take_piecewise_bits < S , L > (
117+ source : & BitBuffer ,
118+ starts : & [ S ] ,
119+ lengths : & [ L ] ,
120+ output_len : usize ,
121+ ) -> VortexResult < BitBuffer >
122+ where
123+ S : crate :: dtype:: UnsignedPType ,
124+ L : crate :: dtype:: UnsignedPType ,
125+ {
126+ validate_index_ranges ( source. len ( ) , starts, lengths, output_len) ?;
127+
128+ let mut values = BitBufferMut :: with_capacity ( output_len) ;
129+ for ( & start, & length) in starts. iter ( ) . zip_eq ( lengths) {
130+ let start = index_value_to_usize ( start) ;
131+ let length = index_value_to_usize ( length) ;
132+ values. append_buffer ( & source. slice ( start..start + length) ) ;
133+ }
134+
135+ Ok ( values. freeze ( ) )
136+ }
137+
85138#[ cfg( test) ]
86139mod test {
87140 use rstest:: rstest;
0 commit comments