private void pushPipelineToSnapshot() {
    int iterationsCnt = 0;
    boolean done = false;
    while (!done) {
      iterationsCnt++;
      VersionedSegmentsList segments = getImmutableSegments();
      pushToSnapshot(segments.getStoreSegments());
      // swap can return false in case the pipeline was updated by ongoing compaction
      // and the version increase, the chance of it happenning is very low
      // In Swap: don't close segments (they are in snapshot now) and don't update the region size
      done = swapPipelineWithNull(segments);
      if (iterationsCnt > 2) {
        // practically it is impossible that this loop iterates more than two times
        // (because the compaction is stopped and none restarts it while in snapshot request),
        // however stopping here for the case of the infinite loop causing by any error
        LOG.warn("Multiple unsuccessful attempts to push the compaction pipeline to snapshot,"
          + " while flushing to disk.");
        this.snapshot = SegmentFactory.instance().createImmutableSegment(getComparator());
        break;
      }
    }
  }
NOTE: When {@link CompactingMemStore#flushInMemory(MutableSegment)} calls this method, due to
concurrent writes and because we first add cell size to currActive.getDataSize and then
actually add cell to currActive.cellSet, it is possible that currActive.getDataSize could not
accommodate cellToAdd but currActive.cellSet is still empty if pending writes which not yet add
cells to currActive.cellSet,so for
{@link CompactingMemStore#flushInMemory(MutableSegment)},checkEmpty parameter is false. But if
{@link CompactingMemStore#snapshot} called this method,because there is no pending
write,checkEmpty parameter could be true.
hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/CompactingMemStore.java