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 }
func NewBallotAccumulator(txnId *common.TxnId, txn *msgs.Txn) *BallotAccumulator { actions := txn.Actions() ba := &BallotAccumulator{ Txn: txn, txnId: txnId, vUUIdToBallots: make(map[common.VarUUId]*varBallot), outcome: nil, incompleteVars: actions.Len(), dirty: false, } vBallots := make([]varBallot, ba.incompleteVars) for idx := 0; idx < ba.incompleteVars; idx++ { action := actions.At(idx) vUUId := common.MakeVarUUId(action.VarId()) vBallot := &vBallots[idx] vBallot.vUUId = vUUId ba.vUUIdToBallots[*vUUId] = vBallot } allocs := txn.Allocations() for idx, l := 0, allocs.Len(); idx < l; idx++ { alloc := allocs.At(idx) if alloc.Active() == 0 { break } indices := alloc.ActionIndices() for idy, m := 0, indices.Len(); idy < m; idy++ { vBallots[int(indices.At(idy))].voters++ } } return ba }
func VarFromData(data []byte, exe *dispatcher.Executor, disk *mdbs.MDBServer, vm *VarManager) (*Var, error) { seg, _, err := capn.ReadFromMemoryZeroCopy(data) if err != nil { return nil, err } varCap := msgs.ReadRootVar(seg) v := newVar(common.MakeVarUUId(varCap.Id()), exe, disk, vm) positions := varCap.Positions() if positions.Len() != 0 { v.positions = (*common.Positions)(&positions) } writeTxnId := common.MakeTxnId(varCap.WriteTxnId()) writeTxnClock := VectorClockFromCap(varCap.WriteTxnClock()) writesClock := VectorClockFromCap(varCap.WritesClock()) server.Log(v.UUId, "Restored", writeTxnId) if result, err := disk.ReadonlyTransaction(func(rtxn *mdbs.RTxn) (interface{}, error) { return db.ReadTxnFromDisk(rtxn, writeTxnId) }).ResultError(); err == nil { if result == nil || result.(*msgs.Txn) == nil { panic(fmt.Sprintf("%v Unable to find txn %v on disk (%v)", v.UUId, writeTxnId, result)) } actions := result.(*msgs.Txn).Actions() v.curFrame = NewFrame(nil, v, writeTxnId, &actions, writeTxnClock, writesClock) v.curFrameOnDisk = v.curFrame } else { return nil, err } v.varCap = &varCap return v, nil }
func (am *AcceptorManager) OneATxnVotesReceived(sender common.RMId, txnId *common.TxnId, oneATxnVotes *msgs.OneATxnVotes) { instanceRMId := common.RMId(oneATxnVotes.RmId()) server.Log(txnId, "1A received from", sender, "; instance:", instanceRMId) instId := instanceId([instanceIdLen]byte{}) instIdSlice := instId[:] copy(instIdSlice, txnId[:]) binary.BigEndian.PutUint32(instIdSlice[common.KeyLen:], uint32(instanceRMId)) replySeg := capn.NewBuffer(nil) msg := msgs.NewRootMessage(replySeg) oneBTxnVotes := msgs.NewOneBTxnVotes(replySeg) msg.SetOneBTxnVotes(oneBTxnVotes) oneBTxnVotes.SetRmId(oneATxnVotes.RmId()) oneBTxnVotes.SetTxnId(oneATxnVotes.TxnId()) proposals := oneATxnVotes.Proposals() promises := msgs.NewTxnVotePromiseList(replySeg, proposals.Len()) oneBTxnVotes.SetPromises(promises) for idx, l := 0, proposals.Len(); idx < l; idx++ { proposal := proposals.At(idx) vUUId := common.MakeVarUUId(proposal.VarId()) copy(instIdSlice[common.KeyLen+4:], vUUId[:]) promise := promises.At(idx) promise.SetVarId(vUUId[:]) am.ensureInstance(txnId, &instId, vUUId).OneATxnVotesReceived(&proposal, &promise) } NewOneShotSender(server.SegToBytes(replySeg), am.ConnectionManager, sender) }
func (c *cache) updateFromTxnCommit(txn *msgs.ClientTxn, txnId *common.TxnId) { actions := txn.Actions() c.Lock() defer c.Unlock() for idx, l := 0, actions.Len(); idx < l; idx++ { action := actions.At(idx) vUUId := common.MakeVarUUId(action.VarId()) switch action.Which() { case msgs.CLIENTACTION_WRITE: write := action.Write() refs := write.References() c.updateFromWrite(txnId, vUUId, write.Value(), &refs) case msgs.CLIENTACTION_READWRITE: rw := action.Readwrite() refs := rw.References() c.updateFromWrite(txnId, vUUId, rw.Value(), &refs) case msgs.CLIENTACTION_CREATE: create := action.Create() refs := create.References() c.updateFromWrite(txnId, vUUId, create.Value(), &refs) case msgs.CLIENTACTION_READ: // do nothing } } }
func (c *cache) updateFromTxnAbort(updates *msgs.ClientUpdate_List) []*common.VarUUId { modifiedVars := make([]*common.VarUUId, 0, updates.Len()) c.Lock() defer c.Unlock() for idx, l := 0, updates.Len(); idx < l; idx++ { update := updates.At(idx) txnId := common.MakeTxnId(update.Version()) actions := update.Actions() for idy, m := 0, actions.Len(); idy < m; idy++ { action := actions.At(idy) vUUId := common.MakeVarUUId(action.VarId()) //fmt.Printf("%v@%v ", vUUId, txnId) switch action.Which() { case msgs.CLIENTACTION_DELETE: c.updateFromDelete(vUUId, txnId) modifiedVars = append(modifiedVars, vUUId) case msgs.CLIENTACTION_WRITE: // We're missing TxnId and TxnId made a write of vUUId (to // version TxnId). write := action.Write() refs := write.References() if c.updateFromWrite(txnId, vUUId, write.Value(), &refs) { modifiedVars = append(modifiedVars, vUUId) } default: log.Fatal("Received update that was neither a read or write action:", action.Which()) } } } //fmt.Println(".") return modifiedVars }
func (br badReads) combine(rmBal *rmBallot) { clock := rmBal.ballot.Clock badRead := rmBal.ballot.VoteCap.AbortBadRead() txnId := common.MakeTxnId(badRead.TxnId()) actions := badRead.TxnActions() for idx, l := 0, actions.Len(); idx < l; idx++ { action := actions.At(idx) vUUId := common.MakeVarUUId(action.VarId()) if bra, found := br[*vUUId]; found { bra.combine(&action, rmBal, txnId, clock.Clock[*vUUId]) } else if action.Which() == msgs.ACTION_READ { br[*vUUId] = &badReadAction{ rmBallot: rmBal, vUUId: vUUId, txnId: common.MakeTxnId(action.Read().Version()), clockElem: clock.Clock[*vUUId] - 1, action: &action, } if clock.Clock[*vUUId] == 0 { panic(fmt.Sprintf("Just did 0 - 1 in int64 (%v, %v) (%v)", vUUId, clock, txnId)) } } else { br[*vUUId] = &badReadAction{ rmBallot: rmBal, vUUId: vUUId, txnId: txnId, clockElem: clock.Clock[*vUUId], action: &action, } } } }
func TopologyFromCap(txnId *common.TxnId, root *msgs.VarIdPos, topology *msgs.Topology) *Topology { t := &Topology{Configuration: &configuration.Configuration{}} t.ClusterId = topology.ClusterId() t.Version = topology.Version() t.Hosts = topology.Hosts().ToArray() t.F = topology.F() t.FInc = t.F + 1 t.TwoFInc = (2 * uint16(t.F)) + 1 t.MaxRMCount = topology.MaxRMCount() t.AsyncFlush = topology.AsyncFlush() rms := topology.Rms() t.AllRMs = make([]common.RMId, rms.Len()) for idx := range t.AllRMs { t.AllRMs[idx] = common.RMId(rms.At(idx)) } t.DBVersion = txnId if root != nil && len(root.Id()) == common.KeyLen { t.RootVarUUId = common.MakeVarUUId(root.Id()) pos := common.Positions(root.Positions()) t.RootPositions = &pos } accounts := topology.Accounts() t.Accounts = make(map[string]string, accounts.Len()) for idx, l := 0, accounts.Len(); idx < l; idx++ { account := accounts.At(idx) t.Accounts[account.Username()] = account.Password() } return t }
func (conn *Connection) nextVarUUId() *common.VarUUId { conn.lock.Lock() defer conn.lock.Unlock() binary.BigEndian.PutUint64(conn.namespace[:8], conn.nextVUUId) vUUId := common.MakeVarUUId(conn.namespace) conn.nextVUUId++ return vUUId }
func (lc *LocalConnection) NextVarUUId() *common.VarUUId { lc.Lock() defer lc.Unlock() vUUId := common.MakeVarUUId(lc.namespace) binary.BigEndian.PutUint64(vUUId[0:8], lc.nextVarNumber) lc.nextVarNumber++ return vUUId }
func (vc versionCache) UpdateFromAbort(updates *msgs.Update_List) map[*msgs.Update][]*msgs.Action { validUpdates := make(map[*msgs.Update][]*msgs.Action) for idx, l := 0, updates.Len(); idx < l; idx++ { update := updates.At(idx) txnId := common.MakeTxnId(update.TxnId()) clock := eng.VectorClockFromCap(update.Clock()) actions := update.Actions() validActions := make([]*msgs.Action, 0, actions.Len()) for idy, m := 0, actions.Len(); idy < m; idy++ { action := actions.At(idy) vUUId := common.MakeVarUUId(action.VarId()) clockElem := clock.Clock[*vUUId] switch action.Which() { case msgs.ACTION_MISSING: if c, found := vc[*vUUId]; found { cmp := c.txnId.Compare(txnId) if clockElem > c.clockElem && cmp == common.EQ { panic(fmt.Sprintf("Clock version increased on missing for %v@%v (%v > %v)", vUUId, txnId, clockElem, c.clockElem)) } if clockElem > c.clockElem || (clockElem == c.clockElem && cmp == common.LT) { delete(vc, *vUUId) validActions = append(validActions, &action) } } case msgs.ACTION_WRITE: if c, found := vc[*vUUId]; found { cmp := c.txnId.Compare(txnId) if clockElem > c.clockElem && cmp == common.EQ { panic(fmt.Sprintf("Clock version increased on write for %v@%v (%v > %v)", vUUId, txnId, clockElem, c.clockElem)) } if clockElem > c.clockElem || (clockElem == c.clockElem && cmp == common.LT) { c.txnId = txnId c.clockElem = clockElem validActions = append(validActions, &action) } } else { vc[*vUUId] = &cached{ txnId: txnId, clockElem: clockElem, } validActions = append(validActions, &action) } default: panic(fmt.Sprintf("%v", action.Which())) } } if len(validActions) != 0 { validUpdates[&update] = validActions } } return validUpdates }
func (vw *varWrapper) start() { defer close(vw.c) c1 := &varWrapperCell{varWrapper: vw} c2 := &varWrapperCell{varWrapper: vw} c1.other, c2.other = c2, c1 curCell := c1 _, err := vw.store.db.ReadonlyTransaction(func(rtxn *mdbs.RTxn) interface{} { rtxn.WithCursor(vw.store.db.Vars, func(cursor *mdbs.Cursor) interface{} { vUUIdBytes, varBytes, err := cursor.Get(nil, nil, mdb.FIRST) if err != nil { cursor.Error(fmt.Errorf("Err on finding first var in %v: %v", vw.store, err)) return nil } if !bytes.Equal(vUUIdBytes, configuration.TopologyVarUUId[:]) { vUUId := common.MakeVarUUId(vUUIdBytes) cursor.Error(fmt.Errorf("Err on finding first var in %v: expected to find topology var, but found %v instead! (%v)", vw.store, vUUId, varBytes)) return nil } for ; err == nil; vUUIdBytes, varBytes, err = cursor.Get(nil, nil, mdb.NEXT) { vUUId := common.MakeVarUUId(vUUIdBytes) seg, _, err := capn.ReadFromMemoryZeroCopy(varBytes) if err != nil { cursor.Error(fmt.Errorf("Err on decoding %v in %v: %v (%v)", vUUId, vw.store, err, varBytes)) return nil } varCap := msgs.ReadRootVar(seg) curCell.vUUId = vUUId curCell.varCap = &varCap vw.c <- curCell curCell = curCell.other } if err != nil && err != mdb.NotFound { cursor.Error(err) } return nil }) return nil }).ResultError() if err != nil { curCell.err = err vw.c <- curCell } }
func MakeAbortBallots(txn *msgs.Txn, alloc *msgs.Allocation) []*eng.Ballot { actions := txn.Actions() actionIndices := alloc.ActionIndices() ballots := make([]*eng.Ballot, actionIndices.Len()) for idx, l := 0, actionIndices.Len(); idx < l; idx++ { action := actions.At(int(actionIndices.At(idx))) vUUId := common.MakeVarUUId(action.VarId()) ballots[idx] = eng.NewBallot(vUUId, eng.AbortDeadlock, nil) } return ballots }
func (p *proposal) OneBTxnVotesReceived(sender common.RMId, oneBTxnVotes *msgs.OneBTxnVotes) { promises := oneBTxnVotes.Promises() for idx, l := 0, promises.Len(); idx < l; idx++ { promise := promises.At(idx) vUUId := common.MakeVarUUId(promise.VarId()) pi := p.instances[*vUUId] pi.oneBTxnVotesReceived(sender, &promise) } p.maybeSendOneA() p.maybeSendTwoA() }
func (cts *ClientTxnSubmitter) addCreatesToCache(outcome *msgs.Outcome) { actions := outcome.Txn().Actions() for idx, l := 0, actions.Len(); idx < l; idx++ { action := actions.At(idx) if action.Which() == msgs.ACTION_CREATE { varUUId := common.MakeVarUUId(action.VarId()) positions := common.Positions(action.Create().Positions()) cts.hashCache.AddPosition(varUUId, &positions) } } }
func BallotFromCap(ballotCap *msgs.Ballot) *Ballot { voteCap := ballotCap.Vote() ballot := &Ballot{ VarUUId: common.MakeVarUUId(ballotCap.VarId()), Clock: VectorClockFromCap(ballotCap.Clock()), Vote: Vote(voteCap.Which()), BallotCap: ballotCap, VoteCap: &voteCap, } return ballot }
func (fo *frameOpen) createRollClientTxn() (*msgs.ClientTxn, map[common.VarUUId]*common.Positions) { var origWrite *msgs.Action vUUIdBytes := fo.v.UUId[:] for idx, l := 0, fo.frameTxnActions.Len(); idx < l; idx++ { action := fo.frameTxnActions.At(idx) if bytes.Equal(action.VarId(), vUUIdBytes) { origWrite = &action break } } seg := capn.NewBuffer(nil) ctxn := msgs.NewClientTxn(seg) ctxn.SetRetry(false) actions := msgs.NewClientActionList(seg, 1) ctxn.SetActions(actions) action := actions.At(0) action.SetVarId(fo.v.UUId[:]) action.SetRoll() roll := action.Roll() roll.SetVersion(fo.frameTxnId[:]) var refs msgs.VarIdPos_List switch origWrite.Which() { case msgs.ACTION_WRITE: ow := origWrite.Write() roll.SetValue(ow.Value()) refs = ow.References() case msgs.ACTION_READWRITE: owr := origWrite.Readwrite() roll.SetValue(owr.Value()) refs = owr.References() case msgs.ACTION_CREATE: oc := origWrite.Create() roll.SetValue(oc.Value()) refs = oc.References() case msgs.ACTION_ROLL: owr := origWrite.Roll() roll.SetValue(owr.Value()) refs = owr.References() default: panic(fmt.Sprintf("%v unexpected action type when building roll: %v", fo.frame, origWrite.Which())) } posMap := make(map[common.VarUUId]*common.Positions) posMap[*fo.v.UUId] = fo.v.positions refVarList := seg.NewDataList(refs.Len()) roll.SetReferences(refVarList) for idx, l := 0, refs.Len(); idx < l; idx++ { ref := refs.At(idx) vUUId := common.MakeVarUUId(ref.Id()) pos := common.Positions(ref.Positions()) posMap[*vUUId] = &pos refVarList.Set(idx, vUUId[:]) } return &ctxn, posMap }
func (p *proposal) TwoBFailuresReceived(sender common.RMId, failures *msgs.TwoBTxnVotesFailures) { nacks := failures.Nacks() for idx, l := 0, nacks.Len(); idx < l; idx++ { nack := nacks.At(idx) vUUId := common.MakeVarUUId(nack.VarId()) pi := p.instances[*vUUId] pi.twoBNackReceived(&nack) } p.maybeSendOneA() p.maybeSendTwoA() }
func ImmigrationTxnFromCap(exe *dispatcher.Executor, vd *VarDispatcher, stateChange TxnLocalStateChange, ourRMId common.RMId, txnCap *msgs.Txn, varCaps *msgs.Var_List) { txn := TxnFromCap(exe, vd, stateChange, ourRMId, txnCap) txnActions := txnCap.Actions() txn.localActions = make([]localAction, varCaps.Len()) actionsMap := make(map[common.VarUUId]*localAction) for idx, l := 0, varCaps.Len(); idx < l; idx++ { varCap := varCaps.At(idx) action := &txn.localActions[idx] action.Txn = txn action.vUUId = common.MakeVarUUId(varCap.Id()) action.writeTxnActions = &txnActions positions := varCap.Positions() action.createPositions = (*common.Positions)(&positions) action.outcomeClock = VectorClockFromCap(varCap.WriteTxnClock()) action.writesClock = VectorClockFromCap(varCap.WritesClock()) actionsMap[*action.vUUId] = action } for idx, l := 0, txnActions.Len(); idx < l; idx++ { actionCap := txnActions.At(idx) vUUId := common.MakeVarUUId(actionCap.VarId()) if action, found := actionsMap[*vUUId]; found { action.writeAction = &actionCap } } txn.Start(false) txn.nextState() for idx := range txn.localActions { action := &txn.localActions[idx] f := func(v *Var) { if v == nil { panic(fmt.Sprintf("%v immigration error: %v unable to create var!", txn.Id, action.vUUId)) } else { v.ReceiveTxnOutcome(action) } } vd.ApplyToVar(f, true, action.vUUId) } }
func VectorClockFromCap(vcCap msgs.VectorClock) *VectorClock { vUUIds := vcCap.VarUuids() values := vcCap.Values() vc := &VectorClock{ Clock: make(map[common.VarUUId]uint64, vUUIds.Len()), cap: &vcCap, } for idx, l := 0, vUUIds.Len(); idx < l; idx++ { vUUId := common.MakeVarUUId(vUUIds.At(idx)) vc.Clock[*vUUId] = values.At(idx) } return vc }
func (am *AcceptorManager) TwoATxnVotesReceived(sender common.RMId, txnId *common.TxnId, twoATxnVotes *msgs.TwoATxnVotes) { instanceRMId := common.RMId(twoATxnVotes.RmId()) server.Log(txnId, "2A received from", sender, "; instance:", instanceRMId) instId := instanceId([instanceIdLen]byte{}) instIdSlice := instId[:] copy(instIdSlice, txnId[:]) binary.BigEndian.PutUint32(instIdSlice[common.KeyLen:], uint32(instanceRMId)) txnCap := twoATxnVotes.Txn() a := am.ensureAcceptor(txnId, &txnCap) requests := twoATxnVotes.AcceptRequests() failureInstances := make([]*instance, 0, requests.Len()) failureRequests := make([]*msgs.TxnVoteAcceptRequest, 0, requests.Len()) for idx, l := 0, requests.Len(); idx < l; idx++ { request := requests.At(idx) vUUId := common.MakeVarUUId(request.Ballot().VarId()) copy(instIdSlice[common.KeyLen+4:], vUUId[:]) inst := am.ensureInstance(txnId, &instId, vUUId) accepted, rejected := inst.TwoATxnVotesReceived(&request) if accepted { a.BallotAccepted(instanceRMId, inst, vUUId, &txnCap) } else if rejected { failureInstances = append(failureInstances, inst) failureRequests = append(failureRequests, &request) } } if len(failureInstances) != 0 { replySeg := capn.NewBuffer(nil) msg := msgs.NewRootMessage(replySeg) twoBTxnVotes := msgs.NewTwoBTxnVotes(replySeg) msg.SetTwoBTxnVotes(twoBTxnVotes) twoBTxnVotes.SetFailures() failuresCap := twoBTxnVotes.Failures() failuresCap.SetTxnId(txnId[:]) failuresCap.SetRmId(uint32(instanceRMId)) nacks := msgs.NewTxnVoteTwoBFailureList(replySeg, len(failureInstances)) failuresCap.SetNacks(nacks) for idx, inst := range failureInstances { failure := nacks.At(idx) failure.SetVarId(inst.vUUId[:]) failure.SetRoundNumber(failureRequests[idx].RoundNumber()) failure.SetRoundNumberTooLow(uint32(inst.promiseNum >> 32)) } server.Log(txnId, "Sending 2B failures to", sender, "; instance:", instanceRMId) // The proposal senders are repeating, so this use of OSS is fine. NewOneShotSender(server.SegToBytes(replySeg), am, sender) } }
func (id *outcomeEqualId) String() string { idList := (*msgs.Outcome)(id).Id() buf := "OutcomeId[" for idx, l := 0, idList.Len(); idx < l; idx++ { outId := idList.At(idx) buf += fmt.Sprintf("%v{", common.MakeVarUUId(outId.VarId())) instList := outId.AcceptedInstances() for idy, m := 0, instList.Len(); idy < m; idy++ { inst := instList.At(idy) buf += fmt.Sprintf("(instance %v: vote %v)", common.RMId(inst.RmId()), inst.Vote()) } buf += "} " } buf += "]" return buf }
func NewTopology(txnId *common.TxnId, root *msgs.VarIdPos, config *Configuration) *Topology { t := &Topology{ Configuration: config, FInc: config.F + 1, TwoFInc: (2 * uint16(config.F)) + 1, DBVersion: txnId, } if root != nil { positions := root.Positions() t.Root = Root{ VarUUId: common.MakeVarUUId(root.Id()), Positions: (*common.Positions)(&positions), } } return t }
func loadVars(disk *mdbs.MDBServer, vars map[common.VarUUId]*varstate) { _, err := disk.ReadonlyTransaction(func(rtxn *mdbs.RTxn) (interface{}, error) { return rtxn.WithCursor(db.DB.Vars, func(cursor *mdb.Cursor) (interface{}, error) { key, data, err := cursor.Get(nil, nil, mdb.FIRST) for ; err == nil; key, data, err = cursor.Get(nil, nil, mdb.NEXT) { vUUId := common.MakeVarUUId(key) seg, _, err := capn.ReadFromMemoryZeroCopy(data) if err != nil { log.Println(err) continue } varCap := msgs.ReadRootVar(seg) pos := varCap.Positions() positions := (*common.Positions)(&pos) writeTxnId := common.MakeTxnId(varCap.WriteTxnId()) writeTxnClock := eng.VectorClockFromCap(varCap.WriteTxnClock()) writesClock := eng.VectorClockFromCap(varCap.WritesClock()) if state, found := vars[*vUUId]; found { if err := state.matches(disk, writeTxnId, writeTxnClock, writesClock, positions); err != nil { log.Println(err) } } else { state = &varstate{ vUUId: vUUId, disks: []*mdbs.MDBServer{disk}, writeTxnId: writeTxnId, writeTxnClock: writeTxnClock, writeWritesClock: writesClock, positions: positions, } vars[*vUUId] = state } } if err == mdb.NotFound { return nil, nil } else { return nil, err } }) }).ResultError() if err != nil { log.Println(err) } }
func (sts *SimpleTxnSubmitter) translateCreate(outgoingSeg *capn.Segment, referencesInNeedOfPositions *[]*msgs.VarIdPos, action *msgs.Action, clientAction *cmsgs.ClientAction) (*common.Positions, []common.RMId, error) { action.SetCreate() clientCreate := clientAction.Create() create := action.Create() create.SetValue(clientCreate.Value()) vUUId := common.MakeVarUUId(clientAction.VarId()) positions, hashCodes, err := sts.hashCache.CreatePositions(vUUId, int(sts.topology.MaxRMCount)) if err != nil { return nil, nil, err } create.SetPositions((capn.UInt8List)(*positions)) clientReferences := clientCreate.References() references := msgs.NewVarIdPosList(outgoingSeg, clientReferences.Len()) create.SetReferences(references) copyReferences(&clientReferences, &references, referencesInNeedOfPositions) return positions, hashCodes, nil }
func (am *AcceptorManager) loadFromData(txnId *common.TxnId, data []byte) { seg, _, err := capn.ReadFromMemoryZeroCopy(data) if err != nil { log.Println("Unable to decode acceptor state", data) return } state := msgs.ReadRootAcceptorState(seg) txn := state.Txn() instId := instanceId([instanceIdLen]byte{}) instIdSlice := instId[:] outcome := state.Outcome() copy(instIdSlice, txnId[:]) instances := state.Instances() acc := AcceptorFromData(txnId, &txn, &outcome, state.SendToAll(), &instances, am) aInst := &acceptorInstances{acceptor: acc} am.acceptors[*txnId] = aInst for idx, l := 0, instances.Len(); idx < l; idx++ { instancesForVar := instances.At(idx) vUUId := common.MakeVarUUId(instancesForVar.VarId()) acceptedInstances := instancesForVar.Instances() for idy, m := 0, acceptedInstances.Len(); idy < m; idy++ { acceptedInstance := acceptedInstances.At(idy) roundNumber := acceptedInstance.RoundNumber() ballot := acceptedInstance.Ballot() instance := &instance{ manager: am, vUUId: vUUId, promiseNum: paxosNumber(roundNumber), acceptedNum: paxosNumber(roundNumber), accepted: &ballot, } binary.BigEndian.PutUint32(instIdSlice[common.KeyLen:], acceptedInstance.RmId()) copy(instIdSlice[common.KeyLen+4:], vUUId[:]) am.instances[instId] = instance aInst.addInstance(&instId) } } acc.Start() }
func (vc versionCache) UpdateFromCommit(txnId *common.TxnId, outcome *msgs.Outcome) { clock := eng.VectorClockFromCap(outcome.Commit()) actions := outcome.Txn().Actions() for idx, l := 0, actions.Len(); idx < l; idx++ { action := actions.At(idx) if action.Which() != msgs.ACTION_READ { vUUId := common.MakeVarUUId(action.VarId()) if c, found := vc[*vUUId]; found { c.txnId = txnId c.clockElem = clock.Clock[*vUUId] } else { vc[*vUUId] = &cached{ txnId: txnId, clockElem: clock.Clock[*vUUId], } } } } }
func (c *cache) updateFromWrite(txnId *common.TxnId, vUUId *common.VarUUId, value []byte, refs *capn.DataList) bool { vr, found := c.m[*vUUId] references := make([]*common.VarUUId, refs.Len()) switch { case found && vr.version.Equal(txnId): log.Fatal("Divergence discovered on update of ", vUUId, ": server thinks we don't have ", txnId, " but we do!") return false case found: // Must use the new array because there could be txns in // progress that still have pointers to the old array. vr.references = references default: vr = &valueRef{references: references} c.m[*vUUId] = vr } // fmt.Printf("%v updated (%v -> %v)\n", vUUId, vr.version, txnId) vr.version = txnId vr.value = value for idz, n := 0, refs.Len(); idz < n; idz++ { vr.references[idz] = common.MakeVarUUId(refs.At(idz)) } return found }
func (cts *ClientTxnSubmitter) translateUpdates(seg *capn.Segment, updates map[*msgs.Update][]*msgs.Action) cmsgs.ClientUpdate_List { clientUpdates := cmsgs.NewClientUpdateList(seg, len(updates)) idx := 0 for update, actions := range updates { clientUpdate := clientUpdates.At(idx) idx++ clientUpdate.SetVersion(update.TxnId()) clientActions := cmsgs.NewClientActionList(seg, len(actions)) clientUpdate.SetActions(clientActions) for idy, action := range actions { clientAction := clientActions.At(idy) clientAction.SetVarId(action.VarId()) switch action.Which() { case msgs.ACTION_MISSING: clientAction.SetDelete() case msgs.ACTION_WRITE: clientAction.SetWrite() write := action.Write() clientWrite := clientAction.Write() clientWrite.SetValue(write.Value()) references := write.References() clientReferences := seg.NewDataList(references.Len()) clientWrite.SetReferences(clientReferences) for idz, n := 0, references.Len(); idz < n; idz++ { ref := references.At(idz) clientReferences.Set(idz, ref.Id()) positions := common.Positions(ref.Positions()) cts.hashCache.AddPosition(common.MakeVarUUId(ref.Id()), &positions) } default: panic(fmt.Sprintf("Unexpected action type: %v", action.Which())) } } } return clientUpdates }
func (cash *connectionAwaitServerHandshake) start() (bool, error) { seg := capn.NewBuffer(nil) hello := msgs.NewRootHelloFromClient(seg) hello.SetUsername(cash.username) hello.SetPassword(cash.password) cash.username = "" cash.password = nil buf := new(bytes.Buffer) if _, err := seg.WriteTo(buf); err != nil { return false, err } if err := cash.send(buf.Bytes()); err != nil { return false, err } if seg, err := cash.readAndDecryptOne(); err == nil { server := msgs.ReadRootHelloFromServer(seg) root := server.Root() if len(root.Id()) != common.KeyLen { return false, fmt.Errorf("Root object VarUUId is of wrong length!") } cash.lock.Lock() cash.rootVUUId = common.MakeVarUUId(root.Id()) cash.namespace = make([]byte, common.KeyLen) copy(cash.namespace[8:], server.Namespace()) cash.serverHost = server.LocalHost() cash.rmId = common.RMId(binary.BigEndian.Uint32(cash.namespace[16:20])) cash.lock.Unlock() cash.nextState() return false, nil } else { return false, err } }