1616// under the License.
1717
1818use crate :: coalesce:: InProgressArray ;
19+ use crate :: filter:: { FilterPredicate , IndexIterator , IterationStrategy , SlicesIterator } ;
1920use arrow_array:: cast:: AsArray ;
2021use arrow_array:: { Array , ArrayRef , ArrowPrimitiveType , PrimitiveArray } ;
2122use arrow_buffer:: { NullBufferBuilder , ScalarBuffer } ;
@@ -92,8 +93,8 @@ impl<T: ArrowPrimitiveType + Debug> InProgressArray for InProgressPrimitiveArray
9293 Ok ( ( ) )
9394 }
9495
95- /// Copy rows by indices using an iterator (internal helper)
96- fn copy_rows_by_indices ( & mut self , indices : & [ usize ] ) -> Result < ( ) , ArrowError > {
96+ /// Copy rows by indices using a predicate
97+ fn copy_rows_by_filter ( & mut self , filter : & FilterPredicate ) -> Result < ( ) , ArrowError > {
9798 self . ensure_capacity ( ) ;
9899
99100 let s = self
@@ -107,21 +108,86 @@ impl<T: ArrowPrimitiveType + Debug> InProgressArray for InProgressPrimitiveArray
107108 . as_primitive :: < T > ( ) ;
108109
109110 let values = s. values ( ) ;
110-
111- // Copy values and nulls for each index
112- if let Some ( nulls) = s. nulls ( ) . filter ( |n| n. null_count ( ) > 0 ) {
113- for & idx in indices {
114- if nulls. is_null ( idx) {
115- self . nulls . append_null ( ) ;
111+ let count = filter. count ( ) ;
112+
113+ // Use the predicate's strategy for optimal iteration
114+ match filter. strategy ( ) {
115+ IterationStrategy :: SlicesIterator => {
116+ // Copy values using slices
117+ for ( start, end) in SlicesIterator :: new ( filter. filter_array ( ) ) {
118+ self . current . extend_from_slice ( & values[ start..end] ) ;
119+ }
120+ // Copy nulls using slices
121+ if let Some ( nulls) = s. nulls ( ) . filter ( |n| n. null_count ( ) > 0 ) {
122+ for ( start, end) in SlicesIterator :: new ( filter. filter_array ( ) ) {
123+ let slice = nulls. slice ( start, end - start) ;
124+ self . nulls . append_buffer ( & slice) ;
125+ }
116126 } else {
117- self . nulls . append_non_null ( ) ;
127+ self . nulls . append_n_non_nulls ( count ) ;
118128 }
119129 }
120- } else {
121- self . nulls . append_n_non_nulls ( indices. len ( ) ) ;
130+ IterationStrategy :: Slices ( slices) => {
131+ // Copy values using precomputed slices
132+ for & ( start, end) in slices {
133+ self . current . extend_from_slice ( & values[ start..end] ) ;
134+ }
135+ // Copy nulls using slices
136+ if let Some ( nulls) = s. nulls ( ) . filter ( |n| n. null_count ( ) > 0 ) {
137+ for & ( start, end) in slices {
138+ let slice = nulls. slice ( start, end - start) ;
139+ self . nulls . append_buffer ( & slice) ;
140+ }
141+ } else {
142+ self . nulls . append_n_non_nulls ( count) ;
143+ }
144+ }
145+ IterationStrategy :: IndexIterator => {
146+ // Copy values and nulls for each index
147+ if let Some ( nulls) = s. nulls ( ) . filter ( |n| n. null_count ( ) > 0 ) {
148+ for idx in IndexIterator :: new ( filter. filter_array ( ) , count) {
149+ if nulls. is_null ( idx) {
150+ self . nulls . append_null ( ) ;
151+ } else {
152+ self . nulls . append_non_null ( ) ;
153+ }
154+ self . current . push ( values[ idx] ) ;
155+ }
156+ } else {
157+ self . nulls . append_n_non_nulls ( count) ;
158+ for idx in IndexIterator :: new ( filter. filter_array ( ) , count) {
159+ self . current . push ( values[ idx] ) ;
160+ }
161+ }
162+ }
163+ IterationStrategy :: Indices ( indices) => {
164+ // Copy values and nulls using precomputed indices
165+ if let Some ( nulls) = s. nulls ( ) . filter ( |n| n. null_count ( ) > 0 ) {
166+ for & idx in indices {
167+ if nulls. is_null ( idx) {
168+ self . nulls . append_null ( ) ;
169+ } else {
170+ self . nulls . append_non_null ( ) ;
171+ }
172+ }
173+ } else {
174+ self . nulls . append_n_non_nulls ( count) ;
175+ }
176+ self . current . extend ( indices. iter ( ) . map ( |& idx| values[ idx] ) ) ;
177+ }
178+ IterationStrategy :: All => {
179+ // Copy all values
180+ self . current . extend_from_slice ( values) ;
181+ if let Some ( nulls) = s. nulls ( ) {
182+ self . nulls . append_buffer ( nulls) ;
183+ } else {
184+ self . nulls . append_n_non_nulls ( values. len ( ) ) ;
185+ }
186+ }
187+ IterationStrategy :: None => {
188+ // Nothing to copy
189+ }
122190 }
123- self . current
124- . extend ( indices. into_iter ( ) . map ( |idx| values[ * idx] ) ) ;
125191
126192 Ok ( ( ) )
127193 }
0 commit comments