public void onCompactionFinished() {
    if (bucketCount > 0) {
      // Compaction is finished, we need to reconstruct the log segments and physical storage usage in the scan result.
      scanLock.lock();
      try {
        long delay = indexScannerScheduledFuture.getDelay(TimeUnit.SECONDS);
        if (delay > 0) {
          // We haven't started the next index scanner tasks, just cancel it and reschedule.
          indexScannerScheduledFuture.cancel(false);
          indexScannerScheduledFuture = longLiveTaskScheduler.scheduleAtFixedRate(indexScanner, 0,
              TimeUnit.MILLISECONDS.toSeconds(bucketCount * bucketSpanTimeInMs), TimeUnit.SECONDS);
          logger.info("Reschedule index scanner task for store {}", storeId);
        } else {
          // Wait until the ongoing index scanner tasks is finished.
          if (!waitCondition.await(waitTimeoutInSecs, TimeUnit.SECONDS)) {
            logger.error("Timed out while waiting for BlobStoreStats index scan to complete for store {}", storeId);
          }
          indexScannerScheduledFuture.cancel(true);
          indexScannerScheduledFuture = longLiveTaskScheduler.scheduleAtFixedRate(indexScanner, 0,
              TimeUnit.MILLISECONDS.toSeconds(bucketCount * bucketSpanTimeInMs), TimeUnit.SECONDS);
          logger.info("Reschedule index scanner task after waiting for store {}", storeId);
        }
      } catch (InterruptedException e) {
        logger.error("Waiting for scanner to finish is interrupted for store {}", storeId);
      } finally {
        scanLock.unlock();
      }
    }
  }
Callback method when a cycle of compaction is finished.
ambry-store/src/main/java/com/github/ambry/store/BlobStoreStats.java