@Override
    public List<AmbryReplica> getReplicaIdsByState(AmbryPartition partition, ReplicaState state, String dcName) {
      Timer.Context operationTimer = helixClusterManagerMetrics.routingTableQueryTime.time();
      long startTime = SystemTime.getInstance().milliseconds();
      Set<AmbryReplica> replicas = new HashSet<>();
      List<String> dcs = dcName != null ? Collections.singletonList(dcName)
          : dcToDcInfo.values().stream().map(dcInfo -> dcInfo.dcName).collect(Collectors.toList());
      String partitionName = partition.toPathString();
      for (String dc : dcs) {
        Set<String> resourceNames = partitionToResourceNameByDc.get(dc).get(partitionName);
        if (resourceNames == null) {
          // For newly created partitions, we might not able to find resources in other DCs
          continue;
        }
        RoutingTableSnapshot routingTableSnapshot =
            clusterMapConfig.clusterMapUseAggregatedView ? globalRoutingTableSnapshotRef.get()
                : dcToRoutingTableSnapshotRef.get(dc).get();
        int replicasBefore = replicas.size();
        for (String resourceName : resourceNames) {
          getReplicaIdsByStateInRoutingTableSnapshot(routingTableSnapshot, dc, resourceName, partitionName, state,
              replicas);
        }
        if (replicas.size() != replicasBefore) {
          continue;
        }
        logger.trace("Can't find any replicas in dc {} for partition {} at resources {} at state {}", dc, partition,
            resourceNames, state);
        if (!partitionToDuplicateResourceNameByDc.get(dc).containsKey(partitionName)) {
          logger.trace("No duplicate resource found for partition {} in dc {}, continue", partitionName, dc);
          continue;
        }
        Map<String, ExternalView> externalViewMap =
            clusterMapConfig.clusterMapUseAggregatedView ? globalResourceToExternalView
                : dcToResourceToExternalView.get(dc);
        // None of resources has instances for the partition, we try the duplicate resource
        if (!resourceNames.stream()
            .anyMatch(
                resource -> externalViewHasInstanceForPartition(externalViewMap.get(resource), dc, partitionName))) {
          String duplicateResource = partitionToDuplicateResourceNameByDc.get(dc).get(partitionName);
          logger.trace("Partition {} doesn't exist in resources {} in dc {}, try duplicate resource {}", partitionName,
              resourceNames, dc, duplicateResource);
          helixClusterManagerMetrics.resourceNameMismatchCount.inc();
          getReplicaIdsByStateInRoutingTableSnapshot(routingTableSnapshot, dc, duplicateResource, partitionName, state,
              replicas);
        }
      }
      logger.debug("Replicas for partition {} with state {} in dc {} are {}. Query time in Ms {}", partitionName,
          state.name(), dcName != null ? dcName : "", replicas, SystemTime.getInstance().milliseconds() - startTime);
      operationTimer.stop();
      return new ArrayList<>(replicas);
    }
{@inheritDoc}
If dcName is null, then get replicas by given state from all datacenters.
If no routing table snapshot is found for dc name, or no resource name found for given partition, return empty list.
ambry-clustermap/src/main/java/com/github/ambry/clustermap/HelixClusterManager.java