@@ -65,6 +65,57 @@ impl<Method: HashMethodBounds> TransformFinalAggregate<Method> {
65
65
} ,
66
66
) ) )
67
67
}
68
+
69
+ fn transform_agg_hashtable ( & mut self , meta : AggregateMeta < Method , usize > ) -> Result < DataBlock > {
70
+ let mut agg_hashtable: Option < AggregateHashTable > = None ;
71
+ if let AggregateMeta :: Partitioned { bucket : _, data } = meta {
72
+ for bucket_data in data {
73
+ match bucket_data {
74
+ AggregateMeta :: AggregateHashTable ( payload) => match agg_hashtable. as_mut ( ) {
75
+ Some ( ht) => {
76
+ ht. combine_payloads ( & payload, & mut self . flush_state ) ?;
77
+ }
78
+ None => {
79
+ let capacity =
80
+ AggregateHashTable :: get_capacity_for_count ( payload. len ( ) ) ;
81
+
82
+ let mut hashtable = AggregateHashTable :: new_with_capacity (
83
+ self . params . group_data_types . clone ( ) ,
84
+ self . params . aggregate_functions . clone ( ) ,
85
+ HashTableConfig :: default ( ) . with_initial_radix_bits ( 0 ) ,
86
+ capacity,
87
+ ) ;
88
+ hashtable. combine_payloads ( & payload, & mut self . flush_state ) ?;
89
+ agg_hashtable = Some ( hashtable) ;
90
+ }
91
+ } ,
92
+ _ => unreachable ! ( ) ,
93
+ }
94
+ }
95
+ }
96
+
97
+ if let Some ( mut ht) = agg_hashtable {
98
+ let mut blocks = vec ! [ ] ;
99
+ self . flush_state . clear ( ) ;
100
+ loop {
101
+ if ht. merge_result ( & mut self . flush_state ) ? {
102
+ let mut cols = self . flush_state . take_aggregate_results ( ) ;
103
+ cols. extend_from_slice ( & self . flush_state . group_columns ) ;
104
+
105
+ blocks. push ( DataBlock :: new_from_columns ( cols) ) ;
106
+ } else {
107
+ break ;
108
+ }
109
+ }
110
+
111
+ if blocks. is_empty ( ) {
112
+ return Ok ( DataBlock :: empty ( ) ) ;
113
+ }
114
+ return DataBlock :: concat ( & blocks) ;
115
+ }
116
+
117
+ Ok ( DataBlock :: empty ( ) )
118
+ }
68
119
}
69
120
70
121
impl < Method > BlockMetaTransform < AggregateMeta < Method , usize > > for TransformFinalAggregate < Method >
@@ -73,15 +124,17 @@ where Method: HashMethodBounds
73
124
const NAME : & ' static str = "TransformFinalAggregate" ;
74
125
75
126
fn transform ( & mut self , meta : AggregateMeta < Method , usize > ) -> Result < DataBlock > {
127
+ if self . params . enable_experimental_aggregate_hashtable {
128
+ return self . transform_agg_hashtable ( meta) ;
129
+ }
130
+
76
131
if let AggregateMeta :: Partitioned { bucket, data } = meta {
77
132
let mut reach_limit = false ;
78
133
let arena = Arc :: new ( Bump :: new ( ) ) ;
79
134
let hashtable = self . method . create_hash_table :: < usize > ( arena) ?;
80
135
let _dropper = AggregateHashTableDropper :: create ( self . params . clone ( ) ) ;
81
136
let mut hash_cell = HashTableCell :: < Method , usize > :: create ( hashtable, _dropper) ;
82
137
83
- let mut agg_hashtable: Option < AggregateHashTable > = None ;
84
-
85
138
for bucket_data in data {
86
139
match bucket_data {
87
140
AggregateMeta :: Spilled ( _) => unreachable ! ( ) ,
@@ -186,45 +239,8 @@ where Method: HashMethodBounds
186
239
}
187
240
}
188
241
} ,
189
- AggregateMeta :: AggregateHashTable ( payload) => match agg_hashtable. as_mut ( ) {
190
- Some ( ht) => {
191
- ht. combine_payloads ( & payload, & mut self . flush_state ) ?;
192
- }
193
- None => {
194
- let capacity =
195
- AggregateHashTable :: get_capacity_for_count ( payload. len ( ) ) ;
196
-
197
- let mut hashtable = AggregateHashTable :: new_with_capacity (
198
- self . params . group_data_types . clone ( ) ,
199
- self . params . aggregate_functions . clone ( ) ,
200
- HashTableConfig :: default ( ) . with_initial_radix_bits ( 0 ) ,
201
- capacity,
202
- ) ;
203
- hashtable. combine_payloads ( & payload, & mut self . flush_state ) ?;
204
- agg_hashtable = Some ( hashtable) ;
205
- }
206
- } ,
207
- }
208
- }
209
-
210
- if let Some ( mut ht) = agg_hashtable {
211
- let mut blocks = vec ! [ ] ;
212
- self . flush_state . clear ( ) ;
213
- loop {
214
- if ht. merge_result ( & mut self . flush_state ) ? {
215
- let mut cols = self . flush_state . take_aggregate_results ( ) ;
216
- cols. extend_from_slice ( & self . flush_state . group_columns ) ;
217
-
218
- blocks. push ( DataBlock :: new_from_columns ( cols) ) ;
219
- } else {
220
- break ;
221
- }
222
- }
223
-
224
- if blocks. is_empty ( ) {
225
- return Ok ( DataBlock :: empty ( ) ) ;
242
+ AggregateMeta :: AggregateHashTable ( _) => unreachable ! ( ) ,
226
243
}
227
- return DataBlock :: concat ( & blocks) ;
228
244
}
229
245
230
246
let keys_len = hash_cell. hashtable . len ( ) ;
0 commit comments