public Future<RecoveryInfo> applyBufferedUpdates(){
  versionInfo.blockUpdates();
  try {
    cancelApplyBufferUpdate=false;
    if (state != State.BUFFERING)     return null;
    operationFlags&=~FLAG_GAP;
    if (tlog == null) {
      state=State.ACTIVE;
      return null;
    }
    tlog.incref();
    state=State.APPLYING_BUFFERED;
  }
  finally {
    versionInfo.unblockUpdates();
  }
  if (recoveryExecutor.isShutdown()) {
    tlog.decref();
    throw new RuntimeException("executor is not running...");
  }
  ExecutorCompletionService<RecoveryInfo> cs=new ExecutorCompletionService<>(recoveryExecutor);
  LogReplayer replayer=new LogReplayer(Arrays.asList(new TransactionLog[]{tlog}),true);
  return cs.submit(replayer,recoveryInfo);
}

public Future < RecoveryInfo > applyBufferedUpdates ( ) { versionInfo . blockUpdates ( ) ; try { cancelApplyBufferUpdate = false ; if ( state != State . BUFFERING ) return null ; operationFlags &= ~ FLAG_GAP ; if ( tlog == null ) { state = State . ACTIVE ; return null ; } tlog . incref ( ) ; state = State . APPLYING_BUFFERED ; } finally { versionInfo . unblockUpdates ( ) ; } if ( recoveryExecutor . isShutdown ( ) ) { tlog . decref ( ) ; throw new RuntimeException ( "executor is not running..." ) ; } ExecutorCompletionService < RecoveryInfo > cs = new ExecutorCompletionService < > ( recoveryExecutor ) ; LogReplayer replayer = new LogReplayer ( Arrays . asList ( new TransactionLog [ ] { tlog } ) , true ) ; return cs . submit ( replayer , recoveryInfo ) ; }
returns the future to wait on , or null if no replay was needed
