void addEntry(IndexEntry entry, Offset fileEndOffset) throws StoreException {
    rwLock.writeLock().lock();
    try {
      if (sealed.get()) {
        throw new StoreException("IndexSegment : " + indexFile.getAbsolutePath() + " cannot add to a sealed index ",
            StoreErrorCodes.IllegalIndexOperation);
      }
      logger.trace("IndexSegment {} inserting key - {} value - offset {} size {} ttl {} "
              + "originalMessageOffset {} fileEndOffset {}", indexFile.getAbsolutePath(), entry.getKey(),
          entry.getValue().getOffset(), entry.getValue().getSize(), entry.getValue().getExpiresAtMs(),
          entry.getValue().getOriginalMessageOffset(), fileEndOffset);
      boolean isPresent = index.containsKey(entry.getKey());
      index.computeIfAbsent(entry.getKey(), key -> new ConcurrentSkipListSet<>()).add(entry.getValue());
      if (!isPresent) {
        bloomFilter.add(getStoreKeyBytes(entry.getKey()));
      }
      if (resetKeyInfo == null) {
        resetKeyInfo =
            new ResetKeyInfo(entry.getKey(), entry.getValue().getIndexValueType(), entry.getValue().getLifeVersion());
      }
      numberOfItems.incrementAndGet();
      sizeWritten.addAndGet(entry.getKey().sizeInBytes() + entry.getValue().getBytes().capacity());
      endOffset.set(fileEndOffset);
      long operationTimeInMs = entry.getValue().getOperationTimeInMs();
      if (operationTimeInMs == Utils.Infinite_Time) {
        lastModifiedTimeSec.set(time.seconds());
      } else if ((operationTimeInMs / Time.MsPerSec) > lastModifiedTimeSec.get()) {
        lastModifiedTimeSec.set(operationTimeInMs / Time.MsPerSec);
      }
      if (valueSize == VALUE_SIZE_INVALID_VALUE) {
        valueSize = entry.getValue().getBytes().capacity();
        logger.info("IndexSegment : {} setting value size to {} for index with start offset {}",
            indexFile.getAbsolutePath(), valueSize, startOffset);
      }
      int keySize = entry.getKey().sizeInBytes();
      if (keySize + valueSize > maxEntrySize) {
        maxEntrySize = keySize + valueSize;
        logger.info("IndexSegment : {} setting persisted entry size to {} of key {} for index with start offset {}",
            indexFile.getAbsolutePath(), maxEntrySize, entry.getKey().getLongForm(), startOffset);
      }
    } finally {
      rwLock.writeLock().unlock();
    }
  }
Adds an entry into the segment. The operation works only if the segment is read/write
@param entry The entry that needs to be added to the segment.
@param fileEndOffset The file end offset that this entry represents.
@throws StoreException
ambry-store/src/main/java/com/github/ambry/store/IndexSegment.java