code: private void addToReadIndex(StorageOperation operation) {
          try {
              if (operation instanceof StreamSegmentAppendOperation) {
                  // Record a StreamSegmentAppendOperation. Just in case, we also support this type of operation, but we need to
                  // log a warning indicating so. This means we do not optimize memory properly, and we end up storing data
                  // in two different places.
                  StreamSegmentAppendOperation appendOperation = (StreamSegmentAppendOperation) operation;
                  this.readIndex.append(appendOperation.getStreamSegmentId(),
                          appendOperation.getStreamSegmentOffset(),
                          appendOperation.getData());
              } else if (operation instanceof MergeSegmentOperation) {
                  // Record a MergeSegmentOperation. We call beginMerge here, and the StorageWriter will call completeMerge.
                  MergeSegmentOperation mergeOperation = (MergeSegmentOperation) operation;
                  this.readIndex.beginMerge(mergeOperation.getStreamSegmentId(),
                          mergeOperation.getStreamSegmentOffset(),
                          mergeOperation.getSourceSegmentId());
              } else {
                  assert !(operation instanceof CachedStreamSegmentAppendOperation)
                          : "attempted to add a CachedStreamSegmentAppendOperation to the ReadIndex";
              }
          } catch (ObjectClosedException | StreamSegmentNotExistsException ex) {
              // The Segment is in the process of being deleted. We usually end up in here because a concurrent delete
              // request has updated the metadata while we were executing.
              log.warn("Not adding operation '{}' to ReadIndex because it refers to a deleted StreamSegment.", operation);
          }
      }
docs: Registers the given operation in the ReadIndex.
  
  @param operation The operation to register.