protected List<InputSplit> createNInputSplitsUniform(InputSplit split, int n)
    throws IllegalArgumentIOException {
    if (split == null || !(split instanceof TableSplit)) {
      throw new IllegalArgumentIOException(
        "InputSplit for CreateNSplitsPerRegion can not be null + "
          + "and should be instance of TableSplit");
    }
    // if n < 1, then still continue using n = 1
    n = n < 1 ? 1 : n;
    List<InputSplit> res = new ArrayList<>(n);
    if (n == 1) {
      res.add(split);
      return res;
    }

    // Collect Region related information
    TableSplit ts = (TableSplit) split;
    TableName tableName = ts.getTable();
    String regionLocation = ts.getRegionLocation();
    String encodedRegionName = ts.getEncodedRegionName();
    long regionSize = ts.getLength();
    byte[] startRow = ts.getStartRow();
    byte[] endRow = ts.getEndRow();

    // For special case: startRow or endRow is empty
    if (startRow.length == 0 && endRow.length == 0) {
      startRow = new byte[1];
      endRow = new byte[1];
      startRow[0] = 0;
      endRow[0] = -1;
    }
    if (startRow.length == 0 && endRow.length != 0) {
      startRow = new byte[1];
      startRow[0] = 0;
    }
    if (startRow.length != 0 && endRow.length == 0) {
      endRow = new byte[startRow.length];
      for (int k = 0; k < startRow.length; k++) {
        endRow[k] = -1;
      }
    }

    // Split Region into n chunks evenly
    byte[][] splitKeys = Bytes.split(startRow, endRow, true, n - 1);
    for (int i = 0; i < splitKeys.length - 1; i++) {
      // 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
      // notice that the regionSize parameter may be not very accurate
      TableSplit tsplit = new TableSplit(tableName, null, splitKeys[i], splitKeys[i + 1],
        regionLocation, encodedRegionName, regionSize / n);
      res.add(tsplit);
    }
    return res;
  }
Create n splits for one InputSplit, For now only support uniform distribution
@param split A TableSplit corresponding to a range of rowkeys
@param n     Number of ranges after splitting. Pass 1 means no split for the range Pass 2 if
             you want to split the range in two;
@return A list of TableSplit, the size of the list is {@code n}
hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/TableInputFormatBase.java