docs: private static SegmentsToCompact findSegmentsToCompact(
        final CompactibleTimelineObjectHolderCursor compactibleTimelineObjectHolderCursor,
        final DataSourceCompactionConfig config
    )
    {
      final boolean keepSegmentGranularity = config.isKeepSegmentGranularity();
      final long inputSegmentSize = config.getInputSegmentSizeBytes();
      final int maxNumSegmentsToCompact = config.getMaxNumSegmentsToCompact();
      final SegmentsToCompact segmentsToCompact = new SegmentsToCompact();
  
      // Finds segments to compact together while iterating timeline from latest to oldest
      while (compactibleTimelineObjectHolderCursor.hasNext()
             && segmentsToCompact.getTotalSize() < inputSegmentSize
             && segmentsToCompact.getNumSegments() < maxNumSegmentsToCompact) {
        final TimelineObjectHolder<String, DataSegment> timeChunkHolder = Preconditions.checkNotNull(
            compactibleTimelineObjectHolderCursor.get(),
            "timelineObjectHolder"
        );
        final List<PartitionChunk<DataSegment>> chunks = Lists.newArrayList(timeChunkHolder.getObject().iterator());
        final long timeChunkSizeBytes = chunks.stream().mapToLong(chunk -> chunk.getObject().getSize()).sum();
  
        final boolean isSameOrAbuttingInterval;
        final Interval lastInterval = segmentsToCompact.getIntervalOfLastSegment();
        if (lastInterval == null) {
          isSameOrAbuttingInterval = true;
        } else {
          final Interval currentInterval = chunks.get(0).getObject().getInterval();
          isSameOrAbuttingInterval = currentInterval.isEqual(lastInterval) || currentInterval.abuts(lastInterval);
        }
  
        // The segments in a holder should be added all together or not.
        final boolean isCompactibleSize = SegmentCompactorUtil.isCompactibleSize(
            inputSegmentSize,
            segmentsToCompact.getTotalSize(),
            timeChunkSizeBytes
        );
        final boolean isCompactibleNum = SegmentCompactorUtil.isCompactibleNum(
            maxNumSegmentsToCompact,
            segmentsToCompact.getNumSegments(),
            chunks.size()
        );
        if (isCompactibleSize
            && isCompactibleNum
            && isSameOrAbuttingInterval
            && (!keepSegmentGranularity || segmentsToCompact.isEmpty())) {
          chunks.forEach(chunk -> segmentsToCompact.add(chunk.getObject()));
        } else {
          if (segmentsToCompact.getNumSegments() > 1) {
            // We found some segmens to compact and cannot add more. End here.
            return segmentsToCompact;
          } else {
            if (!SegmentCompactorUtil.isCompactibleSize(inputSegmentSize, 0, timeChunkSizeBytes)) {
              final DataSegment segment = chunks.get(0).getObject();
              segmentsToCompact.clear();
              log.warn(
                  "shardSize[%d] for dataSource[%s] and interval[%s] is larger than inputSegmentSize[%d]."
                  + " Continue to the next shard.",
                  timeChunkSizeBytes,
                  segment.getDataSource(),
                  segment.getInterval(),
                  inputSegmentSize
              );
            } else if (maxNumSegmentsToCompact < chunks.size()) {
              final DataSegment segment = chunks.get(0).getObject();
              segmentsToCompact.clear();
              log.warn(
                  "The number of segments[%d] for dataSource[%s] and interval[%s] is larger than "
                  + "maxNumSegmentsToCompact[%d]. If you see lots of shards are being skipped due to too many "
                  + "segments, consider increasing 'numTargetCompactionSegments' and "
                  + "'druid.indexer.runner.maxZnodeBytes'. Continue to the next shard.",
                  chunks.size(),
                  segment.getDataSource(),
                  segment.getInterval(),
                  maxNumSegmentsToCompact
              );
            } else {
              if (segmentsToCompact.getNumSegments() == 1) {
                // We found a segment which is smaller than targetCompactionSize but too large to compact with other
                // segments. Skip this one.
                segmentsToCompact.clear();
                chunks.forEach(chunk -> segmentsToCompact.add(chunk.getObject()));
              } else {
                throw new ISE(
                    "Cannot compact segments[%s]. shardBytes[%s], numSegments[%s] "
                    + "with current segmentsToCompact[%s]",
                    chunks.stream().map(PartitionChunk::getObject).collect(Collectors.toList()),
                    timeChunkSizeBytes,
                    chunks.size(),
                    segmentsToCompact
                );
              }
            }
          }
        }
  
        compactibleTimelineObjectHolderCursor.next();
      }
  
      if (segmentsToCompact.getNumSegments() == 1) {
        // Don't compact a single segment
        segmentsToCompact.clear();
      }
  
      return segmentsToCompact;
    }