static LinkedList<Pair<byte[], byte[]>> splitScan(LinkedList<Pair<byte[], byte[]>> regionList,
    final Connection connection, final TableName tableName, SplitAlgorithm splitAlgo)
    throws IOException, InterruptedException {
    LinkedList<Pair<byte[], byte[]>> finished = Lists.newLinkedList();
    LinkedList<Pair<byte[], byte[]>> logicalSplitting = Lists.newLinkedList();
    LinkedList<Pair<byte[], byte[]>> physicalSplitting = Lists.newLinkedList();

    // Get table info
    Pair<Path, Path> tableDirAndSplitFile =
      getTableDirAndSplitFile(connection.getConfiguration(), tableName);
    Path tableDir = tableDirAndSplitFile.getFirst();
    FileSystem fs = tableDir.getFileSystem(connection.getConfiguration());
    // Clear the cache to forcibly refresh region information
    connection.clearRegionLocationCache();
    TableDescriptor htd = null;
    try (Table table = connection.getTable(tableName)) {
      htd = table.getDescriptor();
    }
    try (RegionLocator regionLocator = connection.getRegionLocator(tableName)) {
      // for every region that hasn't been verified as a finished split
      for (Pair<byte[], byte[]> region : regionList) {
        byte[] start = region.getFirst();
        byte[] split = region.getSecond();

        // see if the new split daughter region has come online
        try {
          RegionInfo dri = regionLocator.getRegionLocation(split, true).getRegion();
          if (dri.isOffline() || !Bytes.equals(dri.getStartKey(), split)) {
            logicalSplitting.add(region);
            continue;
          }
        } catch (NoServerForRegionException nsfre) {
          // NSFRE will occur if the old hbase:meta entry has no server assigned
          LOG.info(nsfre.toString(), nsfre);
          logicalSplitting.add(region);
          continue;
        }

        try {
          // when a daughter region is opened, a compaction is triggered
          // wait until compaction completes for both daughter regions
          LinkedList<RegionInfo> check = Lists.newLinkedList();
          check.add(regionLocator.getRegionLocation(start).getRegion());
          check.add(regionLocator.getRegionLocation(split).getRegion());
          for (RegionInfo hri : check.toArray(new RegionInfo[check.size()])) {
            byte[] sk = hri.getStartKey();
            if (sk.length == 0) sk = splitAlgo.firstRow();

            HRegionFileSystem regionFs = HRegionFileSystem
              .openRegionFromFileSystem(connection.getConfiguration(), fs, tableDir, hri, true);

            // Check every Column Family for that region -- check does not have references.
            boolean refFound = false;
            for (ColumnFamilyDescriptor c : htd.getColumnFamilies()) {
              StoreFileTracker sft = StoreFileTrackerFactory
                .create(regionFs.getFileSystem().getConf(), htd, c, regionFs);
              if ((refFound = sft.hasReferences())) {
                break;
              }
            }

            // compaction is completed when all reference files are gone
            if (!refFound) {
              check.remove(hri);
            }
          }
          if (check.isEmpty()) {
            finished.add(region);
          } else {
            physicalSplitting.add(region);
          }
        } catch (NoServerForRegionException nsfre) {
          LOG.debug("No Server Exception thrown for: " + splitAlgo.rowToStr(start));
          physicalSplitting.add(region);
          connection.clearRegionLocationCache();
        }
      }

      LOG.debug("Split Scan: " + finished.size() + " finished / " + logicalSplitting.size()
        + " split wait / " + physicalSplitting.size() + " reference wait");

      return finished;
    }
  }
@throws IOException if the specified SplitAlgorithm class couldn't be instantiated
hbase-server/src/main/java/org/apache/hadoop/hbase/util/RegionSplitter.java