private boolean copyDataByLogSegment(LogSegment logSegmentToCopy, FileSpan duplicateSearchSpan)
      throws IOException, StoreException {
    logger.debug("Copying data from {}", logSegmentToCopy);
    long logSegmentStartTime = time.milliseconds();
    for (Offset indexSegmentStartOffset : getIndexSegmentDetails(logSegmentToCopy.getName()).keySet()) {
      IndexSegment indexSegmentToCopy = srcIndex.getIndexSegments().get(indexSegmentStartOffset);
      if (indexSegmentToCopy == null) {
        // This should not happen
        Offset startOffsetOfTheSegment = new Offset(logSegmentToCopy.getName(), 0);
        Offset endOffsetOfTheSegment = new Offset(logSegmentToCopy.getName().getNextPositionName(), 0);
        // start and end offset would make sure that we copy all the index segments for the log segment.
        Set<Offset> validOffsets =
            srcIndex.getIndexSegments().subMap(startOffsetOfTheSegment, endOffsetOfTheSegment).keySet();
        logger.error("Can't find index segment for start offset {} with {}, the valid offset are {}",
            indexSegmentStartOffset, storeId, validOffsets);
        throw new IllegalStateException("Can't find index segment for start off " + indexSegmentStartOffset);
      }
      logger.info("Processing index segment {} with {}", indexSegmentToCopy.getFile(), storeId);
      long startTime = SystemTime.getInstance().milliseconds();
      if (needsCopying(indexSegmentToCopy.getEndOffset()) && !copyDataByIndexSegment(logSegmentToCopy,
          indexSegmentToCopy, duplicateSearchSpan)) {
        // there is a shutdown in progress or there was no space to copy all entries.
        logger.info("Did not copy all entries in {} with {} (either because there is no space or there is a shutdown)",
            indexSegmentToCopy.getFile(), storeId);
        return false;
      }
      srcMetrics.compactionCopyDataByIndexSegmentTimeInMs.update(SystemTime.getInstance().milliseconds() - startTime,
          TimeUnit.MILLISECONDS);
    }
    srcMetrics.compactionCopyDataByLogSegmentTimeInMs.update(
        SystemTime.getInstance().milliseconds() - logSegmentStartTime, TimeUnit.MILLISECONDS);
    return true;
  }
Copies data from the provided log segment into the target log (swap spaces).
@param logSegmentToCopy the {@link LogSegment} to copy from.
@param duplicateSearchSpan the {@link FileSpan} in which to search for duplicates.
@return {@code true} if all the records in the log segment were copied. {@code false} if some records were not
copied either because there was no more capacity or because a shutdown was initiated.
@throws IOException if there were I/O errors during copying.
@throws StoreException if there are any problems reading or writing to store components.
ambry-store/src/main/java/com/github/ambry/store/BlobStoreCompactor.java