2424import java .util .Iterator ;
2525import java .util .List ;
2626import java .util .Map ;
27+ import java .util .function .BiFunction ;
28+ import java .util .function .Function ;
2729import java .util .function .Supplier ;
2830import org .apache .calcite .rel .type .RelDataType ;
2931import org .apache .calcite .util .ImmutableBitSet ;
@@ -244,13 +246,38 @@ private class Grouping {
244246 /** */
245247 private final RowHandler <Row > handler ;
246248
249+ /** */
250+ private GroupKey .Builder grpKeyBld ;
251+
252+ /** */
253+ private final BiFunction <GroupKey , List <AccumulatorWrapper <Row >>, List <AccumulatorWrapper <Row >>> getOrCreateGroup ;
254+
255+ /** */
256+ private final Function <GroupKey , List <AccumulatorWrapper <Row >>> createGroup ;
257+
247258 /** */
248259 private Grouping (byte grpId , ImmutableBitSet grpFields ) {
249260 this .grpId = grpId ;
250261 this .grpFields = grpFields ;
251262
263+ grpKeyBld = GroupKey .builder (grpFields .cardinality ());
252264 handler = context ().rowHandler ();
253265
266+ createGroup = (k ) -> create ();
267+
268+ getOrCreateGroup = (k , v ) -> {
269+ if (v == null ) {
270+ grpKeyBld = GroupKey .builder (grpFields .cardinality ());
271+
272+ return create ();
273+ }
274+ else {
275+ grpKeyBld .clear ();
276+
277+ return v ;
278+ }
279+ };
280+
254281 init ();
255282 }
256283
@@ -259,7 +286,7 @@ private void init() {
259286 // Initializes aggregates for case when no any rows will be added into the aggregate to have 0 as result.
260287 // Doesn't do it for MAP type due to we don't want send from MAP node zero results because it looks redundant.
261288 if (grpFields .isEmpty () && (type == AggregateType .REDUCE || type == AggregateType .SINGLE ))
262- groups .put (GroupKey .EMPTY_GRP_KEY , create (GroupKey . EMPTY_GRP_KEY ));
289+ groups .put (GroupKey .EMPTY_GRP_KEY , create ());
263290 }
264291
265292 /** */
@@ -293,14 +320,10 @@ else if (type == AggregateType.MAP)
293320
294321 /** */
295322 private void addOnMapper (Row row ) {
296- GroupKey .Builder b = GroupKey .builder (grpFields .cardinality ());
297-
298323 for (Integer field : grpFields )
299- b .add (handler .get (field , row ));
300-
301- GroupKey grpKey = b .build ();
324+ grpKeyBld .add (handler .get (field , row ));
302325
303- List <AccumulatorWrapper <Row >> wrappers = groups .computeIfAbsent ( grpKey , this :: create );
326+ List <AccumulatorWrapper <Row >> wrappers = groups .compute ( grpKeyBld . build (), getOrCreateGroup );
304327
305328 for (AccumulatorWrapper <Row > wrapper : wrappers )
306329 wrapper .add (row );
@@ -315,7 +338,7 @@ private void addOnReducer(Row row) {
315338
316339 GroupKey grpKey = (GroupKey )handler .get (1 , row );
317340
318- List <AccumulatorWrapper <Row >> wrappers = groups .computeIfAbsent (grpKey , this :: create );
341+ List <AccumulatorWrapper <Row >> wrappers = groups .computeIfAbsent (grpKey , createGroup );
319342 Accumulator <Row >[] accums = hasAccumulators () ? (Accumulator <Row >[])handler .get (2 , row ) : null ;
320343
321344 for (int i = 0 ; i < wrappers .size (); i ++) {
@@ -388,7 +411,7 @@ private List<Row> getOnReducer(int cnt) {
388411 }
389412
390413 /** */
391- private List <AccumulatorWrapper <Row >> create (GroupKey key ) {
414+ private List <AccumulatorWrapper <Row >> create () {
392415 if (accFactory == null )
393416 return Collections .emptyList ();
394417
0 commit comments