@@ -113,66 +113,86 @@ impl<T: ArrowPrimitiveType + Debug> InProgressArray for InProgressPrimitiveArray
113113 // Use the predicate's strategy for optimal iteration
114114 match filter. strategy ( ) {
115115 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
116+ // Copy values, nulls using slices
121117 if let Some ( nulls) = s. nulls ( ) . filter ( |n| n. null_count ( ) > 0 ) {
122118 for ( start, end) in SlicesIterator :: new ( filter. filter_array ( ) ) {
119+ // SAFETY: slices are derived from filter predicate
120+ self . current
121+ . extend_from_slice ( unsafe { values. get_unchecked ( start..end) } ) ;
123122 let slice = nulls. slice ( start, end - start) ;
124123 self . nulls . append_buffer ( & slice) ;
125124 }
126125 } else {
126+ for ( start, end) in SlicesIterator :: new ( filter. filter_array ( ) ) {
127+ // SAFETY: SlicesIterator produces valid ranges derived from filter
128+ self . current
129+ . extend_from_slice ( unsafe { values. get_unchecked ( start..end) } ) ;
130+ }
127131 self . nulls . append_n_non_nulls ( count) ;
128132 }
129133 }
130134 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
135+ // Copy values and nulls using precomputed slices - single iteration
136136 if let Some ( nulls) = s. nulls ( ) . filter ( |n| n. null_count ( ) > 0 ) {
137137 for & ( start, end) in slices {
138+ // SAFETY: slices are derived from filter predicate
139+ self . current
140+ . extend_from_slice ( unsafe { values. get_unchecked ( start..end) } ) ;
138141 let slice = nulls. slice ( start, end - start) ;
139142 self . nulls . append_buffer ( & slice) ;
140143 }
141144 } else {
145+ for & ( start, end) in slices {
146+ // SAFETY: slices are derived from filter predicate
147+ self . current
148+ . extend_from_slice ( unsafe { values. get_unchecked ( start..end) } ) ;
149+ }
142150 self . nulls . append_n_non_nulls ( count) ;
143151 }
144152 }
145153 IterationStrategy :: IndexIterator => {
146154 // Copy values and nulls for each index
147155 if let Some ( nulls) = s. nulls ( ) . filter ( |n| n. null_count ( ) > 0 ) {
148- for idx in IndexIterator :: new ( filter. filter_array ( ) , count) {
156+ let indices = IndexIterator :: new ( filter. filter_array ( ) , count) ;
157+ self . current . extend ( indices. map ( |idx : usize | {
149158 if nulls. is_null ( idx) {
150159 self . nulls . append_null ( ) ;
151160 } else {
152161 self . nulls . append_non_null ( ) ;
153162 }
154- self . current . push ( values[ idx] ) ;
155- }
163+ // SAFETY: idx is derived from filter predicate
164+ unsafe { * values. get_unchecked ( idx) }
165+ } ) ) ;
156166 } else {
157167 self . nulls . append_n_non_nulls ( count) ;
158168 let indices = IndexIterator :: new ( filter. filter_array ( ) , count) ;
159- self . current . extend ( indices. map ( |idx| values[ idx] ) ) ;
169+ // SAFETY: indices are derived from filter predicate
170+ self . current
171+ . extend ( indices. map ( |idx : usize | unsafe { * values. get_unchecked ( idx) } ) ) ;
160172 }
161173 }
162174 IterationStrategy :: Indices ( indices) => {
163175 // Copy values and nulls using precomputed indices
164176 if let Some ( nulls) = s. nulls ( ) . filter ( |n| n. null_count ( ) > 0 ) {
165- for & idx in indices {
177+ self . current . extend ( indices. iter ( ) . map ( |& idx| {
178+ // TODO: speed up
166179 if nulls. is_null ( idx) {
167180 self . nulls . append_null ( ) ;
168181 } else {
169182 self . nulls . append_non_null ( ) ;
170183 }
171- }
184+ // SAFETY: indices are derived from filter predicate
185+ unsafe { * values. get_unchecked ( idx) }
186+ } ) ) ;
172187 } else {
173188 self . nulls . append_n_non_nulls ( count) ;
174- }
175- self . current . extend ( indices. iter ( ) . map ( |& idx| values[ idx] ) ) ;
189+ // SAFETY: indices are derived from filter predicate
190+ self . current . extend (
191+ indices
192+ . iter ( )
193+ . map ( |& idx| unsafe { * values. get_unchecked ( idx) } ) ,
194+ )
195+ } ;
176196 }
177197 IterationStrategy :: All => {
178198 // Copy all values
0 commit comments