Пример #1
0
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
}
Пример #2
0
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
}
Пример #3
0
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
}
Пример #4
0
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)
}
Пример #5
0
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
		}
	}
}
Пример #6
0
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("%[email protected]%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
}
Пример #7
0
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,
			}
		}
	}
}
Пример #8
0
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
}
Пример #9
0
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
}
Пример #10
0
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
}
Пример #11
0
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 %[email protected]%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 %[email protected]%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
}
Пример #12
0
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
	}
}
Пример #13
0
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
}
Пример #14
0
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()
}
Пример #15
0
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)
		}
	}
}
Пример #16
0
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
}
Пример #17
0
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
}
Пример #18
0
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()
}
Пример #19
0
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)
	}
}
Пример #20
0
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
}
Пример #21
0
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)
	}
}
Пример #22
0
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
}
Пример #23
0
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
}
Пример #24
0
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)
	}
}
Пример #25
0
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
}
Пример #26
0
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()
}
Пример #27
0
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],
				}
			}
		}
	}
}
Пример #28
0
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
}
Пример #29
0
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
}
Пример #30
0
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
	}
}