code: private ReadResultEntryBase createDataNotAvailableRead(long streamSegmentOffset, int maxLength) {
          maxLength = getLengthUntilNextEntry(streamSegmentOffset, maxLength);
          long storageLength = this.metadata.getStorageLength();
          if (streamSegmentOffset < storageLength) {
              // Requested data exists in Storage.
              // Determine actual read length (until Storage Length) and make sure it does not exceed maxLength.
              long actualReadLength = storageLength - streamSegmentOffset;
              if (actualReadLength > maxLength) {
                  actualReadLength = maxLength;
              }
  
              return createStorageRead(streamSegmentOffset, (int) actualReadLength);
          } else {
              // Note that Future Reads are not necessarily tail reads. They mean that we cannot return a result given
              // the current state of the metadata. An example of when we might return a Future Read that is not a tail read
              // is when we receive a read request immediately after recovery, but before the StorageWriter has had a chance
              // to refresh the Storage state (the metadata may be a bit out of date). In that case, we record a Future Read
              // which will be completed when the StorageWriter invokes triggerFutureReads() upon refreshing the info.
              return createFutureRead(streamSegmentOffset, maxLength);
          }
      }
docs: Creates a ReadResultEntry that is a placeholder for data that is not currently available in memory.
  
  @param streamSegmentOffset The Offset in the StreamSegment where to the ReadResultEntry starts at.
  @param maxLength           The maximum length of the Read, from the Offset of this ReadResultEntry.