CompletableFuture < ResultT > find ( ArrayView soughtKey , long bucketOffset , TimeoutTimer timer ) { int maxReadLength = getMaxReadLength ( ) ; // Read the Key at the current offset and check it against the sought one. AtomicLong offset = new AtomicLong ( bucketOffset ) ; CompletableFuture < ResultT > result = new CompletableFuture <> ( ) ; Futures . loop ( ( ) -> ! result . isDone ( ) , ( ) -> { ReadResult readResult = this . segment . read ( offset . get ( ) , maxReadLength , timer . getRemaining ( ) ) ; val reader = getReader ( soughtKey , offset . get ( ) , timer ) ; AsyncReadResultProcessor . process ( readResult , reader , this . executor ) ; return reader . getResult ( ) . thenComposeAsync ( r -> { SearchContinuation sc = processResult ( r , soughtKey ) ; if ( sc == SearchContinuation . ResultFound || sc == SearchContinuation . NoResult ) { // We either definitely found the result or definitely did not find the result. // In the case we did not find what we were looking for, we may still have some // partial result to return to the caller (i.e., a TableEntry with no value, but with // a version, which indicates a deleted entry (as opposed from an inexistent one). result . complete ( r ) ; } else { return this . getBackpointer . apply ( this . segment , offset . get ( ) , timer . getRemaining ( ) ) . thenAccept ( newOffset -> { offset . set ( newOffset ) ; if ( newOffset < 0 ) { // Could not find anything. result . complete ( null ) ; } } ) ; } return CompletableFuture . completedFuture ( null ) ; } , this . executor ) ; } , this . executor ) . exceptionally ( ex -> { result . completeExceptionally ( ex ) ; return null ; } ) ; return result ; }
Attempts to locate something in a TableBucket that matches a particular key .