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 (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 (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], } } } } }