// putInternal writes the specified value to key. func (kv *KV) putInternal(key proto.Key, value proto.Value) error { value.InitChecksum(key) return kv.Call(proto.Put, &proto.PutRequest{ RequestHeader: proto.RequestHeader{Key: key}, Value: value, }, &proto.PutResponse{}) }
// PutProto sets the given key to the protobuf-serialized byte string // of msg and the provided timestamp. func (mvcc *MVCC) PutProto(key Key, timestamp proto.Timestamp, txn *proto.Transaction, msg gogoproto.Message) error { data, err := gogoproto.Marshal(msg) if err != nil { return err } value := proto.Value{Bytes: data} value.InitChecksum(key) return mvcc.Put(key, timestamp, value, txn) }
// putInternal writes the specified value to key. func putInternal(db DB, key engine.Key, value proto.Value, timestamp proto.Timestamp) error { value.InitChecksum(key) pr := <-db.Put(&proto.PutRequest{ RequestHeader: proto.RequestHeader{ Key: key, User: UserRoot, Timestamp: timestamp, }, Value: value, }) return pr.GoError() }
// PreparePutProto sets the given key to the protobuf-serialized byte // string of msg. The resulting Put call is buffered and will not be // sent until a subsequent call to Flush. Returns marshalling errors // if encountered. func (kv *KV) PreparePutProto(key proto.Key, msg gogoproto.Message) error { data, err := gogoproto.Marshal(msg) if err != nil { return err } value := proto.Value{Bytes: data} value.InitChecksum(key) kv.Prepare(proto.Put, &proto.PutRequest{ RequestHeader: proto.RequestHeader{Key: key}, Value: value, }, &proto.PutResponse{}) return nil }
// setupMVCCData writes up to numVersions values at each of numKeys // keys. The number of versions written for each key is chosen // randomly according to a uniform distribution. Each successive // version is written starting at 5ns and then in 5ns increments. This // allows scans at various times, starting at t=5ns, and continuing to // t=5ns*(numVersions+1). A version for each key will be read on every // such scan, but the dynamics of the scan will change depending on // the historical timestamp. Earlier timestamps mean scans which must // skip more historical versions; later timestamps mean scans which // skip fewer. // // The creation of the rocksdb database is time consuming, especially // for larger numbers of versions. The database is persisted between // runs and stored in the current directory as // "mvcc_scan_<versions>_<keys>". func setupMVCCScanData(numVersions, numKeys int, b *testing.B) (*RocksDB, *stop.Stopper) { loc := fmt.Sprintf("mvcc_scan_%d_%d", numVersions, numKeys) exists := true if _, err := os.Stat(loc); os.IsNotExist(err) { exists = false } log.Infof("creating mvcc data: %s", loc) const cacheSize = 8 << 30 // 8 GB stopper := stop.NewStopper() rocksdb := NewRocksDB(proto.Attributes{Attrs: []string{"ssd"}}, loc, cacheSize, stopper) if err := rocksdb.Open(); err != nil { b.Fatalf("could not create new rocksdb db instance at %s: %v", loc, err) } if exists { return rocksdb, stopper } rng, _ := randutil.NewPseudoRand() keys := make([]proto.Key, numKeys) nvs := make([]int, numKeys) for t := 1; t <= numVersions; t++ { walltime := int64(5 * t) ts := makeTS(walltime, 0) batch := rocksdb.NewBatch() for i := 0; i < numKeys; i++ { if t == 1 { keys[i] = proto.Key(encoding.EncodeUvarint([]byte("key-"), uint64(i))) nvs[i] = int(rand.Int31n(int32(numVersions)) + 1) } // Only write values if this iteration is less than the random // number of versions chosen for this key. if t <= nvs[i] { value := proto.Value{Bytes: randutil.RandBytes(rng, 1024)} value.InitChecksum(keys[i]) if err := MVCCPut(batch, nil, keys[i], ts, value, nil); err != nil { b.Fatal(err) } } } if err := batch.Commit(); err != nil { b.Fatal(err) } batch.Close() } rocksdb.CompactRange(nil, nil) return rocksdb, stopper }