@@ -447,9 +447,8 @@ private DfsSearchResult executeDfsPhase(ShardSearchRequest request, SearchShardT
447
447
try (
448
448
Releasable scope = tracer .withScope (task );
449
449
Releasable ignored = readerContext .markAsUsed (getKeepAlive (request ));
450
- SearchContext context = createContext (readerContext , request , task , true )
450
+ SearchContext context = createContext (readerContext , request , task , ResultsType . DFS , false )
451
451
) {
452
- context .addDfsResult ();
453
452
dfsPhase .execute (context );
454
453
return context .dfsResult ();
455
454
} catch (Exception e ) {
@@ -623,15 +622,19 @@ private static <T> void runAsync(Executor executor, CheckedSupplier<T, Exception
623
622
executor .execute (ActionRunnable .supply (listener , executable ::get ));
624
623
}
625
624
625
+ /**
626
+ * The returned {@link SearchPhaseResult} will have had its ref count incremented by this method.
627
+ * It is the responsibility of the caller to ensure that the ref count is correctly decremented
628
+ * when the object is no longer needed.
629
+ */
626
630
private SearchPhaseResult executeQueryPhase (ShardSearchRequest request , SearchShardTask task ) throws Exception {
627
631
final ReaderContext readerContext = createOrGetReaderContext (request );
628
632
try (
629
633
Releasable scope = tracer .withScope (task );
630
634
Releasable ignored = readerContext .markAsUsed (getKeepAlive (request ));
631
- SearchContext context = createContext (readerContext , request , task , true )
635
+ SearchContext context = createContext (readerContext , request , task , ResultsType . QUERY , true )
632
636
) {
633
637
tracer .startTrace ("executeQueryPhase" , Map .of ());
634
- context .addQueryResult ();
635
638
final long afterQueryTime ;
636
639
try (SearchOperationListenerExecutor executor = new SearchOperationListenerExecutor (context )) {
637
640
loadOrExecuteQueryPhase (request , context );
@@ -643,6 +646,7 @@ private SearchPhaseResult executeQueryPhase(ShardSearchRequest request, SearchSh
643
646
tracer .stopTrace ();
644
647
}
645
648
if (request .numberOfShards () == 1 ) {
649
+ // we already have query results, but we can run fetch at the same time
646
650
context .addFetchResult ();
647
651
return executeFetchPhase (readerContext , context , afterQueryTime );
648
652
} else {
@@ -651,6 +655,7 @@ private SearchPhaseResult executeQueryPhase(ShardSearchRequest request, SearchSh
651
655
final RescoreDocIds rescoreDocIds = context .rescoreDocIds ();
652
656
context .queryResult ().setRescoreDocIds (rescoreDocIds );
653
657
readerContext .setRescoreDocIds (rescoreDocIds );
658
+ context .queryResult ().incRef ();
654
659
return context .queryResult ();
655
660
}
656
661
} catch (Exception e ) {
@@ -678,6 +683,7 @@ private QueryFetchSearchResult executeFetchPhase(ReaderContext reader, SearchCon
678
683
}
679
684
executor .success ();
680
685
}
686
+ // This will incRef the QuerySearchResult when it gets created
681
687
return new QueryFetchSearchResult (context .queryResult (), context .fetchResult ());
682
688
}
683
689
@@ -698,15 +704,15 @@ public void executeQueryPhase(
698
704
runAsync (getExecutor (readerContext .indexShard ()), () -> {
699
705
final ShardSearchRequest shardSearchRequest = readerContext .getShardSearchRequest (null );
700
706
try (
701
- SearchContext searchContext = createContext (readerContext , shardSearchRequest , task , false );
707
+ SearchContext searchContext = createContext (readerContext , shardSearchRequest , task , ResultsType . QUERY , false );
702
708
SearchOperationListenerExecutor executor = new SearchOperationListenerExecutor (searchContext )
703
709
) {
704
- searchContext .addQueryResult ();
705
710
searchContext .searcher ().setAggregatedDfs (readerContext .getAggregatedDfs (null ));
706
711
processScroll (request , readerContext , searchContext );
707
712
QueryPhase .execute (searchContext );
708
713
executor .success ();
709
714
readerContext .setRescoreDocIds (searchContext .rescoreDocIds ());
715
+ // ScrollQuerySearchResult will incRef the QuerySearchResult when it gets constructed.
710
716
return new ScrollQuerySearchResult (searchContext .queryResult (), searchContext .shardTarget ());
711
717
} catch (Exception e ) {
712
718
logger .trace ("Query phase failed" , e );
@@ -716,17 +722,21 @@ public void executeQueryPhase(
716
722
}, wrapFailureListener (listener , readerContext , markAsUsed ));
717
723
}
718
724
725
+ /**
726
+ * The returned {@link SearchPhaseResult} will have had its ref count incremented by this method.
727
+ * It is the responsibility of the caller to ensure that the ref count is correctly decremented
728
+ * when the object is no longer needed.
729
+ */
719
730
public void executeQueryPhase (QuerySearchRequest request , SearchShardTask task , ActionListener <QuerySearchResult > listener ) {
720
731
final ReaderContext readerContext = findReaderContext (request .contextId (), request .shardSearchRequest ());
721
732
final ShardSearchRequest shardSearchRequest = readerContext .getShardSearchRequest (request .shardSearchRequest ());
722
733
final Releasable markAsUsed = readerContext .markAsUsed (getKeepAlive (shardSearchRequest ));
723
734
runAsync (getExecutor (readerContext .indexShard ()), () -> {
724
735
readerContext .setAggregatedDfs (request .dfs ());
725
736
try (
726
- SearchContext searchContext = createContext (readerContext , shardSearchRequest , task , true );
737
+ SearchContext searchContext = createContext (readerContext , shardSearchRequest , task , ResultsType . QUERY , true );
727
738
SearchOperationListenerExecutor executor = new SearchOperationListenerExecutor (searchContext )
728
739
) {
729
- searchContext .addQueryResult ();
730
740
searchContext .searcher ().setAggregatedDfs (request .dfs ());
731
741
QueryPhase .execute (searchContext );
732
742
if (searchContext .queryResult ().hasSearchContext () == false && readerContext .singleSession ()) {
@@ -739,6 +749,7 @@ public void executeQueryPhase(QuerySearchRequest request, SearchShardTask task,
739
749
final RescoreDocIds rescoreDocIds = searchContext .rescoreDocIds ();
740
750
searchContext .queryResult ().setRescoreDocIds (rescoreDocIds );
741
751
readerContext .setRescoreDocIds (rescoreDocIds );
752
+ searchContext .queryResult ().incRef ();
742
753
return searchContext .queryResult ();
743
754
} catch (Exception e ) {
744
755
assert TransportActions .isShardNotAvailableException (e ) == false : new AssertionError (e );
@@ -779,10 +790,9 @@ public void executeFetchPhase(
779
790
runAsync (getExecutor (readerContext .indexShard ()), () -> {
780
791
final ShardSearchRequest shardSearchRequest = readerContext .getShardSearchRequest (null );
781
792
try (
782
- SearchContext searchContext = createContext (readerContext , shardSearchRequest , task , false );
793
+ SearchContext searchContext = createContext (readerContext , shardSearchRequest , task , ResultsType . FETCH , false );
783
794
SearchOperationListenerExecutor executor = new SearchOperationListenerExecutor (searchContext )
784
795
) {
785
- searchContext .addFetchResult ();
786
796
searchContext .assignRescoreDocIds (readerContext .getRescoreDocIds (null ));
787
797
searchContext .searcher ().setAggregatedDfs (readerContext .getAggregatedDfs (null ));
788
798
processScroll (request , readerContext , searchContext );
@@ -805,8 +815,7 @@ public void executeFetchPhase(ShardFetchRequest request, SearchShardTask task, A
805
815
final ShardSearchRequest shardSearchRequest = readerContext .getShardSearchRequest (request .getShardSearchRequest ());
806
816
final Releasable markAsUsed = readerContext .markAsUsed (getKeepAlive (shardSearchRequest ));
807
817
runAsync (getExecutor (readerContext .indexShard ()), () -> {
808
- try (SearchContext searchContext = createContext (readerContext , shardSearchRequest , task , false )) {
809
- searchContext .addFetchResult ();
818
+ try (SearchContext searchContext = createContext (readerContext , shardSearchRequest , task , ResultsType .FETCH , false )) {
810
819
if (request .lastEmittedDoc () != null ) {
811
820
searchContext .scrollContext ().lastEmittedDoc = request .lastEmittedDoc ();
812
821
}
@@ -983,10 +992,12 @@ protected SearchContext createContext(
983
992
ReaderContext readerContext ,
984
993
ShardSearchRequest request ,
985
994
SearchShardTask task ,
995
+ ResultsType resultsType ,
986
996
boolean includeAggregations
987
997
) throws IOException {
988
998
checkCancelled (task );
989
999
final DefaultSearchContext context = createSearchContext (readerContext , request , defaultSearchTimeout );
1000
+ resultsType .addResultsObject (context );
990
1001
try {
991
1002
if (request .scroll () != null ) {
992
1003
context .scrollContext ().scroll = request .scroll ();
@@ -1246,7 +1257,7 @@ private void parseSource(DefaultSearchContext context, SearchSourceBuilder sourc
1246
1257
enableRewriteAggsToFilterByFilter ,
1247
1258
source .aggregations ().isInSortOrderExecutionRequired ()
1248
1259
);
1249
- context .addReleasable (aggContext );
1260
+ context .addQuerySearchResultReleasable (aggContext );
1250
1261
try {
1251
1262
AggregatorFactories factories = source .aggregations ().build (aggContext , null );
1252
1263
context .aggregations (new SearchContextAggregations (factories ));
@@ -1447,6 +1458,41 @@ public ResponseCollectorService getResponseCollectorService() {
1447
1458
return this .responseCollectorService ;
1448
1459
}
1449
1460
1461
+ /**
1462
+ * Used to indicate which result object should be instantiated when creating a search context
1463
+ */
1464
+ enum ResultsType {
1465
+ DFS {
1466
+ @ Override
1467
+ void addResultsObject (SearchContext context ) {
1468
+ context .addDfsResult ();
1469
+ }
1470
+ },
1471
+ QUERY {
1472
+ @ Override
1473
+ void addResultsObject (SearchContext context ) {
1474
+ context .addQueryResult ();
1475
+ }
1476
+ },
1477
+ FETCH {
1478
+ @ Override
1479
+ void addResultsObject (SearchContext context ) {
1480
+ context .addFetchResult ();
1481
+ }
1482
+ },
1483
+ /**
1484
+ * None is intended for use in testing, when we might not progress all the way to generating results
1485
+ */
1486
+ NONE {
1487
+ @ Override
1488
+ void addResultsObject (SearchContext context ) {
1489
+ // this space intentionally left blank
1490
+ }
1491
+ };
1492
+
1493
+ abstract void addResultsObject (SearchContext context );
1494
+ }
1495
+
1450
1496
class Reaper implements Runnable {
1451
1497
@ Override
1452
1498
public void run () {
0 commit comments