private CompletableFuture < UpdateablePageCollection > applyUpdates ( Iterator < PageEntry > updates , TimeoutTimer timer ) { UpdateablePageCollection pageCollection = new UpdateablePageCollection ( this . state . get ( ) . length ) ; AtomicReference < PageWrapper > lastPage = new AtomicReference <> ( null ) ; val lastPageUpdates = new ArrayList < PageEntry > ( ) ; return Futures . loop ( updates :: hasNext , ( ) -> { // Locate the page where the update is to be executed. Do not apply it yet as it is more efficient // to bulk-apply multiple at once. Collect all updates for each Page, and only apply them once we have // "moved on" to another page. PageEntry next = updates . next ( ) ; return locatePage ( next . getKey ( ) , pageCollection , timer ) . thenAccept ( page -> { PageWrapper last = lastPage . get ( ) ; if ( page != last ) { // This key goes to a different page than the one we were looking at. if ( last != null ) { // Commit the outstanding updates. last . getPage ( ) . update ( lastPageUpdates ) ; } // Update the pointers. lastPage . set ( page ) ; lastPageUpdates . clear ( ) ; } // Record the current update. lastPageUpdates . add ( next ) ; } ) ; } , this . executor ) . thenApplyAsync ( v -> { // We need not forget to apply the last batch of updates from the last page. if ( lastPage . get ( ) != null ) { lastPage . get ( ) . getPage ( ) . update ( lastPageUpdates ) ; } return pageCollection ; } , this . executor ) ; }
Executes the given updates on the index . Loads up any necessary BTreePage instances in memory but does not persist the changes to the external data source nor does it reassign offsets to the modified pages perform splits etc .