PartitionId getRandomPartitionWithState(String partitionClass, List<PartitionId> partitionsToExclude,
        Predicate<PartitionState> stateCriteria, String criteriaStr) {
      PartitionId anySuitablePartition = null;
      long startTime = SystemTime.getInstance().milliseconds();
      List<PartitionId> partitionsInClass = new ArrayList<>();
      rwLock.readLock().lock();
      try {
        partitionsInClass = getPartitionsInClass(partitionClass, true);
        int workingSize = partitionsInClass.size();
        while (workingSize > 0) {
          int randomIndex = ThreadLocalRandom.current().nextInt(workingSize);
          PartitionId selected = partitionsInClass.get(randomIndex);
          if (partitionsToExclude == null || partitionsToExclude.size() == 0 || !partitionsToExclude.contains(
              selected)) {
            if (stateCriteria.test(selected.getPartitionState())) {
              anySuitablePartition = selected;
              if (hasEnoughEligibleWritableReplicas(selected)) {
                return selected;
              }
            }
          }
          if (randomIndex != workingSize - 1) {
            partitionsInClass.set(randomIndex, partitionsInClass.get(workingSize - 1));
          }
          workingSize--;
        }
        //if we are here then that means we couldn't find any partition with all local replicas up
        return anySuitablePartition;
      } finally {
        rwLock.readLock().unlock();
        if (anySuitablePartition != null) {
          logger.debug(
              "Partition class {}, number of partitions {}, selected partition {} for {} criteria, search time in Ms {}",
              partitionClass != null ? partitionClass : "", partitionsInClass.size(), anySuitablePartition,
              SystemTime.getInstance().milliseconds() - startTime);
        } else {
          logger.debug(
              "Partition class {}, number of partitions {}, no partition selected for {} criteria, search time in Ms {}",
              partitionClass != null ? partitionClass : "", partitionsInClass.size(),
              SystemTime.getInstance().milliseconds() - startTime);
        }
      }
    }
Returns a partition selected at random, that belongs to the specified partition class and meets the specified
stateCriteria AND has enough replicas up. In case none of the partitions have enough
replicas up, any partition that meets the state criteria is returned. Enough replicas is considered to be all
local replicas if such information is available. In case localDatacenterName is not available, all of the
partition's replicas should be up.
@param partitionClass the class of the partitions desired. Can be {@code null}.
@param partitionsToExclude partitions that should be excluded from the result. Can be {@code null} or empty.
@param stateCriteria {@link Predicate} that specifies the selection criteria for the partition based on {@link PartitionState}.
@param criteriaStr String representing a name for stateCriteria for logging.
@return A partition that meets the specified stateCriteria or {@code null} if no partition with given stateCriteria found
ambry-clustermap/src/main/java/com/github/ambry/clustermap/ClusterMapUtils.java