private List<InputSplit> oneInputSplitPerRegion() throws IOException {
    if (regionSizeCalculator == null) {
      // Initialize here rather than with the other resources because this involves
      // a full scan of meta, which can be heavy. We might as well only do it if/when necessary.
      regionSizeCalculator = createRegionSizeCalculator(getRegionLocator(), getAdmin());
    }

    TableName tableName = getTable().getName();

    Pair<byte[][], byte[][]> keys = getStartEndKeys();
    if (keys == null || keys.getFirst() == null || keys.getFirst().length == 0) {
      HRegionLocation regLoc =
        getRegionLocator().getRegionLocation(HConstants.EMPTY_BYTE_ARRAY, false);
      if (null == regLoc) {
        throw new IOException("Expecting at least one region.");
      }
      List<InputSplit> splits = new ArrayList<>(1);
      long regionSize = regionSizeCalculator.getRegionSize(regLoc.getRegion().getRegionName());
      // In the table input format for single table we do not need to
      // store the scan object in table split because it can be memory intensive and redundant
      // information to what is already stored in conf SCAN. See HBASE-25212
      TableSplit split =
        new TableSplit(tableName, null, HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY,
          regLoc.getHostnamePort().split(Addressing.HOSTNAME_PORT_SEPARATOR)[0], regionSize);
      splits.add(split);
      return splits;
    }
    List<InputSplit> splits = new ArrayList<>(keys.getFirst().length);
    for (int i = 0; i < keys.getFirst().length; i++) {
      if (!includeRegionInSplit(keys.getFirst()[i], keys.getSecond()[i])) {
        continue;
      }

      byte[] startRow = scan.getStartRow();
      byte[] stopRow = scan.getStopRow();
      // determine if the given start an stop key fall into the region
      if (
        (startRow.length == 0 || keys.getSecond()[i].length == 0
          || Bytes.compareTo(startRow, keys.getSecond()[i]) < 0)
          && (stopRow.length == 0 || Bytes.compareTo(stopRow, keys.getFirst()[i]) > 0)
      ) {
        byte[] splitStart =
          startRow.length == 0 || Bytes.compareTo(keys.getFirst()[i], startRow) >= 0
            ? keys.getFirst()[i]
            : startRow;
        byte[] splitStop =
          (stopRow.length == 0 || Bytes.compareTo(keys.getSecond()[i], stopRow) <= 0)
            && keys.getSecond()[i].length > 0 ? keys.getSecond()[i] : stopRow;

        HRegionLocation location = getRegionLocator().getRegionLocation(keys.getFirst()[i], false);
        // The below InetSocketAddress creation does a name resolution.
        InetSocketAddress isa = new InetSocketAddress(location.getHostname(), location.getPort());
        if (isa.isUnresolved()) {
          LOG.warn("Failed resolve " + isa);
        }
        InetAddress regionAddress = isa.getAddress();
        String regionLocation;
        regionLocation = reverseDNS(regionAddress);

        byte[] regionName = location.getRegion().getRegionName();
        String encodedRegionName = location.getRegion().getEncodedName();
        long regionSize = regionSizeCalculator.getRegionSize(regionName);
        // In the table input format for single table we do not need to
        // store the scan object in table split because it can be memory intensive and redundant
        // information to what is already stored in conf SCAN. See HBASE-25212
        TableSplit split = new TableSplit(tableName, null, splitStart, splitStop, regionLocation,
          encodedRegionName, regionSize);
        splits.add(split);
        if (LOG.isDebugEnabled()) {
          LOG.debug("getSplits: split -> " + i + " -> " + split);
        }
      }
    }
    return splits;
  }
Create one InputSplit per region
@return The list of InputSplit for all the regions
@throws IOException throws IOException
hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/TableInputFormatBase.java