@@ -14,8 +14,10 @@ use crate::arrays::DecimalArray;
1414use crate :: arrays:: PiecewiseSequence ;
1515use crate :: arrays:: PrimitiveArray ;
1616use crate :: arrays:: dict:: TakeExecute ;
17+ use crate :: arrays:: piecewise_sequence:: UnitMultiplierLengths ;
1718use crate :: arrays:: piecewise_sequence:: execute_unit_multiplier_index_arrays;
1819use crate :: arrays:: piecewise_sequence:: validate_index_ranges;
20+ use crate :: arrays:: piecewise_sequence:: validate_index_ranges_constant;
1921use crate :: dtype:: IntegerPType ;
2022use crate :: dtype:: NativeDecimalType ;
2123use crate :: dtype:: UnsignedPType ;
@@ -67,10 +69,57 @@ fn take_piecewise_sequence(
6769 } ;
6870 let validity = array. validity ( ) ?. take ( indices_ref) ?;
6971 let output_len = indices_ref. len ( ) ;
70- let taken = take_piecewise_sequence_lengths ( array, & starts, & lengths, validity, output_len) ?;
72+ let taken = match lengths {
73+ UnitMultiplierLengths :: Constant ( length) => {
74+ take_piecewise_sequence_constant_length ( array, & starts, length, validity, output_len) ?
75+ }
76+ UnitMultiplierLengths :: Array ( lengths) => {
77+ take_piecewise_sequence_lengths ( array, & starts, & lengths, validity, output_len) ?
78+ }
79+ } ;
7180 Ok ( Some ( taken) )
7281}
7382
83+ fn take_piecewise_sequence_constant_length (
84+ array : ArrayView < ' _ , Decimal > ,
85+ starts : & PrimitiveArray ,
86+ length : usize ,
87+ validity : Validity ,
88+ output_len : usize ,
89+ ) -> VortexResult < ArrayRef > {
90+ match_each_decimal_value_type ! ( array. values_type( ) , |D | {
91+ take_piecewise_sequence_constant_length_typed:: <D >(
92+ array, starts, length, validity, output_len,
93+ )
94+ } )
95+ }
96+
97+ fn take_piecewise_sequence_constant_length_typed < D > (
98+ array : ArrayView < ' _ , Decimal > ,
99+ starts : & PrimitiveArray ,
100+ length : usize ,
101+ validity : Validity ,
102+ output_len : usize ,
103+ ) -> VortexResult < ArrayRef >
104+ where
105+ D : NativeDecimalType ,
106+ {
107+ match_each_unsigned_integer_ptype ! ( starts. ptype( ) , |S | {
108+ let values = take_piecewise_constant_length_to_buffer:: <S , D >(
109+ starts. as_slice:: <S >( ) ,
110+ length,
111+ array. buffer:: <D >( ) . as_slice( ) ,
112+ output_len,
113+ ) ?;
114+
115+ // SAFETY: contiguous gather preserves the decimal dtype and value representation.
116+ Ok (
117+ unsafe { DecimalArray :: new_unchecked( values, array. decimal_dtype( ) , validity) }
118+ . into_array( ) ,
119+ )
120+ } )
121+ }
122+
74123fn take_piecewise_sequence_lengths (
75124 array : ArrayView < ' _ , Decimal > ,
76125 starts : & PrimitiveArray ,
@@ -131,6 +180,27 @@ fn take_to_buffer<I: IntegerPType, T: NativeDecimalType>(indices: &[I], values:
131180 indices. iter ( ) . map ( |idx| values[ idx. as_ ( ) ] ) . collect ( )
132181}
133182
183+ fn take_piecewise_constant_length_to_buffer < S , T > (
184+ starts : & [ S ] ,
185+ length : usize ,
186+ values : & [ T ] ,
187+ output_len : usize ,
188+ ) -> VortexResult < Buffer < T > >
189+ where
190+ S : UnsignedPType ,
191+ T : NativeDecimalType ,
192+ {
193+ validate_index_ranges_constant ( values. len ( ) , starts, length, output_len) ?;
194+
195+ let mut result = BufferMut :: < T > :: with_capacity ( output_len) ;
196+ for & start in starts {
197+ let start = start. as_ ( ) ;
198+ result. extend_from_slice ( & values[ start..start + length] ) ;
199+ }
200+
201+ Ok ( result. freeze ( ) )
202+ }
203+
134204fn take_piecewise_to_buffer < S , L , T > (
135205 starts : & [ S ] ,
136206 lengths : & [ L ] ,
0 commit comments