private Map<String, Map<String, Map<String, String>>> generateReplicaAdditionMap() {
    //populate dcToInstanceNameToDataNodeId and instanceToDiskReplicasMap
    populateInstancesAndPartitionsMap();
    Map<String, Map<String, Map<String, String>>> newAddedReplicasByDc = new HashMap<>();
    for (Map.Entry<String, HelixAdmin> entry : adminForDc.entrySet()) {
      HelixAdmin dcAdmin = entry.getValue();
      String dcName = entry.getKey();
      info("[{}] Generating replica addition map for datacenter {}", dcName.toUpperCase(), dcName);
      Map<String, Map<String, Replica>> partitionToInstancesAndReplicas = new HashMap<>();
      Map<String, Map<String, String>> newAddedReplicasInDc = new HashMap<>();
      for (String instanceName : dcToInstanceNameToDataNodeId.get(dcName).keySet()) {
        Map<DiskId, SortedSet<Replica>> diskToReplica = instanceToDiskReplicasMap.get(instanceName);
        for (SortedSet<Replica> replicas : diskToReplica.values()) {
          for (Replica replica : replicas) {
            partitionToInstancesAndReplicas.computeIfAbsent(replica.getPartitionId().toPathString(),
                key -> new HashMap<>()).put(instanceName, replica);
          }
        }
      }
      List<String> resourcesInCluster = dcAdmin.getResourcesInCluster(clusterName);
      for (String resourceName : resourcesInCluster) {
        if (!resourceName.matches("\\d+")) {
          continue;
        }
        IdealState idealState = dcAdmin.getResourceIdealState(clusterName, resourceName);
        for (String partitionStr : new HashSet<>(idealState.getPartitionSet())) {
          Set<String> instanceSetInHelix = idealState.getInstanceSet(partitionStr);
          Map<String, Replica> instanceAndReplicaInStatic = partitionToInstancesAndReplicas.get(partitionStr);
          if (instanceAndReplicaInStatic == null || instanceAndReplicaInStatic.isEmpty()) {
            info(
                "[{}] *** Partition {} no longer present in the static clustermap. Uploading cluster admin infos operation won't remove it *** ",
                dcName.toUpperCase(), partitionStr);
          } else if (!instanceAndReplicaInStatic.keySet().equals(instanceSetInHelix)) {
            info(
                "[{}] Different instance sets for partition {} under resource {}. Extracting new replicas from static clustermap.",
                dcName.toUpperCase(), partitionStr, resourceName);
            // instances in static only
            Set<String> instanceSetInStatic = instanceAndReplicaInStatic.keySet();
            instanceSetInStatic.removeAll(instanceSetInHelix);
            for (String instance : instanceSetInStatic) {
              Replica replica = instanceAndReplicaInStatic.get(instance);
              info("[{}] New replica of partition[{}] will be added to instance {} on {}", dcName.toUpperCase(),
                  partitionStr, instance, replica.getMountPath());
              newAddedReplicasInDc.computeIfAbsent(partitionStr, key -> {
                    Map<String, String> partitionMap = new HashMap<>();
                    partitionMap.put(PARTITION_CLASS_STR, replica.getPartitionId().getPartitionClass());
                    partitionMap.put(REPLICAS_CAPACITY_STR, String.valueOf(replica.getCapacityInBytes()));
                    return partitionMap;
                  })
                  .put(instance,
                      replica.getMountPath() + DISK_CAPACITY_DELIM_STR + replica.getDiskId().getRawCapacityInBytes());
            }
          }
        }
      }
      newAddedReplicasByDc.put(dcName, newAddedReplicasInDc);
    }
    return newAddedReplicasByDc;
  }
Generate replica addition infos map grouped by each dc. This map contains detailed replica info (size, mount path, etc)
that will be used by certain server to instantiate new added Ambry replica. The format is as follows.
"mapFields": {
    "1": {
        "replicaCapacityInBytes": 107374182400,
        "partitionClass": "max-replicas-all-datacenters",
        "localhost1_17088": "/tmp/c/1,536870912000",
        "localhost2_17088": "/tmp/d/1,536870912000"
    },
    "2": {
        "replicaCapacityInBytes": 107374182400,
        "partitionClass": "max-replicas-all-datacenters",
        "localhost3_17088": "/tmp/e/1,536870912000"
    }
}
In above example, two new replicas of partition[1] will be added to localhost1 and localhost2 respectively.
The host name is followed by mount path and disk capacity (separated by comma) on which the new replica should be
placed.
@return a map that contains detailed replica info.
ambry-clustermap/src/main/java/com/github/ambry/clustermap/HelixBootstrapUpgradeUtil.java