@@ -92,15 +92,34 @@ protected void doClose() {
92
92
protected LeafBucketCollector getLeafCollector (AggregationExecutionContext aggCtx , LeafBucketCollector sub ) throws IOException {
93
93
return new LeafBucketCollectorBase (sub , null ) {
94
94
95
+ // Keeping track of these fields helps to reduce time spent attempting to add bucket + tsid combos that already were added.
96
+ long currentTsidOrd = -1 ;
97
+ long currentBucket = -1 ;
98
+ long currentBucketOrdinal ;
99
+
95
100
@ Override
96
101
public void collect (int doc , long bucket ) throws IOException {
102
+ // Naively comparing bucket against currentBucket and tsid ord to currentBucket can work really well.
103
+ // TimeSeriesIndexSearcher ensures that docs are emitted in tsid and timestamp order, so if tsid ordinal
104
+ // changes to what is stored in currentTsidOrd then that ordinal well never occur again. Same applies
105
+ // currentBucket if there is no parent aggregation or the immediate parent aggregation creates buckets
106
+ // based on @timestamp field or dimension fields (fields that make up the tsid).
107
+ if (currentBucket == bucket && currentTsidOrd == aggCtx .getTsidOrd ()) {
108
+ collectExistingBucket (sub , doc , currentBucketOrdinal );
109
+ return ;
110
+ }
111
+
97
112
long bucketOrdinal = bucketOrds .add (bucket , aggCtx .getTsid ());
98
113
if (bucketOrdinal < 0 ) { // already seen
99
114
bucketOrdinal = -1 - bucketOrdinal ;
100
115
collectExistingBucket (sub , doc , bucketOrdinal );
101
116
} else {
102
117
collectBucket (sub , doc , bucketOrdinal );
103
118
}
119
+
120
+ currentBucketOrdinal = bucketOrdinal ;
121
+ currentTsidOrd = aggCtx .getTsidOrd ();
122
+ currentBucket = bucket ;
104
123
}
105
124
};
106
125
}
0 commit comments