Esempio n. 1
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
}
Esempio n. 2
0
func populate(records int, server *mdbs.MDBServer, dbs *DBs) error {
	key := make([]byte, keySize)
	val := make([]byte, valSize)
	_, err := server.ReadWriteTransaction(false, func(txn *mdbs.RWTxn) (interface{}, error) {
		for idx := 0; idx < records; idx++ {
			int64ToBytes(int64(idx), key)
			int64ToBytes(int64(idx), val)
			if err := txn.Put(dbs.Test, key, val, 0); err != nil {
				return nil, err
			}
		}
		return nil, nil
	}).ResultError()
	return err
}
Esempio n. 3
0
func (ad *AcceptorDispatcher) loadFromDisk(server *mdbs.MDBServer) {
	res, err := server.ReadonlyTransaction(func(rtxn *mdbs.RTxn) (interface{}, error) {
		return rtxn.WithCursor(db.DB.BallotOutcomes, func(cursor *mdb.Cursor) (interface{}, error) {
			// cursor.Get returns a copy of the data. So it's fine for us
			// to store and process this later - it's not about to be
			// overwritten on disk.
			count := 0
			txnIdData, acceptorState, err := cursor.Get(nil, nil, mdb.FIRST)
			for ; err == nil; txnIdData, acceptorState, err = cursor.Get(nil, nil, mdb.NEXT) {
				count++
				txnId := common.MakeTxnId(txnIdData)
				acceptorStateCopy := acceptorState
				ad.withAcceptorManager(txnId, func(am *AcceptorManager) {
					am.loadFromData(txnId, acceptorStateCopy)
				})
			}
			if err == mdb.NotFound {
				// fine, we just fell off the end as expected.
				return count, nil
			} else {
				return count, err
			}
		})
	}).ResultError()
	if err == nil {
		log.Printf("Loaded %v acceptors from disk\n", res.(int))
	} else {
		log.Println("AcceptorDispatcher error loading from disk:", err)
	}
}
Esempio n. 4
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)
	}
}
Esempio n. 5
0
func worker(records int64, server *mdbs.MDBServer, dbs *DBs, readers, id int, write bool) error {
	msg := fmt.Sprint(id, ": Read")
	if write {
		msg = ": Wrote"
	}
	start := time.Now()
	count := 0
	ticker := time.NewTicker(time.Duration(readers) * time.Second)
	randSource := rand.New(rand.NewSource(time.Now().UnixNano()))
	var err error
	for {
		select {
		case <-ticker.C:
			now := time.Now()
			elapsed := now.Sub(start)
			rate := float64(int64(count)*time.Second.Nanoseconds()) / float64(elapsed.Nanoseconds())
			log.Println(msg, count, "records in", elapsed, "(", rate, "records/sec )")
			start = now
			count = 0
		default:
			if write {
				keyNum := randSource.Int63n(records)
				key := make([]byte, keySize)
				int64ToBytes(keyNum, key)
				forceFlush := keyNum%10 == 0
				future := server.ReadWriteTransaction(forceFlush, func(txn *mdbs.RWTxn) (interface{}, error) {
					val, err1 := txn.Get(dbs.Test, key)
					if err1 != nil {
						return nil, err1
					}
					num := bytesToInt64(val)
					if num < keyNum {
						return nil, fmt.Errorf("Expected val (%v) >= key (%v)", num, keyNum)
					}
					int64ToBytes(num+1, val)
					return nil, txn.Put(dbs.Test, key, val, 0)
				})
				if forceFlush {
					_, err = future.ResultError()
				}
			} else {
				keyNum := randSource.Int63n(records)
				key := make([]byte, keySize)
				int64ToBytes(keyNum, key)
				_, err = server.ReadonlyTransaction(func(txn *mdbs.RTxn) (interface{}, error) {
					val, err1 := txn.GetVal(dbs.Test, key)
					if err1 != nil {
						return nil, err1
					}
					num := bytesToInt64(val.BytesNoCopy())
					if num < keyNum {
						return nil, fmt.Errorf("Expected val (%v) >= key (%v)", num, keyNum)
					}
					return nil, nil
				}).ResultError()
			}
			if err != nil {
				log.Fatal(err)
			}
			count++
		}
	}
}