21
21
22
22
import org .apache .logging .log4j .Logger ;
23
23
import org .apache .logging .log4j .message .ParameterizedMessage ;
24
+ import org .apache .lucene .util .CollectionUtil ;
24
25
import org .apache .lucene .util .SetOnce ;
25
26
import org .elasticsearch .ElasticsearchException ;
26
27
import org .elasticsearch .ExceptionsHelper ;
48
49
49
50
import java .util .ArrayDeque ;
50
51
import java .util .ArrayList ;
51
- import java .util .Collections ;
52
+ import java .util .HashMap ;
52
53
import java .util .List ;
53
54
import java .util .Map ;
54
- import java .util .Set ;
55
55
import java .util .concurrent .ConcurrentHashMap ;
56
56
import java .util .concurrent .Executor ;
57
57
import java .util .concurrent .atomic .AtomicBoolean ;
@@ -83,7 +83,6 @@ abstract class AbstractSearchAsyncAction<Result extends SearchPhaseResult> exten
83
83
private final ClusterState clusterState ;
84
84
private final Map <String , AliasFilter > aliasFilter ;
85
85
private final Map <String , Float > concreteIndexBoosts ;
86
- private final Map <String , Set <String >> indexRoutings ;
87
86
private final SetOnce <AtomicArray <ShardSearchFailure >> shardFailures = new SetOnce <>();
88
87
private final Object shardFailuresMutex = new Object ();
89
88
private final AtomicBoolean hasShardResponse = new AtomicBoolean (false );
@@ -94,6 +93,7 @@ abstract class AbstractSearchAsyncAction<Result extends SearchPhaseResult> exten
94
93
95
94
protected final GroupShardsIterator <SearchShardIterator > toSkipShardsIts ;
96
95
protected final GroupShardsIterator <SearchShardIterator > shardsIts ;
96
+ private final Map <SearchShardIterator , Integer > shardItIndexMap ;
97
97
private final int expectedTotalOps ;
98
98
private final AtomicInteger totalOps = new AtomicInteger ();
99
99
private final int maxConcurrentRequestsPerNode ;
@@ -106,7 +106,6 @@ abstract class AbstractSearchAsyncAction<Result extends SearchPhaseResult> exten
106
106
AbstractSearchAsyncAction (String name , Logger logger , SearchTransportService searchTransportService ,
107
107
BiFunction <String , String , Transport .Connection > nodeIdToConnection ,
108
108
Map <String , AliasFilter > aliasFilter , Map <String , Float > concreteIndexBoosts ,
109
- Map <String , Set <String >> indexRoutings ,
110
109
Executor executor , SearchRequest request ,
111
110
ActionListener <SearchResponse > listener , GroupShardsIterator <SearchShardIterator > shardsIts ,
112
111
SearchTimeProvider timeProvider , ClusterState clusterState ,
@@ -124,6 +123,17 @@ abstract class AbstractSearchAsyncAction<Result extends SearchPhaseResult> exten
124
123
}
125
124
this .toSkipShardsIts = new GroupShardsIterator <>(toSkipIterators );
126
125
this .shardsIts = new GroupShardsIterator <>(iterators );
126
+ this .shardItIndexMap = new HashMap <>();
127
+
128
+ // we compute the shard index based on the natural order of the shards
129
+ // that participate in the search request. This means that this number is
130
+ // consistent between two requests that target the same shards.
131
+ List <SearchShardIterator > naturalOrder = new ArrayList <>(iterators );
132
+ CollectionUtil .timSort (naturalOrder );
133
+ for (int i = 0 ; i < naturalOrder .size (); i ++) {
134
+ shardItIndexMap .put (naturalOrder .get (i ), i );
135
+ }
136
+
127
137
// we need to add 1 for non active partition, since we count it in the total. This means for each shard in the iterator we sum up
128
138
// it's number of active shards but use 1 as the default if no replica of a shard is active at this point.
129
139
// on a per shards level we use shardIt.remaining() to increment the totalOps pointer but add 1 for the current shard result
@@ -143,7 +153,6 @@ abstract class AbstractSearchAsyncAction<Result extends SearchPhaseResult> exten
143
153
this .clusterState = clusterState ;
144
154
this .concreteIndexBoosts = concreteIndexBoosts ;
145
155
this .aliasFilter = aliasFilter ;
146
- this .indexRoutings = indexRoutings ;
147
156
this .results = resultConsumer ;
148
157
this .clusters = clusters ;
149
158
}
@@ -210,10 +219,13 @@ public final void run() {
210
219
throw new SearchPhaseExecutionException (getName (), msg , null , ShardSearchFailure .EMPTY_ARRAY );
211
220
}
212
221
}
213
- for (int index = 0 ; index < shardsIts .size (); index ++) {
214
- final SearchShardIterator shardRoutings = shardsIts .get (index );
222
+
223
+ for (int i = 0 ; i < shardsIts .size (); i ++) {
224
+ final SearchShardIterator shardRoutings = shardsIts .get (i );
215
225
assert shardRoutings .skip () == false ;
216
- performPhaseOnShard (index , shardRoutings , shardRoutings .nextOrNull ());
226
+ assert shardItIndexMap .containsKey (shardRoutings );
227
+ int shardIndex = shardItIndexMap .get (shardRoutings );
228
+ performPhaseOnShard (shardIndex , shardRoutings , shardRoutings .nextOrNull ());
217
229
}
218
230
}
219
231
}
@@ -651,15 +663,12 @@ public final void onFailure(Exception e) {
651
663
}
652
664
653
665
@ Override
654
- public final ShardSearchRequest buildShardSearchRequest (SearchShardIterator shardIt ) {
666
+ public final ShardSearchRequest buildShardSearchRequest (SearchShardIterator shardIt , int shardIndex ) {
655
667
AliasFilter filter = aliasFilter .get (shardIt .shardId ().getIndex ().getUUID ());
656
668
assert filter != null ;
657
669
float indexBoost = concreteIndexBoosts .getOrDefault (shardIt .shardId ().getIndex ().getUUID (), DEFAULT_INDEX_BOOST );
658
- String indexName = shardIt .shardId ().getIndex ().getName ();
659
- final String [] routings = indexRoutings .getOrDefault (indexName , Collections .emptySet ())
660
- .toArray (new String [0 ]);
661
- ShardSearchRequest shardRequest = new ShardSearchRequest (shardIt .getOriginalIndices (), request , shardIt .shardId (), getNumShards (),
662
- filter , indexBoost , timeProvider .getAbsoluteStartMillis (), shardIt .getClusterAlias (), routings ,
670
+ ShardSearchRequest shardRequest = new ShardSearchRequest (shardIt .getOriginalIndices (), request , shardIt .shardId (), shardIndex ,
671
+ getNumShards (), filter , indexBoost , timeProvider .getAbsoluteStartMillis (), shardIt .getClusterAlias (),
663
672
shardIt .getSearchContextId (), shardIt .getSearchContextKeepAlive ());
664
673
// if we already received a search result we can inform the shard that it
665
674
// can return a null response if the request rewrites to match none rather
0 commit comments