18
18
import org .elasticsearch .common .io .stream .DelayableWriteable ;
19
19
import org .elasticsearch .common .lucene .search .TopDocsAndMaxScore ;
20
20
import org .elasticsearch .common .util .concurrent .AbstractRunnable ;
21
+ import org .elasticsearch .core .Releasables ;
21
22
import org .elasticsearch .search .SearchPhaseResult ;
22
23
import org .elasticsearch .search .SearchService ;
23
24
import org .elasticsearch .search .SearchShardTarget ;
@@ -174,7 +175,7 @@ public SearchPhaseController.ReducedQueryPhase reduce() throws Exception {
174
175
this .mergeResult = null ;
175
176
final int resultSize = buffer .size () + (mergeResult == null ? 0 : 1 );
176
177
final List <TopDocs > topDocsList = hasTopDocs ? new ArrayList <>(resultSize ) : null ;
177
- final List <DelayableWriteable <InternalAggregations >> aggsList = hasAggs ? new ArrayList <>(resultSize ) : null ;
178
+ List <DelayableWriteable <InternalAggregations >> aggsList = hasAggs ? new ArrayList <>(resultSize ) : null ;
178
179
if (mergeResult != null ) {
179
180
if (topDocsList != null ) {
180
181
topDocsList .add (mergeResult .reducedTopDocs );
@@ -191,29 +192,37 @@ public SearchPhaseController.ReducedQueryPhase reduce() throws Exception {
191
192
topDocsList .add (topDocs .topDocs );
192
193
}
193
194
if (aggsList != null ) {
194
- aggsList .add (result .getAggs ());
195
+ aggsList .add (result .consumeAggs ());
195
196
}
196
197
}
197
198
SearchPhaseController .ReducedQueryPhase reducePhase ;
198
199
long breakerSize = circuitBreakerBytes ;
199
200
try {
201
+ final InternalAggregations aggs ;
200
202
if (aggsList != null ) {
201
203
// Add an estimate of the final reduce size
202
204
breakerSize = addEstimateAndMaybeBreak (estimateRamBytesUsedForReduce (breakerSize ));
205
+ aggs = InternalAggregations .topLevelReduceDelayable (
206
+ aggsList ,
207
+ performFinalReduce ? aggReduceContextBuilder .forFinalReduction () : aggReduceContextBuilder .forPartialReduction ()
208
+ );
209
+ aggsList = null ;
210
+ } else {
211
+ aggs = null ;
203
212
}
204
213
reducePhase = SearchPhaseController .reducedQueryPhase (
205
214
results .asList (),
206
- aggsList ,
215
+ aggs ,
207
216
topDocsList == null ? Collections .emptyList () : topDocsList ,
208
217
topDocsStats ,
209
218
numReducePhases ,
210
219
false ,
211
- aggReduceContextBuilder ,
212
- queryPhaseRankCoordinatorContext ,
213
- performFinalReduce
220
+ queryPhaseRankCoordinatorContext
214
221
);
215
222
} finally {
216
- releaseAggs (buffer );
223
+ if (aggsList != null ) {
224
+ releaseAggs (buffer , aggsList );
225
+ }
217
226
}
218
227
if (hasAggs
219
228
// reduced aggregations can be null if all shards failed
@@ -250,7 +259,7 @@ private MergeResult partialReduce(
250
259
251
260
final TopDocs newTopDocs ;
252
261
final InternalAggregations newAggs ;
253
- final List <DelayableWriteable <InternalAggregations >> aggsList ;
262
+ List <DelayableWriteable <InternalAggregations >> aggsList ;
254
263
final int resultSetSize = toConsume .size () + (lastMerge != null ? 1 : 0 );
255
264
if (hasAggs ) {
256
265
aggsList = new ArrayList <>(resultSetSize );
@@ -275,7 +284,7 @@ private MergeResult partialReduce(
275
284
SearchShardTarget target = result .getSearchShardTarget ();
276
285
processedShards .add (new SearchShard (target .getClusterAlias (), target .getShardId ()));
277
286
if (aggsList != null ) {
278
- aggsList .add (result .getAggs ());
287
+ aggsList .add (result .consumeAggs ());
279
288
}
280
289
if (topDocsList != null ) {
281
290
TopDocsAndMaxScore topDocs = result .consumeTopDocs ();
@@ -285,11 +294,16 @@ private MergeResult partialReduce(
285
294
}
286
295
// we have to merge here in the same way we collect on a shard
287
296
newTopDocs = topDocsList == null ? null : mergeTopDocs (topDocsList , topNSize , 0 );
288
- newAggs = aggsList == null
289
- ? null
290
- : InternalAggregations .topLevelReduceDelayable (aggsList , aggReduceContextBuilder .forPartialReduction ());
297
+ if (aggsList != null ) {
298
+ newAggs = InternalAggregations .topLevelReduceDelayable (aggsList , aggReduceContextBuilder .forPartialReduction ());
299
+ aggsList = null ;
300
+ } else {
301
+ newAggs = null ;
302
+ }
291
303
} finally {
292
- releaseAggs (toConsume );
304
+ if (aggsList != null ) {
305
+ releaseAggs (toConsume , aggsList );
306
+ }
293
307
}
294
308
if (lastMerge != null ) {
295
309
processedShards .addAll (lastMerge .processedShards );
@@ -302,6 +316,11 @@ private MergeResult partialReduce(
302
316
return new MergeResult (processedShards , newTopDocs , newAggs , newAggs != null ? DelayableWriteable .getSerializedSize (newAggs ) : 0 );
303
317
}
304
318
319
+ private static void releaseAggs (List <QuerySearchResult > toConsume , List <DelayableWriteable <InternalAggregations >> aggsList ) {
320
+ releaseAggs (toConsume );
321
+ Releasables .close (aggsList );
322
+ }
323
+
305
324
public int getNumReducePhases () {
306
325
return numReducePhases ;
307
326
}
0 commit comments