public Path splitStoreFile(RegionInfo hri, String familyName, HStoreFile f, byte[] splitRow,
    boolean top, RegionSplitPolicy splitPolicy, StoreFileTracker tracker) throws IOException {
    Path splitDir = new Path(getSplitsDir(hri), familyName);
    // Add the referred-to regions name as a dot separated suffix.
    // See REF_NAME_REGEX regex above. The referred-to regions name is
    // up in the path of the passed in <code>f</code> -- parentdir is family,
    // then the directory above is the region name.
    String parentRegionName = regionInfoForFs.getEncodedName();
    // Write reference with same file id only with the other region name as
    // suffix and into the new region location (under same family).
    Path p = new Path(splitDir, f.getPath().getName() + "." + parentRegionName);
    if (fs.exists(p)) {
      LOG.warn("Found an already existing split file for {}. Assuming this is a recovery.", p);
      return p;
    }
    boolean createLinkFile = false;
    if (splitPolicy == null || !splitPolicy.skipStoreFileRangeCheck(familyName)) {
      // Check whether the split row lies in the range of the store file
      // If it is outside the range, return directly.
      f.initReader();
      try {
        Cell splitKey = PrivateCellUtil.createFirstOnRow(splitRow);
        Optional<ExtendedCell> lastKey = f.getLastKey();
        Optional<ExtendedCell> firstKey = f.getFirstKey();
        if (top) {
          // check if larger than last key.
          // If lastKey is null means storefile is empty.
          if (!lastKey.isPresent()) {
            return null;
          }
          if (f.getComparator().compare(splitKey, lastKey.get()) > 0) {
            return null;
          }
          if (firstKey.isPresent() && f.getComparator().compare(splitKey, firstKey.get()) <= 0) {
            LOG.debug("Will create HFileLink file for {}, top=true", f.getPath());
            createLinkFile = true;
          }
        } else {
          // check if smaller than first key
          // If firstKey is null means storefile is empty.
          if (!firstKey.isPresent()) {
            return null;
          }
          if (f.getComparator().compare(splitKey, firstKey.get()) < 0) {
            return null;
          }
          if (lastKey.isPresent() && f.getComparator().compare(splitKey, lastKey.get()) >= 0) {
            LOG.debug("Will create HFileLink file for {}, top=false", f.getPath());
            createLinkFile = true;
          }
        }
      } finally {
        f.closeStoreFile(f.getCacheConf() != null ? f.getCacheConf().shouldEvictOnClose() : true);
      }
    }
    if (createLinkFile) {
      // create HFileLink file instead of Reference file for child
      String hfileName = f.getPath().getName();
      TableName linkedTable = regionInfoForFs.getTable();
      String linkedRegion = regionInfoForFs.getEncodedName();
      try {
        if (HFileLink.isHFileLink(hfileName)) {
          Matcher m = LINK_NAME_PATTERN.matcher(hfileName);
          if (!m.matches()) {
            throw new IllegalArgumentException(hfileName + " is not a valid HFileLink name!");
          }
          linkedTable = TableName.valueOf(m.group(1), m.group(2));
          linkedRegion = m.group(3);
          hfileName = m.group(4);
        }
        // must create back reference here
        tracker.createHFileLink(linkedTable, linkedRegion, hfileName, true);
        Path path =
          new Path(splitDir, HFileLink.createHFileLinkName(linkedTable, linkedRegion, hfileName));
        LOG.info("Created linkFile:" + path.toString() + " for child: " + hri.getEncodedName()
          + ", parent: " + regionInfoForFs.getEncodedName());
        return path;
      } catch (IOException e) {
        // if create HFileLink file failed, then just skip the error and create Reference file
        LOG.error("Create link file for " + hfileName + " for child " + hri.getEncodedName()
          + "failed, will create Reference file", e);
      }
    }
    // A reference to the bottom half of the hsf store file.
    Reference r =
      top ? Reference.createTopReference(splitRow) : Reference.createBottomReference(splitRow);
    tracker.createReference(r, p);
    return p;
  }
Write out a split reference. Package local so it doesnt leak out of regionserver.
@param hri         {@link RegionInfo} of the destination
@param familyName  Column Family Name
@param f           File to split.
@param splitRow    Split Row
@param top         True if we are referring to the top half of the hfile.
@param splitPolicy A split policy instance; be careful! May not be full populated; e.g. if this
                   method is invoked on the Master side, then the RegionSplitPolicy will NOT
                   have a reference to a Region.
@return Path to created reference.
hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionFileSystem.java