func BallotAccumulatorFromData(txnId *common.TxnId, txn *msgs.Txn, outcome *outcomeEqualId, instances *msgs.InstancesForVar_List) *BallotAccumulator { ba := NewBallotAccumulator(txnId, txn) ba.outcome = outcome for idx, l := 0, instances.Len(); idx < l; idx++ { // All instances that went to disk must be complete. But in the // case of a retry, not all instances must be complete before // going to disk. ba.incompleteVars-- instancesForVar := instances.At(idx) acceptedInstances := instancesForVar.Instances() vUUId := common.MakeVarUUId(instancesForVar.VarId()) vBallot := ba.vUUIdToBallots[*vUUId] rmBals := rmBallots(make([]*rmBallot, acceptedInstances.Len())) vBallot.rmToBallot = rmBals for idy, m := 0, acceptedInstances.Len(); idy < m; idy++ { acceptedInstance := acceptedInstances.At(idy) ballot := acceptedInstance.Ballot() rmBal := &rmBallot{ instanceRMId: common.RMId(acceptedInstance.RmId()), ballot: eng.BallotFromCap(&ballot), roundNumber: paxosNumber(acceptedInstance.RoundNumber()), } rmBals[idy] = rmBal } result := instancesForVar.Result() vBallot.result = eng.BallotFromCap(&result) } return ba }
// For every vUUId involved in this txn, we should see fInc * ballots: // one from each RM voting for each vUUId. rmId is the paxos // instanceRMId. func (ba *BallotAccumulator) BallotReceived(instanceRMId common.RMId, inst *instance, vUUId *common.VarUUId, txn *msgs.Txn) *outcomeEqualId { if isDeflated(ba.Txn) && !isDeflated(txn) { ba.Txn = txn } vBallot := ba.vUUIdToBallots[*vUUId] if vBallot.rmToBallot == nil { vBallot.rmToBallot = rmBallots(make([]*rmBallot, 0, vBallot.voters)) } ballot := eng.BallotFromCap(inst.accepted) found := false for idx, rBal := range vBallot.rmToBallot { if found = rBal.instanceRMId == instanceRMId; found { vBallot.rmToBallot[idx].ballot = ballot break } } if !found { rmBal := &rmBallot{ instanceRMId: instanceRMId, ballot: ballot, roundNumber: inst.acceptedNum, } vBallot.rmToBallot = append(vBallot.rmToBallot, rmBal) if len(vBallot.rmToBallot) == vBallot.voters { ba.incompleteVars-- } if len(vBallot.rmToBallot) >= vBallot.voters { vBallot.rmToBallot.Sort() } } if len(vBallot.rmToBallot) >= vBallot.voters { vBallot.result = nil ba.dirty = true } return ba.determineOutcome() }