func (bra *badReadAction) combine(action *msgs.Action, rmBal *rmBallot, txnId *common.TxnId, clockElem uint64) { newActionType := action.Which() braActionType := bra.action.Which() switch { case braActionType != msgs.ACTION_READ && newActionType != msgs.ACTION_READ: // They're both writes in some way. Just order the txns if clockElem > bra.clockElem || (clockElem == bra.clockElem && bra.txnId.Compare(txnId) == common.LT) { bra.set(action, rmBal, txnId, clockElem) } case braActionType == msgs.ACTION_READ && newActionType == msgs.ACTION_READ: braRead := bra.action.Read() newRead := action.Read() clockElem-- // If they read the same version, we really don't care. if !bytes.Equal(braRead.Version(), newRead.Version()) { // They read different versions, but which version was the latter? if clockElem > bra.clockElem { bra.set(action, rmBal, common.MakeTxnId(newRead.Version()), clockElem) } } case braActionType == msgs.ACTION_READ: if bytes.Equal(bra.txnId[:], txnId[:]) { // The write will obviously be in the past of the // existing read, but it's better to have the write // as we can update the client with the actual // value. bra.set(action, rmBal, txnId, clockElem) } else if clockElem > bra.clockElem { // The write is after than the read bra.set(action, rmBal, txnId, clockElem) } default: // Existing is not a read, but new is a read. newRead := action.Read() clockElem-- // If the read is a read of the existing write, better to keep the write if !bytes.Equal(bra.txnId[:], newRead.Version()) { if clockElem > bra.clockElem { // The read must be of some value which was written after our existing write. bra.set(action, rmBal, common.MakeTxnId(newRead.Version()), clockElem) } } } }
func (sts *SimpleTxnSubmitter) translateRead(action *msgs.Action, clientAction *cmsgs.ClientAction) { action.SetRead() clientRead := clientAction.Read() read := action.Read() read.SetVersion(clientRead.Version()) }