public Optional<CompactionContext> requestCompaction(int priority,
    CompactionLifeCycleTracker tracker, User user) throws IOException {
    // don't even select for compaction if writes are disabled
    if (!this.areWritesEnabled()) {
      return Optional.empty();
    }
    // Before we do compaction, try to get rid of unneeded files to simplify things.
    removeUnneededFiles();

    final CompactionContext compaction = storeEngine.createCompaction();
    CompactionRequestImpl request = null;
    this.storeEngine.readLock();
    try {
      synchronized (filesCompacting) {
        // First, see if coprocessor would want to override selection.
        if (this.getCoprocessorHost() != null) {
          final List<HStoreFile> candidatesForCoproc = compaction.preSelect(this.filesCompacting);
          boolean override =
            getCoprocessorHost().preCompactSelection(this, candidatesForCoproc, tracker, user);
          if (override) {
            // Coprocessor is overriding normal file selection.
            compaction.forceSelect(new CompactionRequestImpl(candidatesForCoproc));
          }
        }

        // Normal case - coprocessor is not overriding file selection.
        if (!compaction.hasSelection()) {
          boolean isUserCompaction = priority == Store.PRIORITY_USER;
          boolean mayUseOffPeak =
            offPeakHours.isOffPeakHour() && offPeakCompactionTracker.compareAndSet(false, true);
          try {
            compaction.select(this.filesCompacting, isUserCompaction, mayUseOffPeak,
              forceMajor && filesCompacting.isEmpty());
          } catch (IOException e) {
            if (mayUseOffPeak) {
              offPeakCompactionTracker.set(false);
            }
            throw e;
          }
          assert compaction.hasSelection();
          if (mayUseOffPeak && !compaction.getRequest().isOffPeak()) {
            // Compaction policy doesn't want to take advantage of off-peak.
            offPeakCompactionTracker.set(false);
          }
        }
        if (this.getCoprocessorHost() != null) {
          this.getCoprocessorHost().postCompactSelection(this,
            ImmutableList.copyOf(compaction.getRequest().getFiles()), tracker,
            compaction.getRequest(), user);
        }
        // Finally, we have the resulting files list. Check if we have any files at all.
        request = compaction.getRequest();
        Collection<HStoreFile> selectedFiles = request.getFiles();
        if (selectedFiles.isEmpty()) {
          return Optional.empty();
        }

        addToCompactingFiles(selectedFiles);

        // If we're enqueuing a major, clear the force flag.
        this.forceMajor = this.forceMajor && !request.isMajor();

        // Set common request properties.
        // Set priority, either override value supplied by caller or from store.
        final int compactionPriority =
          (priority != Store.NO_PRIORITY) ? priority : getCompactPriority();
        request.setPriority(compactionPriority);

        if (request.isAfterSplit()) {
          // If the store belongs to recently splitted daughter regions, better we consider
          // them with the higher priority in the compaction queue.
          // Override priority if it is lower (higher int value) than
          // SPLIT_REGION_COMPACTION_PRIORITY
          final int splitHousekeepingPriority =
            Math.min(compactionPriority, SPLIT_REGION_COMPACTION_PRIORITY);
          request.setPriority(splitHousekeepingPriority);
          LOG.info(
            "Keeping/Overriding Compaction request priority to {} for CF {} since it"
              + " belongs to recently split daughter region {}",
            splitHousekeepingPriority, this.getColumnFamilyName(),
            getRegionInfo().getRegionNameAsString());
        }
        request.setDescription(getRegionInfo().getRegionNameAsString(), getColumnFamilyName());
        request.setTracker(tracker);
      }
    } finally {
      this.storeEngine.readUnlock();
    }

    if (LOG.isDebugEnabled()) {
      LOG.debug(this + " is initiating " + (request.isMajor() ? "major" : "minor") + " compaction"
        + (request.isAllFiles() ? " (all files)" : ""));
    }
    this.region.reportCompactionRequestStart(request.isMajor());
    return Optional.of(compaction);
  }
getter for CompactionProgress object
@return CompactionProgress object; can be null
hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HStore.java