public void mergeRegions(RegionInfo child, RegionInfo[] parents, ServerName serverName,
    TableDescriptor htd) throws IOException {
    boolean globalScope = htd.hasGlobalReplicationScope();
    long time = EnvironmentEdgeManager.currentTime();
    List<Mutation> mutations = new ArrayList<>();
    List<RegionInfo> replicationParents = new ArrayList<>();
    for (RegionInfo ri : parents) {
      long seqNum = globalScope ? getOpenSeqNumForParentRegion(ri) : -1;
      // Deletes for merging regions
      mutations.add(MetaTableAccessor.makeDeleteFromRegionInfo(ri, time));
      if (seqNum > 0) {
        mutations
          .add(ReplicationBarrierFamilyFormat.makePutForReplicationBarrier(ri, seqNum, time));
        replicationParents.add(ri);
      }
    }
    // Put for parent
    Put putOfMerged = MetaTableAccessor.makePutFromRegionInfo(child, time);
    putOfMerged = addMergeRegions(putOfMerged, Arrays.asList(parents));
    // Set initial state to CLOSED.
    // NOTE: If initial state is not set to CLOSED then merged region gets added with the
    // default OFFLINE state. If Master gets restarted after this step, start up sequence of
    // master tries to assign this offline region. This is followed by re-assignments of the
    // merged region from resumed {@link MergeTableRegionsProcedure}
    MetaTableAccessor.addRegionStateToPut(putOfMerged, RegionInfo.DEFAULT_REPLICA_ID,
      RegionState.State.CLOSED);
    mutations.add(putOfMerged);
    // The merged is a new region, openSeqNum = 1 is fine. ServerName may be null
    // if crash after merge happened but before we got to here.. means in-memory
    // locations of offlined merged, now-closed, regions is lost. Should be ok. We
    // assign the merged region later.
    if (serverName != null) {
      MetaTableAccessor.addLocation(putOfMerged, serverName, 1, child.getReplicaId());
    }

    // Add empty locations for region replicas of the merged region so that number of replicas
    // can be cached whenever the primary region is looked up from meta
    int regionReplication = getRegionReplication(htd);
    for (int i = 1; i < regionReplication; i++) {
      MetaTableAccessor.addEmptyLocation(putOfMerged, i);
    }
    // add parent reference for serial replication
    if (!replicationParents.isEmpty()) {
      ReplicationBarrierFamilyFormat.addReplicationParent(putOfMerged, replicationParents);
    }
    multiMutate(child, mutations);
  }
Splits the region into two in an atomic operation. Offlines the parent region with the
information that it is split into two, and also adds the daughter regions. Does not add the
location information to the daughter regions since they are not open yet.
hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/RegionStateStore.java