فهرست منبع

Remove GroupShardsIterator and replace it with plain List (#116891) (#122253)

There is no point in having `GroupShardsIterator`, it's mostly an
unnecessary layer of indirection as it has no state and a single field
only. It's only value could be seen in it hiding the ability to mutate
the list it wraps, but that hardly justifies the overhead on the search
path and extra code complexity. Moreover, the list it references is not
copied/immutable in any way, so the value of hiding is limited also.
Armin Braun 8 ماه پیش
والد
کامیت
697f6a1e1f
40فایلهای تغییر یافته به همراه165 افزوده شده و 449 حذف شده
  1. 2 5
      server/src/internalClusterTest/java/org/elasticsearch/index/shard/RemoveCorruptedShardDataCommandIT.java
  2. 3 6
      server/src/internalClusterTest/java/org/elasticsearch/index/store/CorruptedFileIT.java
  3. 3 3
      server/src/internalClusterTest/java/org/elasticsearch/index/suggest/stats/SuggestStatsIT.java
  4. 2 3
      server/src/internalClusterTest/java/org/elasticsearch/search/stats/SearchStatsIT.java
  5. 2 2
      server/src/main/java/org/elasticsearch/action/admin/cluster/shards/TransportClusterSearchShardsAction.java
  6. 2 8
      server/src/main/java/org/elasticsearch/action/admin/indices/diskusage/TransportAnalyzeIndexDiskUsageAction.java
  7. 1 2
      server/src/main/java/org/elasticsearch/action/admin/indices/validate/query/TransportValidateQueryAction.java
  8. 2 3
      server/src/main/java/org/elasticsearch/action/fieldcaps/RequestDispatcher.java
  9. 10 11
      server/src/main/java/org/elasticsearch/action/search/AbstractSearchAsyncAction.java
  10. 15 24
      server/src/main/java/org/elasticsearch/action/search/CanMatchPreFilterSearchPhase.java
  11. 1 2
      server/src/main/java/org/elasticsearch/action/search/SearchDfsQueryThenFetchAsyncAction.java
  12. 2 2
      server/src/main/java/org/elasticsearch/action/search/SearchPhase.java
  13. 2 4
      server/src/main/java/org/elasticsearch/action/search/SearchProgressListener.java
  14. 2 2
      server/src/main/java/org/elasticsearch/action/search/SearchQueryThenFetchAsyncAction.java
  15. 3 3
      server/src/main/java/org/elasticsearch/action/search/TransportOpenPointInTimeAction.java
  16. 8 7
      server/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java
  17. 9 10
      server/src/main/java/org/elasticsearch/action/search/TransportSearchShardsAction.java
  18. 3 3
      server/src/main/java/org/elasticsearch/action/support/broadcast/TransportBroadcastAction.java
  19. 2 8
      server/src/main/java/org/elasticsearch/action/termvectors/TransportTermVectorsAction.java
  20. 0 60
      server/src/main/java/org/elasticsearch/cluster/routing/GroupShardsIterator.java
  21. 7 3
      server/src/main/java/org/elasticsearch/cluster/routing/OperationRouting.java
  22. 9 6
      server/src/main/java/org/elasticsearch/cluster/routing/RoutingTable.java
  23. 2 3
      server/src/test/java/org/elasticsearch/action/admin/indices/diskusage/TransportAnalyzeIndexDiskUsageActionTests.java
  24. 1 4
      server/src/test/java/org/elasticsearch/action/search/AbstractSearchAsyncActionTests.java
  25. 19 20
      server/src/test/java/org/elasticsearch/action/search/CanMatchPreFilterSearchPhaseTests.java
  26. 1 2
      server/src/test/java/org/elasticsearch/action/search/MockSearchPhaseContext.java
  27. 8 11
      server/src/test/java/org/elasticsearch/action/search/SearchAsyncActionTests.java
  28. 7 11
      server/src/test/java/org/elasticsearch/action/search/SearchQueryThenFetchAsyncActionTests.java
  29. 19 14
      server/src/test/java/org/elasticsearch/action/search/SearchShardIteratorTests.java
  30. 2 4
      server/src/test/java/org/elasticsearch/action/search/TransportSearchActionTests.java
  31. 1 2
      server/src/test/java/org/elasticsearch/cluster/action/shard/ShardFailedClusterStateTaskExecutorTests.java
  32. 0 145
      server/src/test/java/org/elasticsearch/cluster/routing/GroupShardsIteratorTests.java
  33. 4 25
      server/src/test/java/org/elasticsearch/cluster/routing/OperationRoutingTests.java
  34. 3 2
      server/src/test/java/org/elasticsearch/cluster/routing/PlainShardIteratorTests.java
  35. 1 7
      server/src/test/java/org/elasticsearch/cluster/structure/RoutingIteratorTests.java
  36. 1 3
      x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/TransportForgetFollowerAction.java
  37. 1 3
      x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/termsenum/action/TransportTermsEnumAction.java
  38. 3 8
      x-pack/plugin/downsample/src/main/java/org/elasticsearch/xpack/downsample/TransportDownsampleIndexerAction.java
  39. 1 6
      x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/EnrichShardMultiSearchAction.java
  40. 1 2
      x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/enrich/AbstractLookupService.java

+ 2 - 5
server/src/internalClusterTest/java/org/elasticsearch/index/shard/RemoveCorruptedShardDataCommandIT.java

@@ -32,7 +32,6 @@ import org.elasticsearch.cli.ProcessInfo;
 import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.node.DiscoveryNode;
 import org.elasticsearch.cluster.node.DiscoveryNodes;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.routing.ShardIterator;
 import org.elasticsearch.cluster.routing.ShardRouting;
 import org.elasticsearch.cluster.routing.ShardRoutingState;
@@ -531,8 +530,7 @@ public class RemoveCorruptedShardDataCommandIT extends ESIntegTestCase {
             nodeNameToNodeId.put(cursor.getValue().getName(), cursor.getKey());
         }
 
-        final GroupShardsIterator<ShardIterator> shardIterators = state.getRoutingTable()
-            .activePrimaryShardsGrouped(new String[] { indexName }, false);
+        final List<ShardIterator> shardIterators = state.getRoutingTable().activePrimaryShardsGrouped(new String[] { indexName }, false);
         final List<ShardIterator> iterators = iterableAsArrayList(shardIterators);
         final ShardRouting shardRouting = iterators.iterator().next().nextOrNull();
         assertThat(shardRouting, notNullValue());
@@ -571,8 +569,7 @@ public class RemoveCorruptedShardDataCommandIT extends ESIntegTestCase {
 
     private Path getPathToShardData(String indexName, String dirSuffix) {
         ClusterState state = clusterAdmin().prepareState(TEST_REQUEST_TIMEOUT).get().getState();
-        GroupShardsIterator<ShardIterator> shardIterators = state.getRoutingTable()
-            .activePrimaryShardsGrouped(new String[] { indexName }, false);
+        List<ShardIterator> shardIterators = state.getRoutingTable().activePrimaryShardsGrouped(new String[] { indexName }, false);
         List<ShardIterator> iterators = iterableAsArrayList(shardIterators);
         ShardIterator shardIterator = RandomPicks.randomFrom(random(), iterators);
         ShardRouting shardRouting = shardIterator.nextOrNull();

+ 3 - 6
server/src/internalClusterTest/java/org/elasticsearch/index/store/CorruptedFileIT.java

@@ -34,7 +34,6 @@ import org.elasticsearch.cluster.ClusterStateObserver;
 import org.elasticsearch.cluster.health.ClusterHealthStatus;
 import org.elasticsearch.cluster.metadata.IndexMetadata;
 import org.elasticsearch.cluster.node.DiscoveryNode;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.routing.IndexShardRoutingTable;
 import org.elasticsearch.cluster.routing.ShardIterator;
 import org.elasticsearch.cluster.routing.ShardRouting;
@@ -311,8 +310,7 @@ public class CorruptedFileIT extends ESIntegTestCase {
         }
         assertThat(response.getStatus(), is(ClusterHealthStatus.RED));
         ClusterState state = clusterAdmin().prepareState(TEST_REQUEST_TIMEOUT).get().getState();
-        GroupShardsIterator<ShardIterator> shardIterators = state.getRoutingTable()
-            .activePrimaryShardsGrouped(new String[] { "test" }, false);
+        List<ShardIterator> shardIterators = state.getRoutingTable().activePrimaryShardsGrouped(new String[] { "test" }, false);
         for (ShardIterator iterator : shardIterators) {
             ShardRouting routing;
             while ((routing = iterator.nextOrNull()) != null) {
@@ -667,7 +665,7 @@ public class CorruptedFileIT extends ESIntegTestCase {
 
     private int numShards(String... index) {
         ClusterState state = clusterAdmin().prepareState(TEST_REQUEST_TIMEOUT).get().getState();
-        GroupShardsIterator<?> shardIterators = state.getRoutingTable().activePrimaryShardsGrouped(index, false);
+        List<?> shardIterators = state.getRoutingTable().activePrimaryShardsGrouped(index, false);
         return shardIterators.size();
     }
 
@@ -695,8 +693,7 @@ public class CorruptedFileIT extends ESIntegTestCase {
     private ShardRouting corruptRandomPrimaryFile(final boolean includePerCommitFiles) throws IOException {
         ClusterState state = clusterAdmin().prepareState(TEST_REQUEST_TIMEOUT).get().getState();
         Index test = state.metadata().index("test").getIndex();
-        GroupShardsIterator<ShardIterator> shardIterators = state.getRoutingTable()
-            .activePrimaryShardsGrouped(new String[] { "test" }, false);
+        List<ShardIterator> shardIterators = state.getRoutingTable().activePrimaryShardsGrouped(new String[] { "test" }, false);
         List<ShardIterator> iterators = iterableAsArrayList(shardIterators);
         ShardIterator shardIterator = RandomPicks.randomFrom(random(), iterators);
         ShardRouting shardRouting = shardIterator.nextOrNull();

+ 3 - 3
server/src/internalClusterTest/java/org/elasticsearch/index/suggest/stats/SuggestStatsIT.java

@@ -14,7 +14,6 @@ import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsResponse;
 import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse;
 import org.elasticsearch.action.search.SearchRequestBuilder;
 import org.elasticsearch.cluster.ClusterState;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.routing.ShardIterator;
 import org.elasticsearch.cluster.routing.ShardRouting;
 import org.elasticsearch.index.search.stats.SearchStats;
@@ -24,6 +23,7 @@ import org.elasticsearch.search.suggest.term.TermSuggestionBuilder;
 import org.elasticsearch.test.ESIntegTestCase;
 
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
@@ -146,7 +146,7 @@ public class SuggestStatsIT extends ESIntegTestCase {
 
     private Set<String> nodeIdsWithIndex(String... indices) {
         ClusterState state = clusterAdmin().prepareState(TEST_REQUEST_TIMEOUT).get().getState();
-        GroupShardsIterator<ShardIterator> allAssignedShardsGrouped = state.routingTable().allAssignedShardsGrouped(indices, true);
+        List<ShardIterator> allAssignedShardsGrouped = state.routingTable().allAssignedShardsGrouped(indices, true);
         Set<String> nodes = new HashSet<>();
         for (ShardIterator shardIterator : allAssignedShardsGrouped) {
             for (ShardRouting routing : shardIterator) {
@@ -161,7 +161,7 @@ public class SuggestStatsIT extends ESIntegTestCase {
 
     protected int numAssignedShards(String... indices) {
         ClusterState state = clusterAdmin().prepareState(TEST_REQUEST_TIMEOUT).get().getState();
-        GroupShardsIterator<?> allAssignedShardsGrouped = state.routingTable().allAssignedShardsGrouped(indices, true);
+        List<?> allAssignedShardsGrouped = state.routingTable().allAssignedShardsGrouped(indices, true);
         return allAssignedShardsGrouped.size();
     }
 }

+ 2 - 3
server/src/internalClusterTest/java/org/elasticsearch/search/stats/SearchStatsIT.java

@@ -14,7 +14,6 @@ import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsResponse;
 import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse;
 import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.metadata.IndexMetadata;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.routing.ShardIterator;
 import org.elasticsearch.cluster.routing.ShardRouting;
 import org.elasticsearch.common.settings.Settings;
@@ -165,7 +164,7 @@ public class SearchStatsIT extends ESIntegTestCase {
 
     private Set<String> nodeIdsWithIndex(String... indices) {
         ClusterState state = clusterAdmin().prepareState(TEST_REQUEST_TIMEOUT).get().getState();
-        GroupShardsIterator<ShardIterator> allAssignedShardsGrouped = state.routingTable().allAssignedShardsGrouped(indices, true);
+        List<ShardIterator> allAssignedShardsGrouped = state.routingTable().allAssignedShardsGrouped(indices, true);
         Set<String> nodes = new HashSet<>();
         for (ShardIterator shardIterator : allAssignedShardsGrouped) {
             for (ShardRouting routing : shardIterator) {
@@ -248,7 +247,7 @@ public class SearchStatsIT extends ESIntegTestCase {
 
     protected int numAssignedShards(String... indices) {
         ClusterState state = clusterAdmin().prepareState(TEST_REQUEST_TIMEOUT).get().getState();
-        GroupShardsIterator<?> allAssignedShardsGrouped = state.routingTable().allAssignedShardsGrouped(indices, true);
+        List<?> allAssignedShardsGrouped = state.routingTable().allAssignedShardsGrouped(indices, true);
         return allAssignedShardsGrouped.size();
     }
 

+ 2 - 2
server/src/main/java/org/elasticsearch/action/admin/cluster/shards/TransportClusterSearchShardsAction.java

@@ -19,7 +19,6 @@ import org.elasticsearch.cluster.block.ClusterBlockLevel;
 import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
 import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver.ResolvedExpression;
 import org.elasticsearch.cluster.node.DiscoveryNode;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.routing.ShardIterator;
 import org.elasticsearch.cluster.routing.ShardRouting;
 import org.elasticsearch.cluster.service.ClusterService;
@@ -34,6 +33,7 @@ import org.elasticsearch.transport.TransportService;
 
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -101,7 +101,7 @@ public class TransportClusterSearchShardsAction extends TransportMasterNodeReadA
         }
 
         Set<String> nodeIds = new HashSet<>();
-        GroupShardsIterator<ShardIterator> groupShardsIterator = clusterService.operationRouting()
+        List<ShardIterator> groupShardsIterator = clusterService.operationRouting()
             .searchShards(clusterState, concreteIndices, routingMap, request.preference());
         ShardRouting shard;
         ClusterSearchShardsGroup[] groupResponses = new ClusterSearchShardsGroup[groupShardsIterator.size()];

+ 2 - 8
server/src/main/java/org/elasticsearch/action/admin/indices/diskusage/TransportAnalyzeIndexDiskUsageAction.java

@@ -21,7 +21,6 @@ import org.elasticsearch.cluster.block.ClusterBlockException;
 import org.elasticsearch.cluster.block.ClusterBlockLevel;
 import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
 import org.elasticsearch.cluster.node.DiscoveryNode;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.routing.ShardIterator;
 import org.elasticsearch.cluster.routing.ShardRouting;
 import org.elasticsearch.cluster.service.ClusterService;
@@ -214,13 +213,8 @@ public class TransportAnalyzeIndexDiskUsageAction extends TransportBroadcastActi
     }
 
     @Override
-    protected GroupShardsIterator<ShardIterator> shards(
-        ClusterState clusterState,
-        AnalyzeIndexDiskUsageRequest request,
-        String[] concreteIndices
-    ) {
-        final GroupShardsIterator<ShardIterator> groups = clusterService.operationRouting()
-            .searchShards(clusterState, concreteIndices, null, null);
+    protected List<ShardIterator> shards(ClusterState clusterState, AnalyzeIndexDiskUsageRequest request, String[] concreteIndices) {
+        final List<ShardIterator> groups = clusterService.operationRouting().searchShards(clusterState, concreteIndices, null, null);
         for (ShardIterator group : groups) {
             // fails fast if any non-active groups
             if (group.size() == 0) {

+ 1 - 2
server/src/main/java/org/elasticsearch/action/admin/indices/validate/query/TransportValidateQueryAction.java

@@ -22,7 +22,6 @@ import org.elasticsearch.cluster.block.ClusterBlockException;
 import org.elasticsearch.cluster.block.ClusterBlockLevel;
 import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
 import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver.ResolvedExpression;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.routing.ShardIterator;
 import org.elasticsearch.cluster.routing.ShardRouting;
 import org.elasticsearch.cluster.service.ClusterService;
@@ -145,7 +144,7 @@ public class TransportValidateQueryAction extends TransportBroadcastAction<
     }
 
     @Override
-    protected GroupShardsIterator<ShardIterator> shards(ClusterState clusterState, ValidateQueryRequest request, String[] concreteIndices) {
+    protected List<ShardIterator> shards(ClusterState clusterState, ValidateQueryRequest request, String[] concreteIndices) {
         final String routing;
         if (request.allShards()) {
             routing = null;

+ 2 - 3
server/src/main/java/org/elasticsearch/action/fieldcaps/RequestDispatcher.java

@@ -18,7 +18,6 @@ import org.elasticsearch.action.NoShardAvailableActionException;
 import org.elasticsearch.action.OriginalIndices;
 import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.node.DiscoveryNode;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.routing.ShardIterator;
 import org.elasticsearch.cluster.routing.ShardRouting;
 import org.elasticsearch.cluster.service.ClusterService;
@@ -93,7 +92,7 @@ final class RequestDispatcher {
         this.onComplete = new RunOnce(onComplete);
         this.indexSelectors = ConcurrentCollections.newConcurrentMap();
         for (String index : indices) {
-            final GroupShardsIterator<ShardIterator> shardIts;
+            final List<ShardIterator> shardIts;
             try {
                 shardIts = clusterService.operationRouting().searchShards(clusterState, new String[] { index }, null, null);
             } catch (Exception e) {
@@ -250,7 +249,7 @@ final class RequestDispatcher {
         private final Set<ShardId> unmatchedShardIds = new HashSet<>();
         private final Map<ShardId, Exception> failures = new HashMap<>();
 
-        IndexSelector(GroupShardsIterator<ShardIterator> shardIts) {
+        IndexSelector(List<ShardIterator> shardIts) {
             for (ShardIterator shardIt : shardIts) {
                 for (ShardRouting shard : shardIt) {
                     nodeToShards.computeIfAbsent(shard.currentNodeId(), node -> new ArrayList<>()).add(shard);

+ 10 - 11
server/src/main/java/org/elasticsearch/action/search/AbstractSearchAsyncAction.java

@@ -23,7 +23,6 @@ import org.elasticsearch.action.search.TransportSearchAction.SearchTimeProvider;
 import org.elasticsearch.action.support.SubscribableListener;
 import org.elasticsearch.action.support.TransportActions;
 import org.elasticsearch.cluster.ClusterState;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.common.bytes.BytesReference;
 import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
 import org.elasticsearch.common.util.Maps;
@@ -61,9 +60,9 @@ import java.util.stream.Collectors;
 import static org.elasticsearch.core.Strings.format;
 
 /**
- * This is an abstract base class that encapsulates the logic to fan out to all shards in provided {@link GroupShardsIterator}
+ * This is an abstract base class that encapsulates the logic to fan out to all shards in provided {@link List<SearchShardIterator>}
  * and collect the results. If a shard request returns a failure this class handles the advance to the next replica of the shard until
- * the shards replica iterator is exhausted. Each shard is referenced by position in the {@link GroupShardsIterator} which is later
+ * the shards replica iterator is exhausted. Each shard is referenced by position in the {@link List<SearchShardIterator>} which is later
  * referred to as the {@code shardIndex}.
  * The fan out and collect algorithm is traditionally used as the initial phase which can either be a query execution or collection of
  * distributed frequencies
@@ -94,8 +93,8 @@ abstract class AbstractSearchAsyncAction<Result extends SearchPhaseResult> exten
     private final SearchTimeProvider timeProvider;
     private final SearchResponse.Clusters clusters;
 
-    protected final GroupShardsIterator<SearchShardIterator> toSkipShardsIts;
-    protected final GroupShardsIterator<SearchShardIterator> shardsIts;
+    protected final List<SearchShardIterator> toSkipShardsIts;
+    protected final List<SearchShardIterator> shardsIts;
     private final SearchShardIterator[] shardIterators;
     private final AtomicInteger outstandingShards;
     private final int maxConcurrentRequestsPerNode;
@@ -117,7 +116,7 @@ abstract class AbstractSearchAsyncAction<Result extends SearchPhaseResult> exten
         Executor executor,
         SearchRequest request,
         ActionListener<SearchResponse> listener,
-        GroupShardsIterator<SearchShardIterator> shardsIts,
+        List<SearchShardIterator> shardsIts,
         SearchTimeProvider timeProvider,
         ClusterState clusterState,
         SearchTask task,
@@ -136,8 +135,8 @@ abstract class AbstractSearchAsyncAction<Result extends SearchPhaseResult> exten
                 iterators.add(iterator);
             }
         }
-        this.toSkipShardsIts = new GroupShardsIterator<>(toSkipIterators);
-        this.shardsIts = new GroupShardsIterator<>(iterators);
+        this.toSkipShardsIts = toSkipIterators;
+        this.shardsIts = iterators;
         outstandingShards = new AtomicInteger(shardsIts.size());
         this.shardIterators = iterators.toArray(new SearchShardIterator[0]);
         // we later compute the shard index based on the natural order of the shards
@@ -172,8 +171,8 @@ abstract class AbstractSearchAsyncAction<Result extends SearchPhaseResult> exten
         SearchSourceBuilder sourceBuilder
     ) {
         progressListener.notifyListShards(
-            SearchProgressListener.buildSearchShards(this.shardsIts),
-            SearchProgressListener.buildSearchShards(toSkipShardsIts),
+            SearchProgressListener.buildSearchShardsFromIter(this.shardsIts),
+            SearchProgressListener.buildSearchShardsFromIter(toSkipShardsIts),
             clusters,
             sourceBuilder == null || sourceBuilder.size() > 0,
             timeProvider
@@ -257,7 +256,7 @@ abstract class AbstractSearchAsyncAction<Result extends SearchPhaseResult> exten
         successfulShardExecution();
     }
 
-    private boolean checkMinimumVersion(GroupShardsIterator<SearchShardIterator> shardsIts) {
+    private boolean checkMinimumVersion(List<SearchShardIterator> shardsIts) {
         for (SearchShardIterator it : shardsIts) {
             if (it.getTargetNodeIds().isEmpty() == false) {
                 boolean isCompatible = it.getTargetNodeIds().stream().anyMatch(nodeId -> {

+ 15 - 24
server/src/main/java/org/elasticsearch/action/search/CanMatchPreFilterSearchPhase.java

@@ -13,7 +13,6 @@ import org.apache.logging.log4j.Logger;
 import org.apache.lucene.util.FixedBitSet;
 import org.elasticsearch.Version;
 import org.elasticsearch.action.ActionListener;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.common.util.Maps;
 import org.elasticsearch.common.util.concurrent.AbstractRunnable;
 import org.elasticsearch.common.util.concurrent.CountDown;
@@ -63,8 +62,8 @@ final class CanMatchPreFilterSearchPhase extends SearchPhase {
 
     private final Logger logger;
     private final SearchRequest request;
-    private final GroupShardsIterator<SearchShardIterator> shardsIts;
-    private final ActionListener<GroupShardsIterator<SearchShardIterator>> listener;
+    private final List<SearchShardIterator> shardsIts;
+    private final ActionListener<List<SearchShardIterator>> listener;
     private final TransportSearchAction.SearchTimeProvider timeProvider;
     private final BiFunction<String, String, Transport.Connection> nodeIdToConnection;
     private final SearchTransportService searchTransportService;
@@ -86,12 +85,12 @@ final class CanMatchPreFilterSearchPhase extends SearchPhase {
         Map<String, Float> concreteIndexBoosts,
         Executor executor,
         SearchRequest request,
-        GroupShardsIterator<SearchShardIterator> shardsIts,
+        List<SearchShardIterator> shardsIts,
         TransportSearchAction.SearchTimeProvider timeProvider,
         SearchTask task,
         boolean requireAtLeastOneMatch,
         CoordinatorRewriteContextProvider coordinatorRewriteContextProvider,
-        ActionListener<GroupShardsIterator<SearchShardIterator>> listener
+        ActionListener<List<SearchShardIterator>> listener
     ) {
         super("can_match");
         this.logger = logger;
@@ -184,10 +183,9 @@ final class CanMatchPreFilterSearchPhase extends SearchPhase {
         if (matchedShardLevelRequests.isEmpty()) {
             finishPhase();
         } else {
-            GroupShardsIterator<SearchShardIterator> matchingShards = new GroupShardsIterator<>(matchedShardLevelRequests);
             // verify missing shards only for the shards that we hit for the query
-            checkNoMissingShards(matchingShards);
-            new Round(matchingShards).run();
+            checkNoMissingShards(matchedShardLevelRequests);
+            new Round(matchedShardLevelRequests).run();
         }
     }
 
@@ -197,12 +195,12 @@ final class CanMatchPreFilterSearchPhase extends SearchPhase {
         results.consumeResult(result, () -> {});
     }
 
-    private void checkNoMissingShards(GroupShardsIterator<SearchShardIterator> shards) {
+    private void checkNoMissingShards(List<SearchShardIterator> shards) {
         assert assertSearchCoordinationThread();
         doCheckNoMissingShards(getName(), request, shards);
     }
 
-    private Map<SendingTarget, List<SearchShardIterator>> groupByNode(GroupShardsIterator<SearchShardIterator> shards) {
+    private Map<SendingTarget, List<SearchShardIterator>> groupByNode(List<SearchShardIterator> shards) {
         Map<SendingTarget, List<SearchShardIterator>> requests = new HashMap<>();
         for (int i = 0; i < shards.size(); i++) {
             final SearchShardIterator shardRoutings = shards.get(i);
@@ -225,11 +223,11 @@ final class CanMatchPreFilterSearchPhase extends SearchPhase {
      * to retry on other available shard copies.
      */
     class Round extends AbstractRunnable {
-        private final GroupShardsIterator<SearchShardIterator> shards;
+        private final List<SearchShardIterator> shards;
         private final CountDown countDown;
         private final AtomicReferenceArray<Exception> failedResponses;
 
-        Round(GroupShardsIterator<SearchShardIterator> shards) {
+        Round(List<SearchShardIterator> shards) {
             this.shards = shards;
             this.countDown = new CountDown(shards.size());
             this.failedResponses = new AtomicReferenceArray<>(shardsIts.size());
@@ -316,7 +314,7 @@ final class CanMatchPreFilterSearchPhase extends SearchPhase {
                 finishPhase();
             } else {
                 // trigger another round, forcing execution
-                executor.execute(new Round(new GroupShardsIterator<>(remainingShards)) {
+                executor.execute(new Round(remainingShards) {
                     @Override
                     public boolean isForceExecution() {
                         return true;
@@ -380,7 +378,7 @@ final class CanMatchPreFilterSearchPhase extends SearchPhase {
         );
     }
 
-    private boolean checkMinimumVersion(GroupShardsIterator<SearchShardIterator> shardsIts) {
+    private boolean checkMinimumVersion(List<SearchShardIterator> shardsIts) {
         for (SearchShardIterator it : shardsIts) {
             if (it.getTargetNodeIds().isEmpty() == false) {
                 boolean isCompatible = it.getTargetNodeIds().stream().anyMatch(nodeId -> {
@@ -495,10 +493,7 @@ final class CanMatchPreFilterSearchPhase extends SearchPhase {
         public void close() {}
     }
 
-    private GroupShardsIterator<SearchShardIterator> getIterator(
-        CanMatchSearchPhaseResults results,
-        GroupShardsIterator<SearchShardIterator> shardsIts
-    ) {
+    private List<SearchShardIterator> getIterator(CanMatchSearchPhaseResults results, List<SearchShardIterator> shardsIts) {
         FixedBitSet possibleMatches = results.getPossibleMatches();
         // TODO: pick the local shard when possible
         if (requireAtLeastOneMatch && results.getNumPossibleMatches() == 0) {
@@ -532,14 +527,10 @@ final class CanMatchPreFilterSearchPhase extends SearchPhase {
             return shardsIts;
         }
         FieldSortBuilder fieldSort = FieldSortBuilder.getPrimaryFieldSortOrNull(request.source());
-        return new GroupShardsIterator<>(sortShards(shardsIts, results.minAndMaxes, fieldSort.order()));
+        return sortShards(shardsIts, results.minAndMaxes, fieldSort.order());
     }
 
-    private static List<SearchShardIterator> sortShards(
-        GroupShardsIterator<SearchShardIterator> shardsIts,
-        MinAndMax<?>[] minAndMaxes,
-        SortOrder order
-    ) {
+    private static List<SearchShardIterator> sortShards(List<SearchShardIterator> shardsIts, MinAndMax<?>[] minAndMaxes, SortOrder order) {
         int bound = shardsIts.size();
         List<Integer> toSort = new ArrayList<>(bound);
         for (int i = 0; i < bound; i++) {

+ 1 - 2
server/src/main/java/org/elasticsearch/action/search/SearchDfsQueryThenFetchAsyncAction.java

@@ -20,7 +20,6 @@ import org.apache.lucene.util.SetOnce;
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.client.internal.Client;
 import org.elasticsearch.cluster.ClusterState;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
 import org.elasticsearch.search.SearchPhaseResult;
 import org.elasticsearch.search.SearchShardTarget;
@@ -56,7 +55,7 @@ final class SearchDfsQueryThenFetchAsyncAction extends AbstractSearchAsyncAction
         SearchPhaseResults<SearchPhaseResult> queryPhaseResultConsumer,
         SearchRequest request,
         ActionListener<SearchResponse> listener,
-        GroupShardsIterator<SearchShardIterator> shardsIts,
+        List<SearchShardIterator> shardsIts,
         TransportSearchAction.SearchTimeProvider timeProvider,
         ClusterState clusterState,
         SearchTask task,

+ 2 - 2
server/src/main/java/org/elasticsearch/action/search/SearchPhase.java

@@ -8,7 +8,6 @@
  */
 package org.elasticsearch.action.search;
 
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.core.CheckedRunnable;
 import org.elasticsearch.search.SearchPhaseResult;
 import org.elasticsearch.search.SearchShardTarget;
@@ -16,6 +15,7 @@ import org.elasticsearch.transport.Transport;
 
 import java.io.IOException;
 import java.io.UncheckedIOException;
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -49,7 +49,7 @@ abstract class SearchPhase implements CheckedRunnable<IOException> {
             + "]. Consider using `allow_partial_search_results` setting to bypass this error.";
     }
 
-    protected void doCheckNoMissingShards(String phaseName, SearchRequest request, GroupShardsIterator<SearchShardIterator> shardsIts) {
+    protected void doCheckNoMissingShards(String phaseName, SearchRequest request, List<SearchShardIterator> shardsIts) {
         assert request.allowPartialSearchResults() != null : "SearchRequest missing setting for allowPartialSearchResults";
         if (request.allowPartialSearchResults() == false) {
             final StringBuilder missingShards = new StringBuilder();

+ 2 - 4
server/src/main/java/org/elasticsearch/action/search/SearchProgressListener.java

@@ -13,7 +13,6 @@ import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.lucene.search.TotalHits;
 import org.elasticsearch.action.search.SearchResponse.Clusters;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.search.SearchPhaseResult;
 import org.elasticsearch.search.SearchShardTarget;
 import org.elasticsearch.search.aggregations.InternalAggregations;
@@ -21,7 +20,6 @@ import org.elasticsearch.search.query.QuerySearchResult;
 
 import java.util.List;
 import java.util.Objects;
-import java.util.stream.StreamSupport;
 
 /**
  * A listener that allows to track progress of the {@link TransportSearchAction}.
@@ -225,7 +223,7 @@ public abstract class SearchProgressListener {
             .toList();
     }
 
-    static List<SearchShard> buildSearchShards(GroupShardsIterator<SearchShardIterator> its) {
-        return StreamSupport.stream(its.spliterator(), false).map(e -> new SearchShard(e.getClusterAlias(), e.shardId())).toList();
+    static List<SearchShard> buildSearchShardsFromIter(List<SearchShardIterator> its) {
+        return its.stream().map(e -> new SearchShard(e.getClusterAlias(), e.shardId())).toList();
     }
 }

+ 2 - 2
server/src/main/java/org/elasticsearch/action/search/SearchQueryThenFetchAsyncAction.java

@@ -14,7 +14,6 @@ import org.apache.lucene.search.TopFieldDocs;
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.client.internal.Client;
 import org.elasticsearch.cluster.ClusterState;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
 import org.elasticsearch.search.SearchPhaseResult;
 import org.elasticsearch.search.SearchShardTarget;
@@ -25,6 +24,7 @@ import org.elasticsearch.search.internal.ShardSearchRequest;
 import org.elasticsearch.search.query.QuerySearchResult;
 import org.elasticsearch.transport.Transport;
 
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Executor;
 import java.util.function.BiFunction;
@@ -52,7 +52,7 @@ class SearchQueryThenFetchAsyncAction extends AbstractSearchAsyncAction<SearchPh
         SearchPhaseResults<SearchPhaseResult> resultConsumer,
         SearchRequest request,
         ActionListener<SearchResponse> listener,
-        GroupShardsIterator<SearchShardIterator> shardsIts,
+        List<SearchShardIterator> shardsIts,
         TransportSearchAction.SearchTimeProvider timeProvider,
         ClusterState clusterState,
         SearchTask task,

+ 3 - 3
server/src/main/java/org/elasticsearch/action/search/TransportOpenPointInTimeAction.java

@@ -23,7 +23,6 @@ import org.elasticsearch.action.support.ChannelActionListener;
 import org.elasticsearch.action.support.HandledTransportAction;
 import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.cluster.ClusterState;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.service.ClusterService;
 import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
 import org.elasticsearch.common.io.stream.StreamInput;
@@ -49,6 +48,7 @@ import org.elasticsearch.transport.TransportResponseHandler;
 import org.elasticsearch.transport.TransportService;
 
 import java.io.IOException;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Executor;
 import java.util.function.BiFunction;
@@ -150,7 +150,7 @@ public class TransportOpenPointInTimeAction extends HandledTransportAction<OpenP
             SearchTask task,
             SearchRequest searchRequest,
             Executor executor,
-            GroupShardsIterator<SearchShardIterator> shardIterators,
+            List<SearchShardIterator> shardIterators,
             TransportSearchAction.SearchTimeProvider timeProvider,
             BiFunction<String, String, Transport.Connection> connectionLookup,
             ClusterState clusterState,
@@ -212,7 +212,7 @@ public class TransportOpenPointInTimeAction extends HandledTransportAction<OpenP
             SearchTask task,
             SearchRequest searchRequest,
             Executor executor,
-            GroupShardsIterator<SearchShardIterator> shardIterators,
+            List<SearchShardIterator> shardIterators,
             TransportSearchAction.SearchTimeProvider timeProvider,
             BiFunction<String, String, Transport.Connection> connectionLookup,
             ClusterState clusterState,

+ 8 - 7
server/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java

@@ -11,6 +11,7 @@ package org.elasticsearch.action.search;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
+import org.apache.lucene.util.CollectionUtil;
 import org.elasticsearch.ExceptionsHelper;
 import org.elasticsearch.TransportVersions;
 import org.elasticsearch.action.ActionListener;
@@ -40,7 +41,6 @@ import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
 import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver.ResolvedExpression;
 import org.elasticsearch.cluster.node.DiscoveryNode;
 import org.elasticsearch.cluster.node.DiscoveryNodes;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.routing.OperationRouting;
 import org.elasticsearch.cluster.routing.ShardIterator;
 import org.elasticsearch.cluster.routing.ShardRouting;
@@ -1286,7 +1286,7 @@ public class TransportSearchAction extends HandledTransportAction<SearchRequest,
                 );
             }
         }
-        final GroupShardsIterator<SearchShardIterator> shardIterators = mergeShardsIterators(localShardIterators, remoteShardIterators);
+        final List<SearchShardIterator> shardIterators = mergeShardsIterators(localShardIterators, remoteShardIterators);
 
         failIfOverShardCountLimit(clusterService, shardIterators.size());
 
@@ -1420,7 +1420,7 @@ public class TransportSearchAction extends HandledTransportAction<SearchRequest,
     }
 
     // package private for testing
-    static GroupShardsIterator<SearchShardIterator> mergeShardsIterators(
+    static List<SearchShardIterator> mergeShardsIterators(
         List<SearchShardIterator> localShardIterators,
         List<SearchShardIterator> remoteShardIterators
     ) {
@@ -1430,7 +1430,8 @@ public class TransportSearchAction extends HandledTransportAction<SearchRequest,
         } else {
             shards = CollectionUtils.concatLists(remoteShardIterators, localShardIterators);
         }
-        return GroupShardsIterator.sortAndCreate(shards);
+        CollectionUtil.timSort(shards);
+        return shards;
     }
 
     interface SearchPhaseProvider {
@@ -1438,7 +1439,7 @@ public class TransportSearchAction extends HandledTransportAction<SearchRequest,
             SearchTask task,
             SearchRequest searchRequest,
             Executor executor,
-            GroupShardsIterator<SearchShardIterator> shardIterators,
+            List<SearchShardIterator> shardIterators,
             SearchTimeProvider timeProvider,
             BiFunction<String, String, Transport.Connection> connectionLookup,
             ClusterState clusterState,
@@ -1462,7 +1463,7 @@ public class TransportSearchAction extends HandledTransportAction<SearchRequest,
             SearchTask task,
             SearchRequest searchRequest,
             Executor executor,
-            GroupShardsIterator<SearchShardIterator> shardIterators,
+            List<SearchShardIterator> shardIterators,
             SearchTimeProvider timeProvider,
             BiFunction<String, String, Transport.Connection> connectionLookup,
             ClusterState clusterState,
@@ -1854,7 +1855,7 @@ public class TransportSearchAction extends HandledTransportAction<SearchRequest,
         String[] concreteIndices
     ) {
         var routingMap = indexNameExpressionResolver.resolveSearchRouting(clusterState, searchRequest.routing(), searchRequest.indices());
-        GroupShardsIterator<ShardIterator> shardRoutings = clusterService.operationRouting()
+        List<ShardIterator> shardRoutings = clusterService.operationRouting()
             .searchShards(
                 clusterState,
                 concreteIndices,

+ 9 - 10
server/src/main/java/org/elasticsearch/action/search/TransportSearchShardsAction.java

@@ -9,6 +9,7 @@
 
 package org.elasticsearch.action.search;
 
+import org.apache.lucene.util.CollectionUtil;
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.action.ActionType;
 import org.elasticsearch.action.RemoteClusterActionType;
@@ -18,7 +19,6 @@ import org.elasticsearch.action.support.HandledTransportAction;
 import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
 import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver.ResolvedExpression;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.service.ClusterService;
 import org.elasticsearch.index.Index;
 import org.elasticsearch.index.query.Rewriteable;
@@ -138,15 +138,14 @@ public class TransportSearchShardsAction extends HandledTransportAction<SearchSh
                     concreteIndices
                 );
                 String[] concreteIndexNames = Arrays.stream(concreteIndices).map(Index::getName).toArray(String[]::new);
-                GroupShardsIterator<SearchShardIterator> shardIts = GroupShardsIterator.sortAndCreate(
-                    transportSearchAction.getLocalShardsIterator(
-                        clusterState,
-                        searchRequest,
-                        searchShardsRequest.clusterAlias(),
-                        indicesAndAliases,
-                        concreteIndexNames
-                    )
+                List<SearchShardIterator> shardIts = transportSearchAction.getLocalShardsIterator(
+                    clusterState,
+                    searchRequest,
+                    searchShardsRequest.clusterAlias(),
+                    indicesAndAliases,
+                    concreteIndexNames
                 );
+                CollectionUtil.timSort(shardIts);
                 if (SearchService.canRewriteToMatchNone(searchRequest.source()) == false) {
                     delegate.onResponse(new SearchShardsResponse(toGroups(shardIts), clusterState.nodes().getAllNodes(), aliasFilters));
                 } else {
@@ -171,7 +170,7 @@ public class TransportSearchShardsAction extends HandledTransportAction<SearchSh
         );
     }
 
-    private static List<SearchShardsGroup> toGroups(GroupShardsIterator<SearchShardIterator> shardIts) {
+    private static List<SearchShardsGroup> toGroups(List<SearchShardIterator> shardIts) {
         List<SearchShardsGroup> groups = new ArrayList<>(shardIts.size());
         for (SearchShardIterator shardIt : shardIts) {
             boolean skip = shardIt.skip();

+ 3 - 3
server/src/main/java/org/elasticsearch/action/support/broadcast/TransportBroadcastAction.java

@@ -22,7 +22,6 @@ import org.elasticsearch.cluster.block.ClusterBlockException;
 import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
 import org.elasticsearch.cluster.node.DiscoveryNode;
 import org.elasticsearch.cluster.node.DiscoveryNodes;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.routing.ShardIterator;
 import org.elasticsearch.cluster.routing.ShardRouting;
 import org.elasticsearch.cluster.service.ClusterService;
@@ -35,6 +34,7 @@ import org.elasticsearch.transport.TransportService;
 import org.elasticsearch.transport.Transports;
 
 import java.io.IOException;
+import java.util.List;
 import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReferenceArray;
@@ -108,7 +108,7 @@ public abstract class TransportBroadcastAction<
      * Determines the shards this operation will be executed on. The operation is executed once per shard iterator, typically
      * on the first shard in it. If the operation fails, it will be retried on the next shard in the iterator.
      */
-    protected abstract GroupShardsIterator<ShardIterator> shards(ClusterState clusterState, Request request, String[] concreteIndices);
+    protected abstract List<ShardIterator> shards(ClusterState clusterState, Request request, String[] concreteIndices);
 
     protected abstract ClusterBlockException checkGlobalBlock(ClusterState state, Request request);
 
@@ -121,7 +121,7 @@ public abstract class TransportBroadcastAction<
         final ActionListener<Response> listener;
         final ClusterState clusterState;
         final DiscoveryNodes nodes;
-        final GroupShardsIterator<ShardIterator> shardsIts;
+        final List<ShardIterator> shardsIts;
         final int expectedOps;
         final AtomicInteger counterOps = new AtomicInteger();
         // ShardResponse or Exception

+ 2 - 8
server/src/main/java/org/elasticsearch/action/termvectors/TransportTermVectorsAction.java

@@ -14,7 +14,6 @@ import org.elasticsearch.action.support.ActionFilters;
 import org.elasticsearch.action.support.single.shard.TransportSingleShardAction;
 import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.routing.ShardIterator;
 import org.elasticsearch.cluster.service.ClusterService;
 import org.elasticsearch.common.io.stream.Writeable;
@@ -65,13 +64,8 @@ public class TransportTermVectorsAction extends TransportSingleShardAction<TermV
         final var operationRouting = clusterService.operationRouting();
         if (request.request().doc() != null && request.request().routing() == null) {
             // artificial document without routing specified, ignore its "id" and use either random shard or according to preference
-            GroupShardsIterator<ShardIterator> groupShardsIter = operationRouting.searchShards(
-                state,
-                new String[] { request.concreteIndex() },
-                null,
-                request.request().preference()
-            );
-            return groupShardsIter.iterator().next();
+            return operationRouting.searchShards(state, new String[] { request.concreteIndex() }, null, request.request().preference())
+                .get(0);
         }
 
         return operationRouting.useOnlyPromotableShardsForStateless(

+ 0 - 60
server/src/main/java/org/elasticsearch/cluster/routing/GroupShardsIterator.java

@@ -1,60 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the "Elastic License
- * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
- * Public License v 1"; you may not use this file except in compliance with, at
- * your election, the "Elastic License 2.0", the "GNU Affero General Public
- * License v3.0 only", or the "Server Side Public License, v 1".
- */
-
-package org.elasticsearch.cluster.routing;
-
-import org.apache.lucene.util.CollectionUtil;
-import org.elasticsearch.common.util.Countable;
-
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * This class implements a compilation of {@link ShardIterator}s. Each {@link ShardIterator}
- * iterated by this {@link Iterable} represents a group of shards.
- * ShardsIterators are always returned in ascending order independently of their order at construction
- * time. The incoming iterators are sorted to ensure consistent iteration behavior across Nodes / JVMs.
-*/
-public final class GroupShardsIterator<ShardIt extends Comparable<ShardIt> & Countable> implements Iterable<ShardIt> {
-
-    private final List<ShardIt> iterators;
-
-    /**
-     * Constructs a new sorted GroupShardsIterator from the given list. Items are sorted based on their natural ordering.
-     * @see PlainShardIterator#compareTo(ShardIterator)
-     */
-    public static <ShardIt extends Comparable<ShardIt> & Countable> GroupShardsIterator<ShardIt> sortAndCreate(List<ShardIt> iterators) {
-        CollectionUtil.timSort(iterators);
-        return new GroupShardsIterator<>(iterators);
-    }
-
-    /**
-     * Constructs a new GroupShardsIterator from the given list.
-     */
-    public GroupShardsIterator(List<ShardIt> iterators) {
-        this.iterators = iterators;
-    }
-
-    /**
-     * Return the number of groups
-     * @return number of groups
-     */
-    public int size() {
-        return iterators.size();
-    }
-
-    @Override
-    public Iterator<ShardIt> iterator() {
-        return iterators.iterator();
-    }
-
-    public ShardIt get(int index) {
-        return iterators.get(index);
-    }
-}

+ 7 - 3
server/src/main/java/org/elasticsearch/cluster/routing/OperationRouting.java

@@ -9,6 +9,7 @@
 
 package org.elasticsearch.cluster.routing;
 
+import org.apache.lucene.util.CollectionUtil;
 import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.metadata.IndexMetadata;
 import org.elasticsearch.cluster.node.DiscoveryNode;
@@ -27,6 +28,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -95,7 +97,7 @@ public class OperationRouting {
         }
     }
 
-    public GroupShardsIterator<ShardIterator> searchShards(
+    public List<ShardIterator> searchShards(
         ClusterState clusterState,
         String[] concreteIndices,
         @Nullable Map<String, Set<String>> routing,
@@ -104,7 +106,7 @@ public class OperationRouting {
         return searchShards(clusterState, concreteIndices, routing, preference, null, null);
     }
 
-    public GroupShardsIterator<ShardIterator> searchShards(
+    public List<ShardIterator> searchShards(
         ClusterState clusterState,
         String[] concreteIndices,
         @Nullable Map<String, Set<String>> routing,
@@ -127,7 +129,9 @@ public class OperationRouting {
                 set.add(PlainShardIterator.allSearchableShards(iterator));
             }
         }
-        return GroupShardsIterator.sortAndCreate(new ArrayList<>(set));
+        var res = new ArrayList<>(set);
+        CollectionUtil.timSort(res);
+        return res;
     }
 
     public static ShardIterator getShards(ClusterState clusterState, ShardId shardId) {

+ 9 - 6
server/src/main/java/org/elasticsearch/cluster/routing/RoutingTable.java

@@ -9,6 +9,7 @@
 
 package org.elasticsearch.cluster.routing;
 
+import org.apache.lucene.util.CollectionUtil;
 import org.elasticsearch.TransportVersions;
 import org.elasticsearch.cluster.Diff;
 import org.elasticsearch.cluster.Diffable;
@@ -194,7 +195,7 @@ public class RoutingTable implements Iterable<IndexRoutingTable>, Diffable<Routi
      *
      * @param includeEmpty             if true, a shard iterator will be added for non-assigned shards as well
      */
-    public GroupShardsIterator<ShardIterator> allActiveShardsGrouped(String[] indices, boolean includeEmpty) {
+    public List<ShardIterator> allActiveShardsGrouped(String[] indices, boolean includeEmpty) {
         return allSatisfyingPredicateShardsGrouped(indices, includeEmpty, ShardRouting::active);
     }
 
@@ -203,11 +204,11 @@ public class RoutingTable implements Iterable<IndexRoutingTable>, Diffable<Routi
      *
      * @param includeEmpty if true, a shard iterator will be added for non-assigned shards as well
      */
-    public GroupShardsIterator<ShardIterator> allAssignedShardsGrouped(String[] indices, boolean includeEmpty) {
+    public List<ShardIterator> allAssignedShardsGrouped(String[] indices, boolean includeEmpty) {
         return allSatisfyingPredicateShardsGrouped(indices, includeEmpty, ShardRouting::assignedToNode);
     }
 
-    private GroupShardsIterator<ShardIterator> allSatisfyingPredicateShardsGrouped(
+    private List<ShardIterator> allSatisfyingPredicateShardsGrouped(
         String[] indices,
         boolean includeEmpty,
         Predicate<ShardRouting> predicate
@@ -232,7 +233,8 @@ public class RoutingTable implements Iterable<IndexRoutingTable>, Diffable<Routi
                 }
             }
         }
-        return GroupShardsIterator.sortAndCreate(set);
+        CollectionUtil.timSort(set);
+        return set;
     }
 
     public ShardsIterator allShards(String[] indices) {
@@ -285,7 +287,7 @@ public class RoutingTable implements Iterable<IndexRoutingTable>, Diffable<Routi
      * @return All the primary shards grouped into a single shard element group each
      * @throws IndexNotFoundException If an index passed does not exists
      */
-    public GroupShardsIterator<ShardIterator> activePrimaryShardsGrouped(String[] indices, boolean includeEmpty) {
+    public List<ShardIterator> activePrimaryShardsGrouped(String[] indices, boolean includeEmpty) {
         // use list here since we need to maintain identity across shards
         ArrayList<ShardIterator> set = new ArrayList<>();
         for (String index : indices) {
@@ -303,7 +305,8 @@ public class RoutingTable implements Iterable<IndexRoutingTable>, Diffable<Routi
                 }
             }
         }
-        return GroupShardsIterator.sortAndCreate(set);
+        CollectionUtil.timSort(set);
+        return set;
     }
 
     @Override

+ 2 - 3
server/src/test/java/org/elasticsearch/action/admin/indices/diskusage/TransportAnalyzeIndexDiskUsageActionTests.java

@@ -18,7 +18,6 @@ import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
 import org.elasticsearch.cluster.node.DiscoveryNode;
 import org.elasticsearch.cluster.node.DiscoveryNodeUtils;
 import org.elasticsearch.cluster.node.DiscoveryNodes;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.routing.PlainShardIterator;
 import org.elasticsearch.cluster.routing.ShardIterator;
 import org.elasticsearch.cluster.routing.ShardRouting;
@@ -299,7 +298,7 @@ public class TransportAnalyzeIndexDiskUsageActionTests extends ESTestCase {
             }
         ) {
             @Override
-            protected GroupShardsIterator<ShardIterator> shards(
+            protected List<ShardIterator> shards(
                 ClusterState clusterState,
                 AnalyzeIndexDiskUsageRequest request,
                 String[] concreteIndices
@@ -308,7 +307,7 @@ public class TransportAnalyzeIndexDiskUsageActionTests extends ESTestCase {
                 for (Map.Entry<ShardId, List<ShardRouting>> e : targetShards.entrySet()) {
                     shardIterators.add(new PlainShardIterator(e.getKey(), e.getValue()));
                 }
-                return new GroupShardsIterator<>(shardIterators);
+                return shardIterators;
             }
         };
     }

+ 1 - 4
server/src/test/java/org/elasticsearch/action/search/AbstractSearchAsyncActionTests.java

@@ -13,7 +13,6 @@ import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.action.OriginalIndices;
 import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.cluster.ClusterState;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.common.UUIDs;
 import org.elasticsearch.core.Tuple;
 import org.elasticsearch.index.Index;
@@ -83,9 +82,7 @@ public class AbstractSearchAsyncActionTests extends ESTestCase {
             null,
             request,
             listener,
-            new GroupShardsIterator<>(
-                Collections.singletonList(new SearchShardIterator(null, new ShardId("index", "_na", 0), Collections.emptyList(), null))
-            ),
+            Collections.singletonList(new SearchShardIterator(null, new ShardId("index", "_na", 0), Collections.emptyList(), null)),
             timeProvider,
             ClusterState.EMPTY_STATE,
             null,

+ 19 - 20
server/src/test/java/org/elasticsearch/action/search/CanMatchPreFilterSearchPhaseTests.java

@@ -10,6 +10,7 @@
 package org.elasticsearch.action.search;
 
 import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.CollectionUtil;
 import org.elasticsearch.TransportVersion;
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.action.OriginalIndices;
@@ -23,7 +24,6 @@ import org.elasticsearch.cluster.metadata.IndexMetadata;
 import org.elasticsearch.cluster.metadata.Metadata;
 import org.elasticsearch.cluster.node.DiscoveryNode;
 import org.elasticsearch.cluster.node.DiscoveryNodeUtils;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.routing.allocation.DataTier;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.UUIDs;
@@ -136,9 +136,9 @@ public class CanMatchPreFilterSearchPhaseTests extends ESTestCase {
             }
         };
 
-        AtomicReference<GroupShardsIterator<SearchShardIterator>> result = new AtomicReference<>();
+        AtomicReference<List<SearchShardIterator>> result = new AtomicReference<>();
         CountDownLatch latch = new CountDownLatch(1);
-        GroupShardsIterator<SearchShardIterator> shardsIter = getShardsIter(
+        List<SearchShardIterator> shardsIter = getShardsIter(
             "idx",
             new OriginalIndices(new String[] { "idx" }, SearchRequest.DEFAULT_INDICES_OPTIONS),
             2,
@@ -233,9 +233,9 @@ public class CanMatchPreFilterSearchPhaseTests extends ESTestCase {
             }
         };
 
-        AtomicReference<GroupShardsIterator<SearchShardIterator>> result = new AtomicReference<>();
+        AtomicReference<List<SearchShardIterator>> result = new AtomicReference<>();
         CountDownLatch latch = new CountDownLatch(1);
-        GroupShardsIterator<SearchShardIterator> shardsIter = getShardsIter(
+        List<SearchShardIterator> shardsIter = getShardsIter(
             "idx",
             new OriginalIndices(new String[] { "idx" }, SearchRequest.DEFAULT_INDICES_OPTIONS),
             2,
@@ -326,9 +326,9 @@ public class CanMatchPreFilterSearchPhaseTests extends ESTestCase {
                 }
             };
 
-            AtomicReference<GroupShardsIterator<SearchShardIterator>> result = new AtomicReference<>();
+            AtomicReference<List<SearchShardIterator>> result = new AtomicReference<>();
             CountDownLatch latch = new CountDownLatch(1);
-            GroupShardsIterator<SearchShardIterator> shardsIter = getShardsIter(
+            List<SearchShardIterator> shardsIter = getShardsIter(
                 "logs",
                 new OriginalIndices(new String[] { "logs" }, SearchRequest.DEFAULT_INDICES_OPTIONS),
                 randomIntBetween(2, 20),
@@ -428,9 +428,9 @@ public class CanMatchPreFilterSearchPhaseTests extends ESTestCase {
                 }
             };
 
-            AtomicReference<GroupShardsIterator<SearchShardIterator>> result = new AtomicReference<>();
+            AtomicReference<List<SearchShardIterator>> result = new AtomicReference<>();
             CountDownLatch latch = new CountDownLatch(1);
-            GroupShardsIterator<SearchShardIterator> shardsIter = getShardsIter(
+            List<SearchShardIterator> shardsIter = getShardsIter(
                 "logs",
                 new OriginalIndices(new String[] { "logs" }, SearchRequest.DEFAULT_INDICES_OPTIONS),
                 numShards,
@@ -1203,7 +1203,7 @@ public class CanMatchPreFilterSearchPhaseTests extends ESTestCase {
                 false,
                 new ActionListener<>() {
                     @Override
-                    public void onResponse(GroupShardsIterator<SearchShardIterator> searchShardIterators) {
+                    public void onResponse(List<SearchShardIterator> searchShardIterators) {
                         fail(null, "unexpected success with result [%s] while expecting to handle failure with [%s]", searchShardIterators);
                         latch.countDown();
                     }
@@ -1269,7 +1269,7 @@ public class CanMatchPreFilterSearchPhaseTests extends ESTestCase {
         boolean allowPartialResults,
         BiConsumer<List<SearchShardIterator>, List<ShardSearchRequest>> canMatchResultsConsumer
     ) throws Exception {
-        AtomicReference<GroupShardsIterator<SearchShardIterator>> result = new AtomicReference<>();
+        AtomicReference<List<SearchShardIterator>> result = new AtomicReference<>();
         CountDownLatch latch = new CountDownLatch(1);
         Tuple<CanMatchPreFilterSearchPhase, List<ShardSearchRequest>> canMatchAndShardRequests = getCanMatchPhaseAndRequests(
             dataStreams,
@@ -1306,7 +1306,7 @@ public class CanMatchPreFilterSearchPhaseTests extends ESTestCase {
         SuggestBuilder suggest,
         List<Index> unassignedIndices,
         boolean allowPartialResults,
-        ActionListener<GroupShardsIterator<SearchShardIterator>> canMatchActionListener
+        ActionListener<List<SearchShardIterator>> canMatchActionListener
     ) {
         Map<String, Transport.Connection> lookup = new ConcurrentHashMap<>();
         DiscoveryNode primaryNode = DiscoveryNodeUtils.create("node_1");
@@ -1325,7 +1325,7 @@ public class CanMatchPreFilterSearchPhaseTests extends ESTestCase {
         String[] indices = indicesToSearch.toArray(new String[0]);
         OriginalIndices originalIndices = new OriginalIndices(indices, SearchRequest.DEFAULT_INDICES_OPTIONS);
 
-        final List<SearchShardIterator> originalShardIters = new ArrayList<>();
+        final List<SearchShardIterator> shardIters = new ArrayList<>();
         for (var dataStream : dataStreams) {
             boolean atLeastOnePrimaryAssigned = false;
             for (var dataStreamIndex : dataStream.getIndices()) {
@@ -1334,9 +1334,9 @@ public class CanMatchPreFilterSearchPhaseTests extends ESTestCase {
                 boolean withAssignedPrimaries = randomBoolean() || atLeastOnePrimaryAssigned == false;
                 int numShards = randomIntBetween(1, 6);
                 if (unassignedIndices.contains(dataStreamIndex)) {
-                    originalShardIters.addAll(getShardsIter(dataStreamIndex, originalIndices, numShards, false, null, null));
+                    shardIters.addAll(getShardsIter(dataStreamIndex, originalIndices, numShards, false, null, null));
                 } else {
-                    originalShardIters.addAll(
+                    shardIters.addAll(
                         getShardsIter(dataStreamIndex, originalIndices, numShards, false, withAssignedPrimaries ? primaryNode : null, null)
                     );
                     atLeastOnePrimaryAssigned |= withAssignedPrimaries;
@@ -1346,14 +1346,14 @@ public class CanMatchPreFilterSearchPhaseTests extends ESTestCase {
 
         for (Index regularIndex : regularIndices) {
             if (unassignedIndices.contains(regularIndex)) {
-                originalShardIters.addAll(getShardsIter(regularIndex, originalIndices, randomIntBetween(1, 6), false, null, null));
+                shardIters.addAll(getShardsIter(regularIndex, originalIndices, randomIntBetween(1, 6), false, null, null));
             } else {
-                originalShardIters.addAll(
+                shardIters.addAll(
                     getShardsIter(regularIndex, originalIndices, randomIntBetween(1, 6), randomBoolean(), primaryNode, replicaNode)
                 );
             }
         }
-        GroupShardsIterator<SearchShardIterator> shardsIter = GroupShardsIterator.sortAndCreate(originalShardIters);
+        CollectionUtil.timSort(shardIters);
 
         final SearchRequest searchRequest = new SearchRequest();
         searchRequest.indices(indices);
@@ -1416,7 +1416,6 @@ public class CanMatchPreFilterSearchPhaseTests extends ESTestCase {
             System::nanoTime
         );
 
-        AtomicReference<GroupShardsIterator<SearchShardIterator>> result = new AtomicReference<>();
         return new Tuple<>(
             new CanMatchPreFilterSearchPhase(
                 logger,
@@ -1426,7 +1425,7 @@ public class CanMatchPreFilterSearchPhaseTests extends ESTestCase {
                 Collections.emptyMap(),
                 threadPool.executor(ThreadPool.Names.SEARCH_COORDINATION),
                 searchRequest,
-                shardsIter,
+                shardIters,
                 timeProvider,
                 null,
                 true,

+ 1 - 2
server/src/test/java/org/elasticsearch/action/search/MockSearchPhaseContext.java

@@ -13,7 +13,6 @@ import org.apache.logging.log4j.Logger;
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.action.OriginalIndices;
 import org.elasticsearch.cluster.ClusterState;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.common.bytes.BytesArray;
 import org.elasticsearch.common.bytes.BytesReference;
 import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
@@ -62,7 +61,7 @@ public final class MockSearchPhaseContext extends AbstractSearchAsyncAction<Sear
             Runnable::run,
             new SearchRequest(),
             ActionListener.noop(),
-            new GroupShardsIterator<SearchShardIterator>(List.of()),
+            List.of(),
             null,
             ClusterState.EMPTY_STATE,
             new SearchTask(0, "n/a", "n/a", () -> "test", null, Collections.emptyMap()),

+ 8 - 11
server/src/test/java/org/elasticsearch/action/search/SearchAsyncActionTests.java

@@ -15,7 +15,6 @@ import org.elasticsearch.action.support.ActionTestUtils;
 import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.node.DiscoveryNode;
 import org.elasticsearch.cluster.node.DiscoveryNodeUtils;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.routing.RecoverySource;
 import org.elasticsearch.cluster.routing.ShardRouting;
 import org.elasticsearch.cluster.routing.UnassignedInfo;
@@ -67,7 +66,7 @@ public class SearchAsyncActionTests extends ESTestCase {
         DiscoveryNode replicaNode = DiscoveryNodeUtils.create("node_2");
 
         AtomicInteger contextIdGenerator = new AtomicInteger(0);
-        GroupShardsIterator<SearchShardIterator> shardsIter = getShardsIter(
+        List<SearchShardIterator> shardsIter = getShardsIter(
             "idx",
             new OriginalIndices(new String[] { "idx" }, SearchRequest.DEFAULT_INDICES_OPTIONS),
             numShards,
@@ -182,7 +181,7 @@ public class SearchAsyncActionTests extends ESTestCase {
         DiscoveryNode replicaNode = DiscoveryNodeUtils.create("node_1");
 
         AtomicInteger contextIdGenerator = new AtomicInteger(0);
-        GroupShardsIterator<SearchShardIterator> shardsIter = getShardsIter(
+        List<SearchShardIterator> shardsIter = getShardsIter(
             "idx",
             new OriginalIndices(new String[] { "idx" }, SearchRequest.DEFAULT_INDICES_OPTIONS),
             numShards,
@@ -285,7 +284,7 @@ public class SearchAsyncActionTests extends ESTestCase {
         Map<DiscoveryNode, Set<ShardSearchContextId>> nodeToContextMap = newConcurrentMap();
         AtomicInteger contextIdGenerator = new AtomicInteger(0);
         int numShards = randomIntBetween(1, 10);
-        GroupShardsIterator<SearchShardIterator> shardsIter = getShardsIter(
+        List<SearchShardIterator> shardsIter = getShardsIter(
             "idx",
             new OriginalIndices(new String[] { "idx" }, SearchRequest.DEFAULT_INDICES_OPTIONS),
             numShards,
@@ -415,7 +414,7 @@ public class SearchAsyncActionTests extends ESTestCase {
         Map<DiscoveryNode, Set<ShardSearchContextId>> nodeToContextMap = newConcurrentMap();
         AtomicInteger contextIdGenerator = new AtomicInteger(0);
         int numShards = randomIntBetween(2, 10);
-        GroupShardsIterator<SearchShardIterator> shardsIter = getShardsIter(
+        List<SearchShardIterator> shardsIter = getShardsIter(
             "idx",
             new OriginalIndices(new String[] { "idx" }, SearchRequest.DEFAULT_INDICES_OPTIONS),
             numShards,
@@ -534,7 +533,7 @@ public class SearchAsyncActionTests extends ESTestCase {
         DiscoveryNode replicaNode = DiscoveryNodeUtils.create("node_1");
 
         AtomicInteger contextIdGenerator = new AtomicInteger(0);
-        GroupShardsIterator<SearchShardIterator> shardsIter = getShardsIter(
+        List<SearchShardIterator> shardsIter = getShardsIter(
             "idx",
             new OriginalIndices(new String[] { "idx" }, SearchRequest.DEFAULT_INDICES_OPTIONS),
             numShards,
@@ -647,7 +646,7 @@ public class SearchAsyncActionTests extends ESTestCase {
             searchShardIterator.reset();
             searchShardIterators.add(searchShardIterator);
         }
-        GroupShardsIterator<SearchShardIterator> shardsIter = new GroupShardsIterator<>(searchShardIterators);
+        List<SearchShardIterator> shardsIter = searchShardIterators;
         Map<String, Transport.Connection> lookup = Map.of(primaryNode.getId(), new MockConnection(primaryNode));
 
         CountDownLatch latch = new CountDownLatch(1);
@@ -706,7 +705,7 @@ public class SearchAsyncActionTests extends ESTestCase {
         assertThat(searchResponse.get().getSuccessfulShards(), equalTo(shardsIter.size()));
     }
 
-    static GroupShardsIterator<SearchShardIterator> getShardsIter(
+    static List<SearchShardIterator> getShardsIter(
         String index,
         OriginalIndices originalIndices,
         int numShards,
@@ -714,9 +713,7 @@ public class SearchAsyncActionTests extends ESTestCase {
         DiscoveryNode primaryNode,
         DiscoveryNode replicaNode
     ) {
-        return new GroupShardsIterator<>(
-            getShardsIter(new Index(index, "_na_"), originalIndices, numShards, doReplicas, primaryNode, replicaNode)
-        );
+        return getShardsIter(new Index(index, "_na_"), originalIndices, numShards, doReplicas, primaryNode, replicaNode);
     }
 
     static List<SearchShardIterator> getShardsIter(

+ 7 - 11
server/src/test/java/org/elasticsearch/action/search/SearchQueryThenFetchAsyncActionTests.java

@@ -21,7 +21,6 @@ import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.node.DiscoveryNode;
 import org.elasticsearch.cluster.node.DiscoveryNodeUtils;
 import org.elasticsearch.cluster.node.VersionInformation;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.routing.RecoverySource;
 import org.elasticsearch.cluster.routing.ShardRouting;
 import org.elasticsearch.cluster.routing.UnassignedInfo;
@@ -165,7 +164,7 @@ public class SearchQueryThenFetchAsyncActionTests extends ESTestCase {
             }
         };
         CountDownLatch latch = new CountDownLatch(1);
-        GroupShardsIterator<SearchShardIterator> shardsIter = SearchAsyncActionTests.getShardsIter(
+        List<SearchShardIterator> shardsIter = SearchAsyncActionTests.getShardsIter(
             "idx",
             new OriginalIndices(new String[] { "idx" }, SearchRequest.DEFAULT_INDICES_OPTIONS),
             numShards,
@@ -332,7 +331,6 @@ public class SearchQueryThenFetchAsyncActionTests extends ESTestCase {
         routingOldVersionShard.started();
         list.add(new SearchShardIterator(null, new ShardId(new Index("idx", "_na_"), 1), singletonList(routingOldVersionShard), idx));
 
-        GroupShardsIterator<SearchShardIterator> shardsIter = new GroupShardsIterator<>(list);
         final SearchRequest searchRequest = new SearchRequest(minVersion);
         searchRequest.setMaxConcurrentShardRequests(numConcurrent);
         searchRequest.setBatchedReduceSize(2);
@@ -350,7 +348,7 @@ public class SearchQueryThenFetchAsyncActionTests extends ESTestCase {
                 controller,
                 task::isCancelled,
                 task.getProgressListener(),
-                shardsIter.size(),
+                list.size(),
                 exc -> {}
             )
         ) {
@@ -376,7 +374,7 @@ public class SearchQueryThenFetchAsyncActionTests extends ESTestCase {
                     }
 
                 },
-                shardsIter,
+                list,
                 timeProvider,
                 new ClusterState.Builder(new ClusterName("test")).build(),
                 task,
@@ -446,7 +444,6 @@ public class SearchQueryThenFetchAsyncActionTests extends ESTestCase {
         routingOldVersionShard.started();
         list.add(new SearchShardIterator(null, new ShardId(new Index("idx", "_na_"), 1), singletonList(routingOldVersionShard), idx));
 
-        GroupShardsIterator<SearchShardIterator> shardsIter = new GroupShardsIterator<>(list);
         final SearchRequest searchRequest = new SearchRequest(minVersion);
         searchRequest.allowPartialSearchResults(false);
         searchRequest.source(new SearchSourceBuilder().size(1).sort(SortBuilders.fieldSort("timestamp")));
@@ -512,7 +509,7 @@ public class SearchQueryThenFetchAsyncActionTests extends ESTestCase {
                 controller,
                 task::isCancelled,
                 task.getProgressListener(),
-                shardsIter.size(),
+                list.size(),
                 exc -> {}
             )
         ) {
@@ -528,7 +525,7 @@ public class SearchQueryThenFetchAsyncActionTests extends ESTestCase {
                 resultConsumer,
                 searchRequest,
                 null,
-                shardsIter,
+                list,
                 timeProvider,
                 new ClusterState.Builder(new ClusterName("test")).build(),
                 task,
@@ -609,7 +606,6 @@ public class SearchQueryThenFetchAsyncActionTests extends ESTestCase {
         routingNewVersionShard2.started();
         list.add(new SearchShardIterator(null, new ShardId(new Index("idx", "_na_"), 1), singletonList(routingNewVersionShard2), idx));
 
-        GroupShardsIterator<SearchShardIterator> shardsIter = new GroupShardsIterator<>(list);
         final SearchRequest searchRequest = new SearchRequest(minVersion);
         searchRequest.allowPartialSearchResults(false);
         searchRequest.source(new SearchSourceBuilder().size(1).sort(SortBuilders.fieldSort("timestamp")));
@@ -677,7 +673,7 @@ public class SearchQueryThenFetchAsyncActionTests extends ESTestCase {
                 controller,
                 task::isCancelled,
                 task.getProgressListener(),
-                shardsIter.size(),
+                list.size(),
                 exc -> {}
             )
         ) {
@@ -692,7 +688,7 @@ public class SearchQueryThenFetchAsyncActionTests extends ESTestCase {
                 resultConsumer,
                 searchRequest,
                 null,
-                shardsIter,
+                list,
                 timeProvider,
                 new ClusterState.Builder(new ClusterName("test")).build(),
                 task,

+ 19 - 14
server/src/test/java/org/elasticsearch/action/search/SearchShardIteratorTests.java

@@ -12,7 +12,8 @@ package org.elasticsearch.action.search;
 import org.elasticsearch.action.OriginalIndices;
 import org.elasticsearch.action.OriginalIndicesTests;
 import org.elasticsearch.action.support.IndicesOptions;
-import org.elasticsearch.cluster.routing.GroupShardsIteratorTests;
+import org.elasticsearch.cluster.routing.ShardRouting;
+import org.elasticsearch.cluster.routing.TestShardRouting;
 import org.elasticsearch.index.shard.ShardId;
 import org.elasticsearch.search.SearchShardTarget;
 import org.elasticsearch.test.ESTestCase;
@@ -24,10 +25,24 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
+import static org.elasticsearch.cluster.routing.ShardRoutingState.STARTED;
 import static org.hamcrest.Matchers.equalTo;
 
 public class SearchShardIteratorTests extends ESTestCase {
 
+    public static List<ShardRouting> randomShardRoutings(ShardId shardId) {
+        return randomShardRoutings(shardId, randomIntBetween(0, 2));
+    }
+
+    private static List<ShardRouting> randomShardRoutings(ShardId shardId, int numReplicas) {
+        List<ShardRouting> shardRoutings = new ArrayList<>();
+        shardRoutings.add(TestShardRouting.newShardRouting(shardId, randomAlphaOfLengthBetween(5, 10), true, STARTED));
+        for (int j = 0; j < numReplicas; j++) {
+            shardRoutings.add(TestShardRouting.newShardRouting(shardId, randomAlphaOfLengthBetween(5, 10), false, STARTED));
+        }
+        return shardRoutings;
+    }
+
     public void testShardId() {
         ShardId shardId = new ShardId(randomAlphaOfLengthBetween(5, 10), randomAlphaOfLength(10), randomInt());
         SearchShardIterator searchShardIterator = new SearchShardIterator(null, shardId, Collections.emptyList(), OriginalIndices.NONE);
@@ -149,19 +164,14 @@ public class SearchShardIteratorTests extends ESTestCase {
                 for (String uuid : uuids) {
                     ShardId shardId = new ShardId(index, uuid, i);
                     shardIterators.add(
-                        new SearchShardIterator(
-                            null,
-                            shardId,
-                            GroupShardsIteratorTests.randomShardRoutings(shardId),
-                            OriginalIndicesTests.randomOriginalIndices()
-                        )
+                        new SearchShardIterator(null, shardId, randomShardRoutings(shardId), OriginalIndicesTests.randomOriginalIndices())
                     );
                     for (String cluster : clusters) {
                         shardIterators.add(
                             new SearchShardIterator(
                                 cluster,
                                 shardId,
-                                GroupShardsIteratorTests.randomShardRoutings(shardId),
+                                randomShardRoutings(shardId),
                                 OriginalIndicesTests.randomOriginalIndices()
                             )
                         );
@@ -207,11 +217,6 @@ public class SearchShardIteratorTests extends ESTestCase {
     private static SearchShardIterator randomSearchShardIterator() {
         String clusterAlias = randomBoolean() ? null : randomAlphaOfLengthBetween(5, 10);
         ShardId shardId = new ShardId(randomAlphaOfLengthBetween(5, 10), randomAlphaOfLength(10), randomIntBetween(0, Integer.MAX_VALUE));
-        return new SearchShardIterator(
-            clusterAlias,
-            shardId,
-            GroupShardsIteratorTests.randomShardRoutings(shardId),
-            OriginalIndicesTests.randomOriginalIndices()
-        );
+        return new SearchShardIterator(clusterAlias, shardId, randomShardRoutings(shardId), OriginalIndicesTests.randomOriginalIndices());
     }
 }

+ 2 - 4
server/src/test/java/org/elasticsearch/action/search/TransportSearchActionTests.java

@@ -37,8 +37,6 @@ import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
 import org.elasticsearch.cluster.node.DiscoveryNode;
 import org.elasticsearch.cluster.node.DiscoveryNodeUtils;
 import org.elasticsearch.cluster.node.VersionInformation;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
-import org.elasticsearch.cluster.routing.GroupShardsIteratorTests;
 import org.elasticsearch.cluster.routing.IndexRoutingTable;
 import org.elasticsearch.cluster.routing.ShardRouting;
 import org.elasticsearch.cluster.routing.ShardRoutingState;
@@ -152,7 +150,7 @@ public class TransportSearchActionTests extends ESTestCase {
         String clusterAlias
     ) {
         ShardId shardId = new ShardId(index, id);
-        List<ShardRouting> shardRoutings = GroupShardsIteratorTests.randomShardRoutings(shardId);
+        List<ShardRouting> shardRoutings = SearchShardIteratorTests.randomShardRoutings(shardId);
         return new SearchShardIterator(clusterAlias, shardId, shardRoutings, originalIndices);
     }
 
@@ -251,7 +249,7 @@ public class TransportSearchActionTests extends ESTestCase {
         Collections.shuffle(localShardIterators, random());
         Collections.shuffle(remoteShardIterators, random());
 
-        GroupShardsIterator<SearchShardIterator> groupShardsIterator = TransportSearchAction.mergeShardsIterators(
+        List<SearchShardIterator> groupShardsIterator = TransportSearchAction.mergeShardsIterators(
             localShardIterators,
             remoteShardIterators
         );

+ 1 - 2
server/src/test/java/org/elasticsearch/cluster/action/shard/ShardFailedClusterStateTaskExecutorTests.java

@@ -21,7 +21,6 @@ import org.elasticsearch.cluster.action.shard.ShardStateAction.FailedShardUpdate
 import org.elasticsearch.cluster.metadata.IndexMetadata;
 import org.elasticsearch.cluster.metadata.Metadata;
 import org.elasticsearch.cluster.node.DiscoveryNodes;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.routing.IndexShardRoutingTable;
 import org.elasticsearch.cluster.routing.RoutingNodesHelper;
 import org.elasticsearch.cluster.routing.RoutingTable;
@@ -237,7 +236,7 @@ public class ShardFailedClusterStateTaskExecutorTests extends ESAllocationTestCa
 
     private List<FailedShardUpdateTask> createExistingShards(ClusterState currentState, String reason) {
         List<ShardRouting> shards = new ArrayList<>();
-        GroupShardsIterator<ShardIterator> shardGroups = currentState.routingTable().allAssignedShardsGrouped(new String[] { INDEX }, true);
+        List<ShardIterator> shardGroups = currentState.routingTable().allAssignedShardsGrouped(new String[] { INDEX }, true);
         for (ShardIterator shardIt : shardGroups) {
             for (ShardRouting shard : shardIt) {
                 shards.add(shard);

+ 0 - 145
server/src/test/java/org/elasticsearch/cluster/routing/GroupShardsIteratorTests.java

@@ -1,145 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the "Elastic License
- * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
- * Public License v 1"; you may not use this file except in compliance with, at
- * your election, the "Elastic License 2.0", the "GNU Affero General Public
- * License v3.0 only", or the "Server Side Public License, v 1".
- */
-
-package org.elasticsearch.cluster.routing;
-
-import org.apache.lucene.util.CollectionUtil;
-import org.elasticsearch.action.OriginalIndicesTests;
-import org.elasticsearch.action.search.SearchShardIterator;
-import org.elasticsearch.index.Index;
-import org.elasticsearch.index.shard.ShardId;
-import org.elasticsearch.test.ESTestCase;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import static org.elasticsearch.cluster.routing.ShardRoutingState.STARTED;
-
-public class GroupShardsIteratorTests extends ESTestCase {
-
-    public static List<ShardRouting> randomShardRoutings(ShardId shardId) {
-        return randomShardRoutings(shardId, randomIntBetween(0, 2));
-    }
-
-    private static List<ShardRouting> randomShardRoutings(ShardId shardId, int numReplicas) {
-        List<ShardRouting> shardRoutings = new ArrayList<>();
-        shardRoutings.add(TestShardRouting.newShardRouting(shardId, randomAlphaOfLengthBetween(5, 10), true, STARTED));
-        for (int j = 0; j < numReplicas; j++) {
-            shardRoutings.add(TestShardRouting.newShardRouting(shardId, randomAlphaOfLengthBetween(5, 10), false, STARTED));
-        }
-        return shardRoutings;
-    }
-
-    public void testIterate() {
-        List<ShardIterator> list = new ArrayList<>();
-        Index index = new Index("foo", "na");
-        {
-            ShardId shardId = new ShardId(index, 0);
-            list.add(new PlainShardIterator(shardId, randomShardRoutings(shardId)));
-        }
-        list.add(new PlainShardIterator(new ShardId(index, 1), Collections.emptyList()));
-        {
-            ShardId shardId = new ShardId(index, 2);
-            list.add(new PlainShardIterator(shardId, randomShardRoutings(shardId)));
-        }
-        {
-            ShardId shardId = new ShardId(index, 0);
-            list.add(new PlainShardIterator(shardId, randomShardRoutings(shardId)));
-        }
-        {
-            ShardId shardId = new ShardId(index, 1);
-            list.add(new PlainShardIterator(shardId, randomShardRoutings(shardId)));
-        }
-        index = new Index("foo_2", "na");
-        {
-            ShardId shardId = new ShardId(index, 0);
-            list.add(new PlainShardIterator(shardId, randomShardRoutings(shardId)));
-        }
-        {
-            ShardId shardId = new ShardId(index, 1);
-            list.add(new PlainShardIterator(shardId, randomShardRoutings(shardId)));
-        }
-
-        Collections.shuffle(list, random());
-        {
-            GroupShardsIterator<ShardIterator> unsorted = new GroupShardsIterator<>(list);
-            GroupShardsIterator<ShardIterator> iter = new GroupShardsIterator<>(list);
-            List<ShardIterator> actualIterators = new ArrayList<>();
-            for (ShardIterator shardsIterator : iter) {
-                actualIterators.add(shardsIterator);
-            }
-            assertEquals(actualIterators, list);
-        }
-        {
-            GroupShardsIterator<ShardIterator> iter = GroupShardsIterator.sortAndCreate(list);
-            List<ShardIterator> actualIterators = new ArrayList<>();
-            for (ShardIterator shardsIterator : iter) {
-                actualIterators.add(shardsIterator);
-            }
-            CollectionUtil.timSort(actualIterators);
-            assertEquals(actualIterators, list);
-        }
-    }
-
-    public void testOrderingWithSearchShardIterators() {
-        String[] indices = generateRandomStringArray(10, 10, false, false);
-        Arrays.sort(indices);
-        String[] uuids = generateRandomStringArray(5, 10, false, false);
-        Arrays.sort(uuids);
-        String[] clusters = generateRandomStringArray(5, 10, false, false);
-        Arrays.sort(clusters);
-
-        List<SearchShardIterator> sorted = new ArrayList<>();
-        int numShards = randomIntBetween(1, 10);
-        for (int i = 0; i < numShards; i++) {
-            for (String index : indices) {
-                for (String uuid : uuids) {
-                    ShardId shardId = new ShardId(index, uuid, i);
-                    SearchShardIterator shardIterator = new SearchShardIterator(
-                        null,
-                        shardId,
-                        GroupShardsIteratorTests.randomShardRoutings(shardId),
-                        OriginalIndicesTests.randomOriginalIndices()
-                    );
-                    sorted.add(shardIterator);
-                    for (String cluster : clusters) {
-                        SearchShardIterator remoteIterator = new SearchShardIterator(
-                            cluster,
-                            shardId,
-                            GroupShardsIteratorTests.randomShardRoutings(shardId),
-                            OriginalIndicesTests.randomOriginalIndices()
-                        );
-                        sorted.add(remoteIterator);
-                    }
-                }
-            }
-        }
-
-        List<SearchShardIterator> shuffled = new ArrayList<>(sorted);
-        Collections.shuffle(shuffled, random());
-        {
-            List<SearchShardIterator> actualIterators = new ArrayList<>();
-            GroupShardsIterator<SearchShardIterator> iter = new GroupShardsIterator<>(shuffled);
-            for (SearchShardIterator searchShardIterator : iter) {
-                actualIterators.add(searchShardIterator);
-            }
-            assertEquals(shuffled, actualIterators);
-        }
-        {
-            List<SearchShardIterator> actualIterators = new ArrayList<>();
-            GroupShardsIterator<SearchShardIterator> iter = GroupShardsIterator.sortAndCreate(shuffled);
-            for (SearchShardIterator searchShardIterator : iter) {
-                actualIterators.add(searchShardIterator);
-            }
-            assertEquals(sorted, actualIterators);
-        }
-    }
-}

+ 4 - 25
server/src/test/java/org/elasticsearch/cluster/routing/OperationRoutingTests.java

@@ -162,7 +162,7 @@ public class OperationRoutingTests extends ESTestCase {
         for (int i = 0; i < numRepeatedSearches; i++) {
             List<ShardRouting> searchedShards = new ArrayList<>(numShards);
             Set<String> selectedNodes = Sets.newHashSetWithExpectedSize(numShards);
-            final GroupShardsIterator<ShardIterator> groupIterator = opRouting.searchShards(state, indexNames, null, sessionKey);
+            final List<ShardIterator> groupIterator = opRouting.searchShards(state, indexNames, null, sessionKey);
 
             assertThat("One group per index shard", groupIterator.size(), equalTo(numIndices * numShards));
             for (ShardIterator shardIterator : groupIterator) {
@@ -283,14 +283,7 @@ public class OperationRoutingTests extends ESTestCase {
         TestThreadPool threadPool = new TestThreadPool("test");
         ClusterService clusterService = ClusterServiceUtils.createClusterService(threadPool);
         ResponseCollectorService collector = new ResponseCollectorService(clusterService);
-        GroupShardsIterator<ShardIterator> groupIterator = opRouting.searchShards(
-            state,
-            indexNames,
-            null,
-            null,
-            collector,
-            new HashMap<>()
-        );
+        List<ShardIterator> groupIterator = opRouting.searchShards(state, indexNames, null, null, collector, new HashMap<>());
 
         assertThat("One group per index shard", groupIterator.size(), equalTo(numIndices * numShards));
 
@@ -369,14 +362,7 @@ public class OperationRoutingTests extends ESTestCase {
         ClusterService clusterService = ClusterServiceUtils.createClusterService(threadPool);
 
         ResponseCollectorService collector = new ResponseCollectorService(clusterService);
-        GroupShardsIterator<ShardIterator> groupIterator = opRouting.searchShards(
-            state,
-            indexNames,
-            null,
-            null,
-            collector,
-            new HashMap<>()
-        );
+        List<ShardIterator> groupIterator = opRouting.searchShards(state, indexNames, null, null, collector, new HashMap<>());
         assertThat("One group per index shard", groupIterator.size(), equalTo(numIndices * numShards));
 
         // We have two nodes, where the second has more load
@@ -435,14 +421,7 @@ public class OperationRoutingTests extends ESTestCase {
         Map<String, Long> outstandingRequests = new HashMap<>();
 
         // Check that we choose to search over both nodes
-        GroupShardsIterator<ShardIterator> groupIterator = opRouting.searchShards(
-            state,
-            indexNames,
-            null,
-            null,
-            collector,
-            outstandingRequests
-        );
+        List<ShardIterator> groupIterator = opRouting.searchShards(state, indexNames, null, null, collector, outstandingRequests);
 
         Set<String> nodeIds = new HashSet<>();
         nodeIds.add(groupIterator.get(0).nextOrNull().currentNodeId());

+ 3 - 2
server/src/test/java/org/elasticsearch/cluster/routing/PlainShardIteratorTests.java

@@ -9,6 +9,7 @@
 
 package org.elasticsearch.cluster.routing;
 
+import org.elasticsearch.action.search.SearchShardIteratorTests;
 import org.elasticsearch.index.shard.ShardId;
 import org.elasticsearch.test.ESTestCase;
 import org.elasticsearch.test.EqualsHashCodeTestUtils;
@@ -55,7 +56,7 @@ public class PlainShardIteratorTests extends ESTestCase {
             for (String index : indices) {
                 for (String uuid : uuids) {
                     ShardId shardId = new ShardId(index, uuid, i);
-                    shardIterators.add(new PlainShardIterator(shardId, GroupShardsIteratorTests.randomShardRoutings(shardId)));
+                    shardIterators.add(new PlainShardIterator(shardId, SearchShardIteratorTests.randomShardRoutings(shardId)));
                 }
             }
         }
@@ -86,6 +87,6 @@ public class PlainShardIteratorTests extends ESTestCase {
 
     private static PlainShardIterator randomPlainShardIterator() {
         ShardId shardId = new ShardId(randomAlphaOfLengthBetween(5, 10), randomAlphaOfLength(10), randomIntBetween(1, Integer.MAX_VALUE));
-        return new PlainShardIterator(shardId, GroupShardsIteratorTests.randomShardRoutings(shardId));
+        return new PlainShardIterator(shardId, SearchShardIteratorTests.randomShardRoutings(shardId));
     }
 }

+ 1 - 7
server/src/test/java/org/elasticsearch/cluster/structure/RoutingIteratorTests.java

@@ -17,7 +17,6 @@ import org.elasticsearch.cluster.TestShardRoutingRoleStrategies;
 import org.elasticsearch.cluster.metadata.IndexMetadata;
 import org.elasticsearch.cluster.metadata.Metadata;
 import org.elasticsearch.cluster.node.DiscoveryNodes;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.routing.OperationRouting;
 import org.elasticsearch.cluster.routing.PlainShardIterator;
 import org.elasticsearch.cluster.routing.RotationShardShuffler;
@@ -357,12 +356,7 @@ public class RoutingIteratorTests extends ESAllocationTestCase {
             new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS)
         );
 
-        GroupShardsIterator<ShardIterator> shardIterators = operationRouting.searchShards(
-            clusterState,
-            new String[] { "test" },
-            null,
-            "_shards:0"
-        );
+        List<ShardIterator> shardIterators = operationRouting.searchShards(clusterState, new String[] { "test" }, null, "_shards:0");
         assertThat(shardIterators.size(), equalTo(1));
         assertThat(shardIterators.iterator().next().shardId().id(), equalTo(0));
 

+ 1 - 3
x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/TransportForgetFollowerAction.java

@@ -16,7 +16,6 @@ import org.elasticsearch.action.support.replication.ReplicationResponse;
 import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.block.ClusterBlockException;
 import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.routing.PlainShardsIterator;
 import org.elasticsearch.cluster.routing.ShardIterator;
 import org.elasticsearch.cluster.routing.ShardRouting;
@@ -141,8 +140,7 @@ public class TransportForgetFollowerAction extends TransportBroadcastByNodeActio
         final ForgetFollowerAction.Request request,
         final String[] concreteIndices
     ) {
-        final GroupShardsIterator<ShardIterator> activePrimaryShards = clusterState.routingTable()
-            .activePrimaryShardsGrouped(concreteIndices, false);
+        final List<ShardIterator> activePrimaryShards = clusterState.routingTable().activePrimaryShardsGrouped(concreteIndices, false);
         final List<ShardRouting> shardRoutings = new ArrayList<>();
         final Iterator<ShardIterator> it = activePrimaryShards.iterator();
         while (it.hasNext()) {

+ 1 - 3
x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/termsenum/action/TransportTermsEnumAction.java

@@ -25,7 +25,6 @@ import org.elasticsearch.cluster.block.ClusterBlockLevel;
 import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
 import org.elasticsearch.cluster.node.DiscoveryNode;
 import org.elasticsearch.cluster.node.DiscoveryNodes;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.routing.ShardIterator;
 import org.elasticsearch.cluster.routing.ShardRouting;
 import org.elasticsearch.cluster.service.ClusterService;
@@ -205,8 +204,7 @@ public class TransportTermsEnumAction extends HandledTransportAction<TermsEnumRe
 
             String[] singleIndex = { indexName };
 
-            GroupShardsIterator<ShardIterator> shards = clusterService.operationRouting()
-                .searchShards(clusterState, singleIndex, null, null);
+            List<ShardIterator> shards = clusterService.operationRouting().searchShards(clusterState, singleIndex, null, null);
 
             for (ShardIterator copiesOfShard : shards) {
                 ShardRouting selectedCopyOfShard = null;

+ 3 - 8
x-pack/plugin/downsample/src/main/java/org/elasticsearch/xpack/downsample/TransportDownsampleIndexerAction.java

@@ -17,7 +17,6 @@ import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.block.ClusterBlockException;
 import org.elasticsearch.cluster.block.ClusterBlockLevel;
 import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.routing.ShardIterator;
 import org.elasticsearch.cluster.routing.ShardRouting;
 import org.elasticsearch.cluster.service.ClusterService;
@@ -35,6 +34,7 @@ import org.elasticsearch.xpack.core.downsample.DownsampleShardTask;
 
 import java.io.IOException;
 import java.util.Arrays;
+import java.util.List;
 import java.util.concurrent.atomic.AtomicReferenceArray;
 
 /**
@@ -79,17 +79,12 @@ public class TransportDownsampleIndexerAction extends TransportBroadcastAction<
     }
 
     @Override
-    protected GroupShardsIterator<ShardIterator> shards(
-        ClusterState clusterState,
-        DownsampleIndexerAction.Request request,
-        String[] concreteIndices
-    ) {
+    protected List<ShardIterator> shards(ClusterState clusterState, DownsampleIndexerAction.Request request, String[] concreteIndices) {
         if (concreteIndices.length > 1) {
             throw new IllegalArgumentException("multiple indices: " + Arrays.toString(concreteIndices));
         }
 
-        final GroupShardsIterator<ShardIterator> groups = clusterService.operationRouting()
-            .searchShards(clusterState, concreteIndices, null, null);
+        final List<ShardIterator> groups = clusterService.operationRouting().searchShards(clusterState, concreteIndices, null, null);
         for (ShardIterator group : groups) {
             // fails fast if any non-active groups
             if (group.size() == 0) {

+ 1 - 6
x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/EnrichShardMultiSearchAction.java

@@ -25,10 +25,8 @@ import org.elasticsearch.action.support.single.shard.SingleShardRequest;
 import org.elasticsearch.action.support.single.shard.TransportSingleShardAction;
 import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.routing.IndexRoutingTable;
 import org.elasticsearch.cluster.routing.Preference;
-import org.elasticsearch.cluster.routing.ShardIterator;
 import org.elasticsearch.cluster.routing.ShardsIterator;
 import org.elasticsearch.cluster.service.ClusterService;
 import org.elasticsearch.common.Strings;
@@ -216,10 +214,7 @@ public class EnrichShardMultiSearchAction extends ActionType<MultiSearchResponse
             if (numShards != 1) {
                 throw new IllegalStateException("index [" + index + "] should have 1 shard, but has " + numShards + " shards");
             }
-
-            GroupShardsIterator<ShardIterator> result = clusterService.operationRouting()
-                .searchShards(state, new String[] { index }, null, Preference.LOCAL.type());
-            return result.get(0);
+            return clusterService.operationRouting().searchShards(state, new String[] { index }, null, Preference.LOCAL.type()).get(0);
         }
 
         @Override

+ 1 - 2
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/enrich/AbstractLookupService.java

@@ -15,7 +15,6 @@ import org.elasticsearch.action.support.ChannelActionListener;
 import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.node.DiscoveryNode;
-import org.elasticsearch.cluster.routing.GroupShardsIterator;
 import org.elasticsearch.cluster.routing.ShardIterator;
 import org.elasticsearch.cluster.routing.ShardRouting;
 import org.elasticsearch.cluster.service.ClusterService;
@@ -210,7 +209,7 @@ public abstract class AbstractLookupService<R extends AbstractLookupService.Requ
      */
     public final void lookupAsync(R request, CancellableTask parentTask, ActionListener<List<Page>> outListener) {
         ClusterState clusterState = clusterService.state();
-        GroupShardsIterator<ShardIterator> shardIterators = clusterService.operationRouting()
+        List<ShardIterator> shardIterators = clusterService.operationRouting()
             .searchShards(clusterState, new String[] { request.index }, Map.of(), "_local");
         if (shardIterators.size() != 1) {
             outListener.onFailure(new EsqlIllegalArgumentException("target index {} has more than one shard", request.index));