private void verifyStructure() {
    LOGGER.info("Verifying structure");
    List<LogSegmentName> srcSegmentNames = getSegmentNames(srcLog);
    List<LogSegmentName> tgtSegmentNames = getSegmentNames(tgtLog);
    List<LogSegmentName> expectedTgtSegmentNames = new ArrayList<>();

    // 1. Check that log segments that should exist, still exist and ones that should not, no longer do
    for (LogSegmentName srcSegmentName : srcSegmentNames) {
      if (segmentsCompactedNames.contains(srcSegmentName)) {
        assert !tgtSegmentNames.contains(srcSegmentName) :
            "Compacted log should not contain segment: " + srcSegmentName;
      } else {
        assert tgtSegmentNames.contains(srcSegmentName) : "Compacted log is missing segment: " + srcSegmentName;
        expectedTgtSegmentNames.add(srcSegmentName);
      }
    }

    // 2. Check that log segments that are newly created have the right generation number
    for (LogSegmentName segmentCompactedName : segmentsCompactedNames) {
      LogSegmentName tgtSegmentName = segmentCompactedName.getNextGenerationName();
      if (tgtSegmentNames.contains(tgtSegmentName)) {
        expectedTgtSegmentNames.add(tgtSegmentName);
      }
    }

    // 3. Check that the log segments that exist in the tgt are as expected
    Collections.sort(expectedTgtSegmentNames);
    assert tgtSegmentNames.equals(expectedTgtSegmentNames) : "Segment names in target log not as expected";

    // 4. Positions should be exclusive
    Set<Long> positionsSeen = new HashSet<>();
    for (LogSegmentName tgtSegmentName : tgtSegmentNames) {
      long position = tgtSegmentName.getPosition();
      assert !positionsSeen.contains(position) : "There are two log segments at position: " + position;
      positionsSeen.add(position);
    }

    int numTempFilesOnDisk = tgtDir.listFiles(BlobStoreCompactor.TEMP_LOG_SEGMENTS_FILTER).length;
    int filesOnDiskCount = tgtDir.listFiles(PersistentIndex.INDEX_SEGMENT_FILE_FILTER).length;
    int inMemIndexSegmentCount = tgtIndex.getIndexSegments().size();
    boolean tempCleanupFileExists = new File(tgtDir, BlobStoreCompactor.TARGET_INDEX_CLEAN_SHUTDOWN_FILE_NAME).exists();

    // 5. "_temp" files and the temp clean shutdown file should not exist
    // 6. The number of index files on disk must equal the number loaded into the PersistentIndex

    if (config.failOnStrayFiles) {
      assert numTempFilesOnDisk == 0 : "Some log segments haven't been cleaned";
      assert !tempCleanupFileExists : "The temp clean shutdown file has not been deleted";
      assert filesOnDiskCount == inMemIndexSegmentCount : "There are stray index segment files on disk";
    } else {
      if (numTempFilesOnDisk != 0) {
        LOGGER.warn("There are {} temp log segment files on disk", numTempFilesOnDisk);
      }
      if (tempCleanupFileExists) {
        LOGGER.warn("A temp clean shutdown file exists");
      }
      if (filesOnDiskCount != inMemIndexSegmentCount) {
        LOGGER.warn("There are {} index segment files on disk but {} in the in-mem index", filesOnDiskCount,
            inMemIndexSegmentCount);
      }
    }

    // 7. All index segments except the latest must have a bloom file and last modified times must be in non decreasing
    // order.
    long prevLastModTimeMs = Long.MIN_VALUE;
    Offset lastSegmentStartOffset = tgtIndex.getIndexSegments().lastKey();
    for (IndexSegment indexSegment : tgtIndex.getIndexSegments().values()) {
      if (!indexSegment.getStartOffset().equals(lastSegmentStartOffset)) {
        File indexSegmentFile = indexSegment.getFile();
        String bloomFileName = indexSegmentFile.getName()
            .replace(IndexSegment.INDEX_SEGMENT_FILE_NAME_SUFFIX, IndexSegment.BLOOM_FILE_NAME_SUFFIX);
        assert new File(tgtDir, bloomFileName).exists() : "There is no bloom file for: " + indexSegmentFile;
      }
      long lastModTimeMs = indexSegment.getLastModifiedTimeMs();
      assert
          lastModTimeMs >= prevLastModTimeMs :
          "Last modified time of " + indexSegment.getStartOffset() + " (" + lastModTimeMs + ") is "
              + "lesser than predecessor (" + prevLastModTimeMs + ")";
      prevLastModTimeMs = indexSegment.getLastModifiedTimeMs();
    }

    LOGGER.info("Verified structure");
  }
Verifies that the structure of the store is consistent (both in mem and on disk). See the documentation of the
class for details on the verifications.
ambry-tools/src/main/java/com/github/ambry/store/CompactionVerifier.java