private StoreFindToken revalidateStoreFindToken(StoreFindToken token,
      ConcurrentSkipListMap<Offset, IndexSegment> indexSegments, boolean ignoreResetKey) throws StoreException {
    StoreFindToken revalidatedToken = token;
    Offset offset = token.getOffset();
    switch (token.getType()) {
      case Uninitialized:
        // nothing to do.
        break;
      case JournalBased:
        // A journal based token. The offset in journal based token is pointing to an IndexValue[IV], this IndexValue belongs
        // to an IndexSegment[IS]. And the offset should always be greater than or equal to IS's start offset. Calling
        // floorKey should return the IS's start offset. Since IV belongs to IS, the IS's start offset should have the
        // same LogSegmentName as the offset's LogSegmentName. But if floorKey is null or these two LogSegmentNames are
        // not the same, it means LogSegment is removed by compaction.
        Offset floorOffset = indexSegments.floorKey(offset);
        if (floorOffset == null || !floorOffset.getName().equals(offset.getName())) {
          if (shouldRebuildTokenBasedOnCompactionHistory && !sanityCheckFailed) {
            revalidatedToken = generateTokenBasedOnIndexSegmentOffset(token, indexSegments);
          } else {
            if (ignoreResetKey || token.getResetKey() == null) {
              revalidatedToken = new StoreFindToken();
            } else {
              // reset key is present in the token, we attempt to generate the new token based on reset key
              revalidatedToken = generateTokenBasedOnResetKey(token, indexSegments);
            }
          }
          metrics.journalBasedTokenResetCount.inc();
          logger.info("Index {}: Revalidated token {} because it is invalid for the index segment map", dataDir, token);
        }
        break;
      case IndexBased:
        // An index based token, but the offset is not in the segments, might be caused by the compaction
        if (!indexSegments.containsKey(offset)) {
          if (shouldRebuildTokenBasedOnCompactionHistory && !sanityCheckFailed) {
            revalidatedToken = generateTokenBasedOnIndexSegmentOffset(token, indexSegments);
          } else {
            if (!ignoreResetKey && token.getResetKey() != null) {
              // reset key is present in the token
              revalidatedToken = generateTokenBasedOnResetKey(token, indexSegments);
            } else {
              revalidatedToken = new StoreFindToken();
            }
          }
          metrics.indexBasedTokenResetCount.inc();
          logger.info("Index {}: Revalidated token {} because it is invalid for the index segment map", dataDir, token);
        }
        break;
      default:
        throw new IllegalStateException("Unrecognized token type: " + token.getType());
    }
    return revalidatedToken;
  }
Re-validates the {@code token} to ensure that it is consistent with the given view of {@code indexSegments}. If it
is not, a {@link FindTokenType#Uninitialized} token is returned.
@param token the {@link StoreFindToken} to revalidate.
@param indexSegments the view of the index segments to revalidate against.
@param ignoreResetKey whether to ignore reset key if a new token needs to be built.
@return {@code token} if is consistent with {@code indexSegments}, a new {@link FindTokenType#Uninitialized}
token otherwise.
ambry-store/src/main/java/com/github/ambry/store/PersistentIndex.java