BlobReadOptions getRandomPutEntryReadOptions() {
    rwLock.readLock().lock();
    try {
      ConcurrentSkipListMap<Offset, IndexSegment> indexSegments = validIndexSegments;
      if (indexSegments.isEmpty()) {
        return null;
      }
      long start = System.currentTimeMillis();
      ArrayList<Offset> indexSegmentOffsets = new ArrayList<>(indexSegments.keySet());
      while (!indexSegmentOffsets.isEmpty()) {
        int idx = ThreadLocalRandom.current().nextInt(indexSegmentOffsets.size());
        Offset offset = indexSegmentOffsets.get(idx);
        IndexSegment segment = indexSegments.get(offset);
        if (segment != null) {
          try {
            IndexEntry indexEntry = segment.getFirstPutEntry();
            if (indexEntry != null) {
              metrics.getRandomPutEntryReadOptionsInMs.update(System.currentTimeMillis() - start);
              return fromIndexValue(indexEntry.getKey(), indexEntry.getValue());
            } else {
              logger.trace("Store {}, offset {} index segment doesn't have any put entry, move on", dataDir, offset);
            }
          } catch (Exception e) {
            logger.error("Store {}, offset {} failed to get the first put entry, move on", dataDir, offset, e);
          }
        } else {
          logger.trace("Store {}, offset {} doesn't exist when getting a random put entry", dataDir, offset);
        }
        // Remove the offset at the idx by swapping it with last element and pop the last element
        indexSegmentOffsets.set(idx, indexSegmentOffsets.get(indexSegmentOffsets.size() - 1));
        indexSegmentOffsets.remove(indexSegmentOffsets.size() - 1);
      }
      return null;
    } finally {
      rwLock.readLock().unlock();
    }
  }
Get a random PUT entry and its {@link BlobReadOptions}. Return null if there is no PUT entry found
in this index.
@return
ambry-store/src/main/java/com/github/ambry/store/PersistentIndex.java