private CostBenefitInfo getBestCandidateToCompact(NavigableMap<LogSegmentName, Long> validDataPerLogSegments,
      long segmentCapacity, long segmentHeaderSize, long maxBlobSize, BlobStoreStats blobStoreStats) {
    Map.Entry<LogSegmentName, Long> firstEntry = validDataPerLogSegments.firstEntry();
    Map.Entry<LogSegmentName, Long> lastEntry = validDataPerLogSegments.lastEntry();
    CostBenefitInfo bestCandidateToCompact = null;
    boolean weightOnBenefit = storeConfig.storeStatsBasedWeightOnBenefitEnabled;

    // weigh more on compaction benefit
    // try to reclaim as many log segments as possible with reasonable cost.
    if (storeConfig.storeStatsBasedMiddleRangeCompactionIntervalInMs != 0) {
      bestCandidateToCompact =
          getMiddleRangeToCompact(validDataPerLogSegments, segmentCapacity, segmentHeaderSize, maxBlobSize,
              blobStoreStats);
      if (bestCandidateToCompact != null) {
        return bestCandidateToCompact;
      }
    }

    // weigh more on least IO effort
    // try to reclaim some log segments with the least IO effort
    while (firstEntry != null) {
      Map.Entry<LogSegmentName, Long> endEntry = lastEntry;
      while (endEntry != null && firstEntry.getKey().compareTo(endEntry.getKey()) <= 0) {
        CostBenefitInfo costBenefitInfo =
            getCostBenefitInfo(firstEntry.getKey(), endEntry.getKey(), validDataPerLogSegments, segmentCapacity,
                segmentHeaderSize, maxBlobSize, weightOnBenefit);
        if (costBenefitInfo.getBenefit() >= storeConfig.storeMinLogSegmentCountToReclaimToTriggerCompaction && (
            bestCandidateToCompact == null
                || costBenefitInfo.getCostBenefitRatio().compareTo(bestCandidateToCompact.getCostBenefitRatio()) < 0)) {
          bestCandidateToCompact = costBenefitInfo;
          logger.trace("Updating best candidate to compact to {} ", bestCandidateToCompact);
        }
        endEntry = validDataPerLogSegments.lowerEntry(endEntry.getKey());
      }
      firstEntry = validDataPerLogSegments.higherEntry(firstEntry.getKey());
    }
    return bestCandidateToCompact;
  }
Finds the best candidate to compact by finding the candidate with the best cost benefit ratio
@param validDataPerLogSegments the valid data size for each log segment in the form of a {@link NavigableMap} of segment names to
valid data sizes.
@param segmentCapacity Segment capacity of one {@link LogSegment}
@param segmentHeaderSize Segment header size of a {@link LogSegment}
@param maxBlobSize The max blob size
@param blobStoreStats the {@link BlobStoreStats}
@return the {@link CostBenefitInfo} for the best candidate to compact. {@code null} if there isn't any.
ambry-store/src/main/java/com/github/ambry/store/StatsBasedCompactionPolicy.java