@@ -128,21 +128,8 @@ pub struct VectorizedGroupValuesColumn {
128
128
/// a specific list in `group_index_lists`.
129
129
emit_group_index_list_buffer : Vec < usize > ,
130
130
131
- /// Similar as `current_indices`, but `remaining_indices`
132
- /// is used to store the rows will be processed in next round.
133
- scalarized_indices : Vec < usize > ,
134
-
135
- /// The `vectorized_equal_tod` row indices buffer
136
- vectorized_equal_to_row_indices : Vec < usize > ,
137
-
138
- /// The `vectorized_equal_tod` group indices buffer
139
- vectorized_equal_to_group_indices : Vec < usize > ,
140
-
141
- /// The `vectorized_equal_tod` result buffer
142
- vectorized_equal_to_results : Vec < bool > ,
143
-
144
- /// The `vectorized append` row indices buffer
145
- vectorized_append_row_indices : Vec < usize > ,
131
+ /// Buffers for `vectorized_append` and `vectorized_equal_to`
132
+ vectorized_operation_buffers : VectorizedOperationBuffers ,
146
133
147
134
/// The actual group by values, stored column-wise. Compare from
148
135
/// the left to right, each column is stored as [`GroupColumn`].
@@ -161,6 +148,38 @@ pub struct VectorizedGroupValuesColumn {
161
148
random_state : RandomState ,
162
149
}
163
150
151
+ /// Buffers to store intermediate results in `vectorized_append`
152
+ /// and `vectorized_equal_to`, for reducing memory allocation
153
+ #[ derive( Default ) ]
154
+ struct VectorizedOperationBuffers {
155
+ /// The `vectorized append` row indices buffer
156
+ append_row_indices : Vec < usize > ,
157
+
158
+ /// The `vectorized_equal_to` row indices buffer
159
+ equal_to_row_indices : Vec < usize > ,
160
+
161
+ /// The `vectorized_equal_to` group indices buffer
162
+ equal_to_group_indices : Vec < usize > ,
163
+
164
+ /// The `vectorized_equal_to` result buffer
165
+ equal_to_results : Vec < bool > ,
166
+
167
+ /// The buffer for storing row indices found not equal to
168
+ /// exist groups in `group_values` in `vectorized_equal_to`.
169
+ /// We will perform `scalarized_intern` for such rows.
170
+ remaining_row_indices : Vec < usize > ,
171
+ }
172
+
173
+ impl VectorizedOperationBuffers {
174
+ fn clear ( & mut self ) {
175
+ self . append_row_indices . clear ( ) ;
176
+ self . equal_to_row_indices . clear ( ) ;
177
+ self . equal_to_group_indices . clear ( ) ;
178
+ self . equal_to_results . clear ( ) ;
179
+ self . remaining_row_indices . clear ( ) ;
180
+ }
181
+ }
182
+
164
183
impl VectorizedGroupValuesColumn {
165
184
/// Create a new instance of GroupValuesColumn if supported for the specified schema
166
185
pub fn try_new ( schema : SchemaRef ) -> Result < Self > {
@@ -170,15 +189,11 @@ impl VectorizedGroupValuesColumn {
170
189
map,
171
190
group_index_lists : Vec :: new ( ) ,
172
191
emit_group_index_list_buffer : Vec :: new ( ) ,
192
+ vectorized_operation_buffers : VectorizedOperationBuffers :: default ( ) ,
173
193
map_size : 0 ,
174
194
group_values : vec ! [ ] ,
175
195
hashes_buffer : Default :: default ( ) ,
176
196
random_state : Default :: default ( ) ,
177
- scalarized_indices : Default :: default ( ) ,
178
- vectorized_equal_to_row_indices : Default :: default ( ) ,
179
- vectorized_equal_to_group_indices : Default :: default ( ) ,
180
- vectorized_equal_to_results : Default :: default ( ) ,
181
- vectorized_append_row_indices : Default :: default ( ) ,
182
197
} )
183
198
}
184
199
@@ -201,9 +216,13 @@ impl VectorizedGroupValuesColumn {
201
216
batch_hashes : & [ u64 ] ,
202
217
groups : & mut [ usize ] ,
203
218
) {
204
- self . vectorized_append_row_indices . clear ( ) ;
205
- self . vectorized_equal_to_row_indices . clear ( ) ;
206
- self . vectorized_equal_to_group_indices . clear ( ) ;
219
+ self . vectorized_operation_buffers . append_row_indices . clear ( ) ;
220
+ self . vectorized_operation_buffers
221
+ . equal_to_row_indices
222
+ . clear ( ) ;
223
+ self . vectorized_operation_buffers
224
+ . equal_to_group_indices
225
+ . clear ( ) ;
207
226
208
227
let mut group_values_len = self . group_values [ 0 ] . len ( ) ;
209
228
for ( row, & target_hash) in batch_hashes. iter ( ) . enumerate ( ) {
@@ -227,7 +246,9 @@ impl VectorizedGroupValuesColumn {
227
246
) ;
228
247
229
248
// Add row index to `vectorized_append_row_indices`
230
- self . vectorized_append_row_indices . push ( row) ;
249
+ self . vectorized_operation_buffers
250
+ . append_row_indices
251
+ . push ( row) ;
231
252
232
253
// Set group index to row in `groups`
233
254
groups[ row] = current_group_idx;
@@ -245,26 +266,41 @@ impl VectorizedGroupValuesColumn {
245
266
let list_offset = group_index_view. value ( ) as usize ;
246
267
let group_index_list = & self . group_index_lists [ list_offset] ;
247
268
for & group_index in group_index_list {
248
- self . vectorized_equal_to_row_indices . push ( row) ;
249
- self . vectorized_equal_to_group_indices . push ( group_index) ;
269
+ self . vectorized_operation_buffers
270
+ . equal_to_row_indices
271
+ . push ( row) ;
272
+ self . vectorized_operation_buffers
273
+ . equal_to_group_indices
274
+ . push ( group_index) ;
250
275
}
251
276
} else {
252
277
let group_index = group_index_view. value ( ) as usize ;
253
- self . vectorized_equal_to_row_indices . push ( row) ;
254
- self . vectorized_equal_to_group_indices . push ( group_index) ;
278
+ self . vectorized_operation_buffers
279
+ . equal_to_row_indices
280
+ . push ( row) ;
281
+ self . vectorized_operation_buffers
282
+ . equal_to_group_indices
283
+ . push ( group_index) ;
255
284
}
256
285
}
257
286
}
258
287
259
288
/// Perform `vectorized_append`` for `rows` in `vectorized_append_row_indices`
260
289
fn vectorized_append ( & mut self , cols : & [ ArrayRef ] ) {
261
- if self . vectorized_append_row_indices . is_empty ( ) {
290
+ if self
291
+ . vectorized_operation_buffers
292
+ . append_row_indices
293
+ . is_empty ( )
294
+ {
262
295
return ;
263
296
}
264
297
265
298
let iter = self . group_values . iter_mut ( ) . zip ( cols. iter ( ) ) ;
266
299
for ( group_column, col) in iter {
267
- group_column. vectorized_append ( col, & self . vectorized_append_row_indices ) ;
300
+ group_column. vectorized_append (
301
+ col,
302
+ & self . vectorized_operation_buffers . append_row_indices ,
303
+ ) ;
268
304
}
269
305
}
270
306
@@ -283,63 +319,86 @@ impl VectorizedGroupValuesColumn {
283
319
/// are very few.
284
320
fn vectorized_equal_to ( & mut self , cols : & [ ArrayRef ] , groups : & mut [ usize ] ) {
285
321
assert_eq ! (
286
- self . vectorized_equal_to_group_indices. len( ) ,
287
- self . vectorized_equal_to_row_indices. len( )
322
+ self . vectorized_operation_buffers
323
+ . equal_to_group_indices
324
+ . len( ) ,
325
+ self . vectorized_operation_buffers. equal_to_row_indices. len( )
288
326
) ;
289
327
290
- self . scalarized_indices . clear ( ) ;
328
+ self . vectorized_operation_buffers
329
+ . remaining_row_indices
330
+ . clear ( ) ;
291
331
292
- if self . vectorized_equal_to_group_indices . is_empty ( ) {
332
+ if self
333
+ . vectorized_operation_buffers
334
+ . equal_to_group_indices
335
+ . is_empty ( )
336
+ {
293
337
return ;
294
338
}
295
339
296
340
// 1. Perform `vectorized_equal_to` for `rows` in `vectorized_equal_to_group_indices`
297
341
// and `group_indices` in `vectorized_equal_to_group_indices`
298
- let mut equal_to_results = mem:: take ( & mut self . vectorized_equal_to_results ) ;
342
+ let mut equal_to_results =
343
+ mem:: take ( & mut self . vectorized_operation_buffers . equal_to_results ) ;
299
344
equal_to_results. clear ( ) ;
300
- equal_to_results. resize ( self . vectorized_equal_to_group_indices . len ( ) , true ) ;
345
+ equal_to_results. resize (
346
+ self . vectorized_operation_buffers
347
+ . equal_to_group_indices
348
+ . len ( ) ,
349
+ true ,
350
+ ) ;
301
351
302
352
for ( col_idx, group_col) in self . group_values . iter ( ) . enumerate ( ) {
303
353
group_col. vectorized_equal_to (
304
- & self . vectorized_equal_to_group_indices ,
354
+ & self . vectorized_operation_buffers . equal_to_group_indices ,
305
355
& cols[ col_idx] ,
306
- & self . vectorized_equal_to_row_indices ,
356
+ & self . vectorized_operation_buffers . equal_to_row_indices ,
307
357
& mut equal_to_results,
308
358
) ;
309
359
}
310
360
311
361
// 2. Check `equal_to_results`, if found not equal to `row`s, just add them
312
362
// to `scalarized_indices`, and perform `scalarized_intern` for them after.
313
363
let mut current_row_equal_to_result = false ;
314
- for ( idx, & row) in self . vectorized_equal_to_row_indices . iter ( ) . enumerate ( ) {
364
+ for ( idx, & row) in self
365
+ . vectorized_operation_buffers
366
+ . equal_to_row_indices
367
+ . iter ( )
368
+ . enumerate ( )
369
+ {
315
370
let equal_to_result = equal_to_results[ idx] ;
316
371
317
372
// Equal to case, set the `group_indices` to `rows` in `groups`
318
373
if equal_to_result {
319
- groups[ row] = self . vectorized_equal_to_group_indices [ idx] ;
374
+ groups[ row] =
375
+ self . vectorized_operation_buffers . equal_to_group_indices [ idx] ;
320
376
}
321
377
current_row_equal_to_result |= equal_to_result;
322
378
323
379
// Look forward next one row to check if have checked all results
324
380
// of current row
325
381
let next_row = self
326
- . vectorized_equal_to_row_indices
382
+ . vectorized_operation_buffers
383
+ . equal_to_row_indices
327
384
. get ( idx + 1 )
328
385
. unwrap_or ( & usize:: MAX ) ;
329
386
330
387
// Have checked all results of current row, check the total result
331
388
if row != * next_row {
332
389
// Not equal to case, add `row` to `scalarized_indices`
333
390
if !current_row_equal_to_result {
334
- self . scalarized_indices . push ( row) ;
391
+ self . vectorized_operation_buffers
392
+ . remaining_row_indices
393
+ . push ( row) ;
335
394
}
336
395
337
396
// Init the total result for checking next row
338
397
current_row_equal_to_result = false ;
339
398
}
340
399
}
341
400
342
- self . vectorized_equal_to_results = equal_to_results;
401
+ self . vectorized_operation_buffers . equal_to_results = equal_to_results;
343
402
}
344
403
345
404
/// It is possible that some `input rows` have the same
@@ -384,13 +443,17 @@ impl VectorizedGroupValuesColumn {
384
443
batch_hashes : & [ u64 ] ,
385
444
groups : & mut [ usize ] ,
386
445
) {
387
- if self . scalarized_indices . is_empty ( ) {
446
+ if self
447
+ . vectorized_operation_buffers
448
+ . remaining_row_indices
449
+ . is_empty ( )
450
+ {
388
451
return ;
389
452
}
390
453
391
454
let mut map = mem:: take ( & mut self . map ) ;
392
455
393
- for & row in & self . scalarized_indices {
456
+ for & row in & self . vectorized_operation_buffers . remaining_row_indices {
394
457
let target_hash = batch_hashes[ row] ;
395
458
let entry = map. get_mut ( target_hash, |( exist_hash, _) | {
396
459
// Somewhat surprisingly, this closure can be called even if the
@@ -781,11 +844,7 @@ impl GroupValues for VectorizedGroupValuesColumn {
781
844
self . hashes_buffer . shrink_to ( count) ;
782
845
self . group_index_lists . clear ( ) ;
783
846
self . emit_group_index_list_buffer . clear ( ) ;
784
- self . scalarized_indices . clear ( ) ;
785
- self . vectorized_append_row_indices . clear ( ) ;
786
- self . vectorized_equal_to_row_indices . clear ( ) ;
787
- self . vectorized_equal_to_group_indices . clear ( ) ;
788
- self . vectorized_equal_to_results . clear ( ) ;
847
+ self . vectorized_operation_buffers . clear ( ) ;
789
848
}
790
849
}
791
850
0 commit comments