private boolean isDeleteTombstoneRemovable(IndexEntry deleteIndexEntry, IndexSegment currentIndexSegment)
      throws StoreException {
    if (srcIndex.isExpired(deleteIndexEntry.getValue())) {
      return true;
    }
    if (remoteTokenTracker == null) {
      return false;
    }
    for (Map.Entry<String, Pair<Long, FindToken>> entry : remoteTokenTracker.getPeerReplicaAndToken().entrySet()) {
      Pair<Long, FindToken> pair = entry.getValue();
      // Ignore this peer if the last active replication's timestamp of this peer is longer than the pre-configured days.
      if (ignoredOfflinePeers.contains(entry.getKey())) {
        if (logger.isTraceEnabled()) {
          logger.trace(
              "Store {}: dealing with delete index entry: key {}, offset {}, peer {}'s last active time is {}, ignore it",
              dataDir, deleteIndexEntry.getKey(), deleteIndexEntry.getValue().getOffset(), entry.getKey(),
              pair.getFirst());
        }
        continue;
      }
      FindToken token = srcIndex.resetTokenIfRequired((StoreFindToken) pair.getSecond());
      if (!token.equals(pair.getSecond())) {
        // incarnation id has changed or there is unclean shutdown
        return false;
      }
      token = srcIndex.revalidateFindToken(pair.getSecond());
      if (!token.equals(pair.getSecond())) {
        // the log segment (token refers to) has been compacted already
        return false;
      }
      switch (token.getType()) {
        case Uninitialized:
          return false;
        case JournalBased:
          // if code reaches here, it means the journal-based token is valid (didn't get reset). Since compaction always
          // performs on segments out of journal, this journal-based token must be past the delete tombstone.
          break;
        case IndexBased:
          // if code reaches here, the index-based token is valid (didn't get reset). We check two following rules:
          // 1. token's index segment is behind delete tombstone's index segment
          // 2. if they are in the same segment, compare the store key (sealed index segment is sorted based on key)
          StoreFindToken indexBasedToken = (StoreFindToken) token;
          if (indexBasedToken.getOffset().compareTo(currentIndexSegment.getStartOffset()) < 0) {
            // index-based token is ahead of current index segment (hasn't reached this delete tombstone)
            return false;
          }
          if (indexBasedToken.getOffset().compareTo(currentIndexSegment.getStartOffset()) == 0) {
            // index-based token refers to current index segment, we need to compare the key
            if (indexBasedToken.getStoreKey().compareTo(deleteIndexEntry.getKey()) <= 0) {
              return false;
            }
          }
          // if tokens start offset > current index segment start offset, then token is obviously past tombstone
          break;
        default:
          throw new IllegalArgumentException("Unsupported token type in compaction: " + token.getType());
      }
    }
    srcMetrics.permanentDeleteTombstonePurgeCount.inc();
    return true;
  }
Check if given delete tombstone is removable. There are two cases where delete tombstone can be safely removed:
1. delete record has finite expiration time and it has expired already;
2. all peer replica tokens have passed position of this delete (That is, they have replicated this delete already)
@param deleteIndexEntry the {@link IndexEntry} associated with delete tombstone
@param currentIndexSegment the {@link IndexSegment} delete tombstone comes from.
@return {@code true} if this delete tombstone can be safely removed. {@code false} otherwise.
ambry-store/src/main/java/com/github/ambry/store/BlobStoreCompactor.java