@Override
  public void selectInstances(Map<Integer, List<InstanceConfig>> poolToInstanceConfigsMap,
      InstancePartitions instancePartitions) {
    int numPools = poolToInstanceConfigsMap.size();
    Preconditions.checkState(numPools != 0, "No pool qualified for selection");

    int tableNameHash = Math.abs(_tableNameWithType.hashCode());
    List<Integer> pools = new ArrayList<>(poolToInstanceConfigsMap.keySet());
    pools.sort(null);
    LOGGER.info("Starting instance replica-group/partition selection for table: {} with hash: {} from pools: {}, "
        + "minimize data movement: {}", _tableNameWithType, tableNameHash, pools, _minimizeDataMovement);

    if (_replicaGroupPartitionConfig.isReplicaGroupBased()) {
      if (_minimizeDataMovement) {
        replicaGroupBasedMinimumMovement(poolToInstanceConfigsMap, instancePartitions, pools, tableNameHash);
      } else {
        replicaGroupBasedSimple(poolToInstanceConfigsMap, instancePartitions, pools, tableNameHash);
      }
    } else {
      nonReplicaGroupBased(poolToInstanceConfigsMap, instancePartitions, pools, tableNameHash);
    }
  }
@Test
  public void testSelectPoolsWhenExistingReplicaGroupMapsToMultiplePools()
      throws JsonProcessingException {
    // The "rg0-2" instance used to belong to Pool 1, but now it belongs to Pool 0.
    //@formatter:off
    String existingPartitionsJson =
        "{\n"
      + "  \"instancePartitionsName\": \"0f97dac8-4123-47c6-9a4d-b8ce039c5ea5_OFFLINE\",\n"
      + "  \"partitionToInstancesMap\": {\n"
      + "    \"0_0\": [\n"
      + "      \"Server_pinot-server-rg0-0.pinot-server-headless.pinot.svc.cluster.local_8098\",\n"
      + "      \"Server_pinot-server-rg0-1.pinot-server-headless.pinot.svc.cluster.local_8098\"\n"
      + "    ],\n"
      + "    \"0_1\": [\n"
      + "      \"Server_pinot-server-rg0-2.pinot-server-headless.pinot.svc.cluster.local_8098\",\n"
      + "      \"Server_pinot-server-rg1-0.pinot-server-headless.pinot.svc.cluster.local_8098\"\n"
      + "    ]\n"
      + "  }\n"
      + "}";
    //@formatter:on
    InstancePartitions existing = OBJECT_MAPPER.readValue(existingPartitionsJson, InstancePartitions.class);
    InstanceReplicaGroupPartitionConfig config =
        new InstanceReplicaGroupPartitionConfig(true, 0, 2, 2, 1, 2, true, null);

    InstanceReplicaGroupPartitionSelector selector =
        new InstanceReplicaGroupPartitionSelector(config, "tableNameBlah", existing, true);

    String[] serverNames = {"rg0-0", "rg0-1", "rg0-2", "rg1-0", "rg1-1", "rg1-2"};
    String[] poolNumbers = {"0", "0", "0", "1", "1", "1"};
    Map<Integer, List<InstanceConfig>> poolToInstanceConfigsMap = new HashMap<>();

    for (int i = 0; i < serverNames.length; i++) {
      Map<String, String> valuesMap = new HashMap<>();
      valuesMap.put("serverName", serverNames[i]);
      valuesMap.put("pool", poolNumbers[i]);

      StringSubstitutor substitutor = new StringSubstitutor(valuesMap);
      String resolvedString = substitutor.replace(INSTANCE_CONFIG_TEMPLATE);

      ZNRecord znRecord = OBJECT_MAPPER.readValue(resolvedString, ZNRecord.class);
      int poolNumber = Integer.parseInt(poolNumbers[i]);
      poolToInstanceConfigsMap.computeIfAbsent(poolNumber, k -> new ArrayList<>()).add(new InstanceConfig(znRecord));
    }

    InstancePartitions assignedPartitions = new InstancePartitions("0f97dac8-4123-47c6-9a4d-b8ce039c5ea5_OFFLINE");
    selector.selectInstances(poolToInstanceConfigsMap, assignedPartitions);

    // The "rg0-2" instance is replaced by "rg1-0" (which belongs to Pool 1), as "rg0-2" no longer belongs to Pool 1.
    // And "rg1-0" remains the same position as it's always under Pool 1.
    //@formatter:off
    String expectedInstancePartitions =
        "{\n"
      + "  \"instancePartitionsName\": \"0f97dac8-4123-47c6-9a4d-b8ce039c5ea5_OFFLINE\",\n"
      + "  \"partitionToInstancesMap\": {\n"
      + "    \"0_0\": [\n"
      + "      \"Server_pinot-server-rg0-0.pinot-server-headless.pinot.svc.cluster.local_8098\",\n"
      + "      \"Server_pinot-server-rg0-1.pinot-server-headless.pinot.svc.cluster.local_8098\"\n"
      + "    ],\n"
      + "    \"0_1\": [\n"
      + "      \"Server_pinot-server-rg1-1.pinot-server-headless.pinot.svc.cluster.local_8098\",\n"
      + "      \"Server_pinot-server-rg1-0.pinot-server-headless.pinot.svc.cluster.local_8098\"\n"
      + "    ]\n"
      + "  }\n"
      + "}";
    //@formatter:on
    InstancePartitions expectedPartitions =
        OBJECT_MAPPER.readValue(expectedInstancePartitions, InstancePartitions.class);
    assertEquals(assignedPartitions, expectedPartitions);
  }