IndexValue getIndexValueOfLastPut() throws StoreException {
      IndexValue indexValueOfLastPut = null;
      ByteBuffer readBuf = serEntries.duplicate();
      int numOfIndexEntries = numberOfEntries(readBuf);
      NavigableSet<IndexValue> values = new TreeSet<>();
      for (int i = 0; i < numOfIndexEntries; i++) {
        StoreKey key = getKeyAt(readBuf, i);
        values.clear();
        getAllValuesFromMmap(readBuf, key, i, numOfIndexEntries, values);
        for (IndexValue indexValue : values) {
          // FLAGS_DEFAULT_VALUE means PUT record
          if (indexValue.getFlags() == IndexValue.FLAGS_DEFAULT_VALUE && (indexValueOfLastPut == null
              || indexValue.compareTo(indexValueOfLastPut) > 0)) {
            indexValueOfLastPut = indexValue;
            // note that values set contains all entries associated with specific key, so there are at most 3 entries in
            // this set (one PUT, one TTL Update and one DELETE). Due to nature of log, PUT always comes first. And if we
            // already find PUT, we can jump out of the inner loop.
            break;
          }
        }
      }
      return indexValueOfLastPut;
    }
@return index value of last PUT record in this index segment. Return {@code null} if no PUT is found
ambry-store/src/main/java/com/github/ambry/store/IndexSegment.java