protected Map<Cell,Long> detectWriteAlreadyCommittedInternal(TableReference tableRef,Map<Cell,Long> keysToLoad,@Output Set<CellConflict> spanningWrites,@Output Set<CellConflict> dominatingWrites,TransactionService transactionService){
  Map<Cell,Long> rawResults=keyValueService.getLatestTimestamps(tableRef,keysToLoad);
  Map<Long,Long> commitTimestamps=getCommitTimestamps(tableRef,rawResults.values(),false);
  Map<Cell,Long> keysToDelete=Maps.newHashMapWithExpectedSize(0);
  for (  Map.Entry<Cell,Long> e : rawResults.entrySet()) {
    Cell key=e.getKey();
    long theirStartTimestamp=e.getValue();
    AssertUtils.assertAndLog(theirStartTimestamp != getStartTimestamp(),"Timestamp reuse is bad:%d",getStartTimestamp());
    Long theirCommitTimestamp=commitTimestamps.get(theirStartTimestamp);
    if (theirCommitTimestamp == null || theirCommitTimestamp == TransactionConstants.FAILED_COMMIT_TS) {
      keysToDelete.put(key,theirStartTimestamp);
      continue;
    }
    AssertUtils.assertAndLog(theirCommitTimestamp != getStartTimestamp(),"Timestamp reuse is bad:%d",getStartTimestamp());
    if (theirStartTimestamp > getStartTimestamp()) {
      dominatingWrites.add(Cells.createConflictWithMetadata(keyValueService,tableRef,key,theirStartTimestamp,theirCommitTimestamp));
    }
 else     if (theirCommitTimestamp > getStartTimestamp()) {
      spanningWrites.add(Cells.createConflictWithMetadata(keyValueService,tableRef,key,theirStartTimestamp,theirCommitTimestamp));
    }
  }
  if (!keysToDelete.isEmpty()) {
    if (!rollbackFailedTransactions(tableRef,keysToDelete,commitTimestamps,transactionService)) {
      return keysToLoad;
    }
  }
  return keysToDelete;
}

protected Map < Cell , Long > detectWriteAlreadyCommittedInternal ( TableReference tableRef , Map < Cell , Long > keysToLoad , @ Output Set < CellConflict > spanningWrites , @ Output Set < CellConflict > dominatingWrites , TransactionService transactionService ) { Map < Cell , Long > rawResults = keyValueService . getLatestTimestamps ( tableRef , keysToLoad ) ; Map < Long , Long > commitTimestamps = getCommitTimestamps ( tableRef , rawResults . values ( ) , false ) ; Map < Cell , Long > keysToDelete = Maps . newHashMapWithExpectedSize ( 0 ) ; for ( Map . Entry < Cell , Long > e : rawResults . entrySet ( ) ) { Cell key = e . getKey ( ) ; long theirStartTimestamp = e . getValue ( ) ; AssertUtils . assertAndLog ( theirStartTimestamp != getStartTimestamp ( ) , "Timestamp reuse is bad:%d" , getStartTimestamp ( ) ) ; Long theirCommitTimestamp = commitTimestamps . get ( theirStartTimestamp ) ; if ( theirCommitTimestamp == null || theirCommitTimestamp == TransactionConstants . FAILED_COMMIT_TS ) { keysToDelete . put ( key , theirStartTimestamp ) ; continue ; } AssertUtils . assertAndLog ( theirCommitTimestamp != getStartTimestamp ( ) , "Timestamp reuse is bad:%d" , getStartTimestamp ( ) ) ; if ( theirStartTimestamp > getStartTimestamp ( ) ) { dominatingWrites . add ( Cells . createConflictWithMetadata ( keyValueService , tableRef , key , theirStartTimestamp , theirCommitTimestamp ) ) ; } else if ( theirCommitTimestamp > getStartTimestamp ( ) ) { spanningWrites . add ( Cells . createConflictWithMetadata ( keyValueService , tableRef , key , theirStartTimestamp , theirCommitTimestamp ) ) ; } } if ( ! keysToDelete . isEmpty ( ) ) { if ( ! rollbackFailedTransactions ( tableRef , keysToDelete , commitTimestamps , transactionService ) ) { return keysToLoad ; } } return keysToDelete ; }
this will return the set of keys that need to be retried . it will output any conflicts it finds into the output params .
