protected void addRemoteReplicaInfoToReplicaThread(List<RemoteReplicaInfo> remoteReplicaInfos, boolean startThread) {
    for (RemoteReplicaInfo remoteReplicaInfo : remoteReplicaInfos) {
      DataNodeId dataNodeIdToReplicate = remoteReplicaInfo.getReplicaId().getDataNodeId();
      String datacenter = dataNodeIdToReplicate.getDatacenterName();
      List<ReplicaThread> replicaThreads = getOrCreateThreadPoolIfNecessary(datacenter, startThread);
      if (replicaThreads == null) {
        logger.warn("Number of replica threads is smaller or equal to 0, not starting any replica threads for {}.",
            datacenter);
        continue;
      }
      ReplicaThread replicaThread = dataNodeIdToReplicaThread.computeIfAbsent(dataNodeIdToReplicate,
          key -> replicaThreads.get(getReplicaThreadIndexToUse(datacenter)));
      replicaThread.addRemoteReplicaInfo(remoteReplicaInfo);
      remoteReplicaInfo.setReplicaThread(replicaThread);
    }
  }
Assign {@link RemoteReplicaInfo} to a {@link ReplicaThread} for replication.
The assignment is based on {@link DataNodeId}. If no {@link ReplicaThread} responsible for a {@link DataNodeId},
a {@link ReplicaThread} will be selected by {@link ReplicationEngine#getReplicaThreadIndexToUse(String)}.
Create threads pool for a DC if not exists.
@param remoteReplicaInfos List of {@link RemoteReplicaInfo} to add.
@param startThread if threads need to be started when create.
ambry-replication/src/main/java/com/github/ambry/replication/ReplicationEngine.java