public StripeCompactionRequest selectCompaction(StripeInformationProvider si,
    List<HStoreFile> filesCompacting, boolean isOffpeak) throws IOException {
    // TODO: first cut - no parallel compactions. To have more fine grained control we
    // probably need structure more sophisticated than a list.
    if (!filesCompacting.isEmpty()) {
      LOG.debug("Not selecting compaction: " + filesCompacting.size() + " files compacting");
      return null;
    }

    // We are going to do variations of compaction in strict order of preference.
    // A better/more advanced approach is to use a heuristic to see which one is "more
    // necessary" at current time.

    // This can happen due to region split. We can skip it later; for now preserve
    // compact-all-things behavior.
    Collection<HStoreFile> allFiles = si.getStoreFiles();
    if (StoreUtils.hasReferences(allFiles)) {
      LOG.debug("There are references in the store; compacting all files");
      long targetKvs = estimateTargetKvs(allFiles, config.getInitialCount()).getFirst();
      SplitStripeCompactionRequest request =
        new SplitStripeCompactionRequest(allFiles, OPEN_KEY, OPEN_KEY, targetKvs);
      request.setMajorRangeFull();
      request.getRequest().setAfterSplit(true);
      return request;
    }

    int stripeCount = si.getStripeCount();
    List<HStoreFile> l0Files = si.getLevel0Files();

    // See if we need to make new stripes.
    boolean shouldCompactL0 =
      this.config.getLevel0MinFiles() <= l0Files.size() || allL0FilesExpired(si);
    if (stripeCount == 0) {
      if (!shouldCompactL0) {
        return null; // nothing to do.
      }
      return selectL0OnlyCompaction(si);
    }

    boolean canDropDeletesNoL0 = l0Files.isEmpty();
    if (shouldCompactL0) {
      if (!canDropDeletesNoL0) {
        // If we need to compact L0, see if we can add something to it, and drop deletes.
        StripeCompactionRequest result =
          selectSingleStripeCompaction(si, !shouldSelectL0Files(si), canDropDeletesNoL0, isOffpeak);
        if (result != null) {
          return result;
        }
      }
      LOG.debug("Selecting L0 compaction with " + l0Files.size() + " files");
      return selectL0OnlyCompaction(si);
    }

    // Try to delete fully expired stripes
    StripeCompactionRequest result = selectExpiredMergeCompaction(si, canDropDeletesNoL0);
    if (result != null) {
      return result;
    }

    // Ok, nothing special here, let's see if we need to do a common compaction.
    // This will also split the stripes that are too big if needed.
    return selectSingleStripeCompaction(si, false, canDropDeletesNoL0, isOffpeak);
  }
Stripe store implementation of compaction policy.
hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/compactions/StripeCompactionPolicy.java