@Override
  public void updateReaders(List<HStoreFile> sfs, List<KeyValueScanner> memStoreScanners)
    throws IOException {
    if (CollectionUtils.isEmpty(sfs) && CollectionUtils.isEmpty(memStoreScanners)) {
      return;
    }
    boolean updateReaders = false;
    flushLock.lock();
    try {
      if (!closeLock.tryLock()) {
        // The reason for doing this is that when the current store scanner does not retrieve
        // any new cells, then the scanner is considered to be done. The heap of this scanner
        // is not closed till the shipped() call is completed. Hence in that case if at all
        // the partial close (close (false)) has been called before updateReaders(), there is no
        // need for the updateReaders() to happen.
        LOG.debug("StoreScanner already has the close lock. There is no need to updateReaders");
        // no lock acquired.
        clearAndClose(memStoreScanners);
        return;
      }
      // lock acquired
      updateReaders = true;
      if (this.closing) {
        LOG.debug("StoreScanner already closing. There is no need to updateReaders");
        clearAndClose(memStoreScanners);
        return;
      }
      flushed = true;
      final boolean isCompaction = false;
      boolean usePread = get || scanUsePread;
      // SEE HBASE-19468 where the flushed files are getting compacted even before a scanner
      // calls next(). So its better we create scanners here rather than next() call. Ensure
      // these scanners are properly closed() whether or not the scan is completed successfully
      // Eagerly creating scanners so that we have the ref counting ticking on the newly created
      // store files. In case of stream scanners this eager creation does not induce performance
      // penalty because in scans (that uses stream scanners) the next() call is bound to happen.
      List<KeyValueScanner> scanners =
        store.getScanners(sfs, cacheBlocks, get, usePread, isCompaction, matcher,
          scan.getStartRow(), scan.getStopRow(), this.readPt, false, isOnlyLatestVersionScan(scan));
      flushedstoreFileScanners.addAll(scanners);
      if (!CollectionUtils.isEmpty(memStoreScanners)) {
        clearAndClose(memStoreScannersAfterFlush);
        memStoreScannersAfterFlush.addAll(memStoreScanners);
      }
    } finally {
      flushLock.unlock();
      if (updateReaders) {
        closeLock.unlock();
      }
    }
    // Let the next() call handle re-creating and seeking
  }
See {@link #trySkipToNextRow(ExtendedCell)}
@param cell current cell
@return true means skip to next column, false means not
hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java