@Override
  public void delete(List<MessageInfo> infos) throws StoreException {
    List<MessageInfo> infosToDelete = new ArrayList<>(infos.size());
    List<InputStream> inputStreams = new ArrayList<>();
    try {
      for (MessageInfo info : infos) {
        short lifeVersion = info.getLifeVersion();
        MessageInfo latestInfo = getMergedMessageInfo(info.getStoreKey(), messageInfos);
        if (latestInfo == null) {
          throw new StoreException("Cannot delete id " + info.getStoreKey() + " since it is not present in the index.",
              StoreErrorCodes.IDNotFound);
        }
        if (lifeVersion == MessageInfo.LIFE_VERSION_FROM_FRONTEND) {
          if (latestInfo.isDeleted()) {
            throw new StoreException(
                "Cannot delete id " + info.getStoreKey() + " since it is already deleted in the index.",
                StoreErrorCodes.IDDeleted);
          }
          lifeVersion = latestInfo.getLifeVersion();
        } else {
          if ((latestInfo.isDeleted() && latestInfo.getLifeVersion() >= info.getLifeVersion()) || (
              latestInfo.getLifeVersion() > info.getLifeVersion())) {
            throw new StoreException(
                "Cannot delete id " + info.getStoreKey() + " since it is already deleted in the index.",
                StoreErrorCodes.LifeVersionConflict);
          }
          lifeVersion = info.getLifeVersion();
        }
        MessageFormatInputStream stream =
            new DeleteMessageFormatInputStream(info.getStoreKey(), info.getAccountId(), info.getContainerId(),
                info.getOperationTimeMs(), lifeVersion);
        infosToDelete.add(new MessageInfo(info.getStoreKey(), stream.getSize(), true, info.isTtlUpdated(), false,
            info.getExpirationTimeInMs(), null, info.getAccountId(), info.getContainerId(), info.getOperationTimeMs(),
            lifeVersion));
        inputStreams.add(stream);
      }
      MessageFormatWriteSet writeSet =
          new MessageFormatWriteSet(new SequenceInputStream(Collections.enumeration(inputStreams)), infosToDelete,
              false);
      writeSet.writeTo(log);
      messageInfos.addAll(infosToDelete);
    } catch (Exception e) {
      throw (e instanceof StoreException ? (StoreException) e : new StoreException(e, StoreErrorCodes.UnknownError));
    }
  }
Log that stores all data in memory.
ambry-replication/src/test/java/com/github/ambry/replication/InMemoryStore.java