private CompletableReadResultEntry getSingleReadResultEntry ( long resultStartOffset , int maxLength ) { Exceptions . checkNotClosed ( this . closed , this ) ; if ( maxLength < 0 ) { // Nothing to read. return null ; } CompletableReadResultEntry result = null ; // Check to see if we are trying to read beyond the last offset of a sealed StreamSegment. ReadAvailability ra = checkReadAvailability ( resultStartOffset , false ) ; if ( ra == ReadAvailability . BeyondLastOffset ) { result = new EndOfStreamSegmentReadResultEntry ( resultStartOffset , maxLength ) ; } else if ( ra == ReadAvailability . BeforeStartOffset ) { result = new TruncatedReadResultEntry ( resultStartOffset , maxLength , this . metadata . getStartOffset ( ) ) ; } else { // Look up an entry in the index that contains our requested start offset. synchronized ( this . lock ) { ReadIndexEntry indexEntry = this . indexEntries . getFloor ( resultStartOffset ) ; if ( indexEntry == null ) { // No data in the index or we have at least one entry and the ResultStartOffset is before the Start Offset // of the first entry in the index. Use the metadata to figure out whether to return a Storage or Future Read. result = createDataNotAvailableRead ( resultStartOffset , maxLength ) ; } else { // We have an entry. Let's see if it's valid or not. if ( resultStartOffset > indexEntry . getLastStreamSegmentOffset ( ) ) { // ResultStartOffset is beyond the End Offset of this entry. This means either: // 1. This is the last entry and ResultStartOffset is after it. OR // 2. We have a gap in our entries, and ResultStartOffset is somewhere in there. result = createDataNotAvailableRead ( resultStartOffset , maxLength ) ; } else if ( indexEntry . isDataEntry ( ) ) { // ResultStartOffset is after the StartOffset and before the End Offset of this entry. result = createMemoryRead ( indexEntry , resultStartOffset , maxLength , true ) ; } else if ( indexEntry instanceof RedirectIndexEntry ) { // ResultStartOffset is after the StartOffset and before the End Offset of this entry, but this // is a Redirect; reissue the request to the appropriate index. result = createRedirectedRead ( resultStartOffset , maxLength , ( RedirectIndexEntry ) indexEntry ) ; } } } } // Just before exiting, check we are returning something. We should always return something if we coded this correctly. assert result != null : String . format ( "Reached the end of getSingleReadResultEntry(id=%d, offset=%d, length=%d) " + "with no plausible result in sight. This means we missed a case." , this . metadata . getId ( ) , resultStartOffset , maxLength ) ; return result ; }
Returns the first ReadResultEntry that matches the specified search parameters .