public static List<InputSplit> getSplits(Scan scan, SnapshotManifest manifest,
    List<RegionInfo> regionManifests, Path restoreDir, Configuration conf,
    RegionSplitter.SplitAlgorithm sa, int numSplits) throws IOException {
    // load table descriptor
    TableDescriptor htd = manifest.getTableDescriptor();

    Path tableDir = CommonFSUtils.getTableDir(restoreDir, htd.getTableName());

    boolean localityEnabled = conf.getBoolean(SNAPSHOT_INPUTFORMAT_LOCALITY_ENABLED_KEY,
      SNAPSHOT_INPUTFORMAT_LOCALITY_ENABLED_DEFAULT);

    boolean scanMetricsEnabled = conf.getBoolean(SNAPSHOT_INPUTFORMAT_SCAN_METRICS_ENABLED,
      SNAPSHOT_INPUTFORMAT_SCAN_METRICS_ENABLED_DEFAULT);
    scan.setScanMetricsEnabled(scanMetricsEnabled);

    boolean useRegionLoc = conf.getBoolean(SNAPSHOT_INPUTFORMAT_LOCALITY_BY_REGION_LOCATION,
      SNAPSHOT_INPUTFORMAT_LOCALITY_BY_REGION_LOCATION_DEFAULT);

    Connection connection = null;
    RegionLocator regionLocator = null;
    if (localityEnabled && useRegionLoc) {
      Configuration newConf = new Configuration(conf);
      newConf.setInt("hbase.hconnection.threads.max", 1);
      try {
        connection = ConnectionFactory.createConnection(newConf);
        regionLocator = connection.getRegionLocator(htd.getTableName());

        /* Get all locations for the table and cache it */
        regionLocator.getAllRegionLocations();
      } finally {
        if (connection != null) {
          connection.close();
        }
      }
    }

    List<InputSplit> splits = new ArrayList<>();
    for (RegionInfo hri : regionManifests) {
      // load region descriptor
      List<String> hosts = null;
      if (localityEnabled) {
        if (regionLocator != null) {
          /* Get Location from the local cache */
          HRegionLocation location = regionLocator.getRegionLocation(hri.getStartKey(), false);

          hosts = new ArrayList<>(1);
          hosts.add(location.getHostname());
        } else {
          hosts = calculateLocationsForInputSplit(conf, htd, hri, tableDir);
        }
      }

      if (numSplits > 1) {
        byte[][] sp = sa.split(hri.getStartKey(), hri.getEndKey(), numSplits, true);
        for (int i = 0; i < sp.length - 1; i++) {
          if (
            PrivateCellUtil.overlappingKeys(scan.getStartRow(), scan.getStopRow(), sp[i], sp[i + 1])
          ) {

            Scan boundedScan = new Scan(scan);
            if (scan.getStartRow().length == 0) {
              boundedScan.withStartRow(sp[i]);
            } else {
              boundedScan.withStartRow(
                Bytes.compareTo(scan.getStartRow(), sp[i]) > 0 ? scan.getStartRow() : sp[i]);
            }

            if (scan.getStopRow().length == 0) {
              boundedScan.withStopRow(sp[i + 1]);
            } else {
              boundedScan.withStopRow(
                Bytes.compareTo(scan.getStopRow(), sp[i + 1]) < 0 ? scan.getStopRow() : sp[i + 1]);
            }

            splits.add(new InputSplit(htd, hri, hosts, boundedScan, restoreDir));
          }
        }
      } else {
        if (
          PrivateCellUtil.overlappingKeys(scan.getStartRow(), scan.getStopRow(), hri.getStartKey(),
            hri.getEndKey())
        ) {

          splits.add(new InputSplit(htd, hri, hosts, scan, restoreDir));
        }
      }
    }

    return splits;
  }
Implementation class for RecordReader logic common between mapred and mapreduce.
hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/TableSnapshotInputFormatImpl.java