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 }
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++ } } }