// MakeNameMetadataKey returns the key for the name. Pass name == "" in order // to generate the prefix key to use to scan over all of the names for the // specified parentID. func MakeNameMetadataKey(parentID ID, name string) roachpb.Key { normName := parser.ReNormalizeName(name) k := keys.MakeTablePrefix(uint32(NamespaceTable.ID)) k = encoding.EncodeUvarintAscending(k, uint64(NamespaceTable.PrimaryIndex.ID)) k = encoding.EncodeUvarintAscending(k, uint64(parentID)) if name != "" { k = encoding.EncodeBytesAscending(k, []byte(normName)) k = keys.MakeFamilyKey(k, uint32(NamespaceTable.Columns[2].ID)) } return k }
// MakeRangeKeyPrefix creates a key prefix under which all range-local keys // can be found. func MakeRangeKeyPrefix(key roachpb.RKey) roachpb.Key { buf := make(roachpb.Key, 0, len(LocalRangePrefix)+len(key)+1) buf = append(buf, LocalRangePrefix...) buf = encoding.EncodeBytesAscending(buf, key) return buf }
// AbortCacheKey returns a range-local key by Range ID for an // abort cache entry, with detail specified by encoding the // supplied transaction ID. func AbortCacheKey(rangeID roachpb.RangeID, txnID *uuid.UUID) roachpb.Key { key := MakeRangeIDReplicatedKey(rangeID, LocalAbortCacheSuffix, nil) key = encoding.EncodeBytesAscending(key, txnID.GetBytes()) return key }
func BenchmarkSstRekey(b *testing.B) { // TODO(dan): DRY this with BenchmarkRocksDBSstFileReader. dir, cleanupFn := testutils.TempDir(b, 1) defer cleanupFn() sstPath := filepath.Join(dir, "sst") { const maxEntries = 100000 const keyLen = 10 const valLen = 100 b.SetBytes(keyLen + valLen) ts := hlc.Timestamp{WallTime: timeutil.Now().UnixNano()} kv := engine.MVCCKeyValue{ Key: engine.MVCCKey{Key: roachpb.Key(make([]byte, keyLen)), Timestamp: ts}, Value: make([]byte, valLen), } sst := engine.MakeRocksDBSstFileWriter() if err := sst.Open(sstPath); err != nil { b.Fatal(sst) } var entries = b.N if entries > maxEntries { entries = maxEntries } for i := 0; i < entries; i++ { payload := []byte(fmt.Sprintf("%09d", i)) kv.Key.Key = kv.Key.Key[:0] kv.Key.Key = encoding.EncodeUvarintAscending(kv.Key.Key, uint64(i)) // tableID kv.Key.Key = encoding.EncodeUvarintAscending(kv.Key.Key, 0) // indexID kv.Key.Key = encoding.EncodeBytesAscending(kv.Key.Key, payload) kv.Key.Key = keys.MakeRowSentinelKey(kv.Key.Key) copy(kv.Value, payload) if err := sst.Add(kv); err != nil { b.Fatal(err) } } if err := sst.Close(); err != nil { b.Fatal(err) } } const newTableID = 100 b.ResetTimer() sst, err := engine.MakeRocksDBSstFileReader() if err != nil { b.Fatal(err) } if err := sst.AddFile(sstPath); err != nil { b.Fatal(err) } defer sst.Close() count := 0 iterateFn := sql.MakeRekeyMVCCKeyValFunc(newTableID, func(kv engine.MVCCKeyValue) (bool, error) { count++ if count >= b.N { return true, nil } return false, nil }) for { if err := sst.Iterate(engine.MVCCKey{Key: keys.MinKey}, engine.MVCCKey{Key: keys.MaxKey}, iterateFn); err != nil { b.Fatal(err) } if count >= b.N { break } } }
func TestPrettyPrint(t *testing.T) { tm, _ := time.Parse(time.RFC3339Nano, "2016-03-30T13:40:35.053725008Z") duration := duration.Duration{Months: 1, Days: 1, Nanos: 1 * time.Second.Nanoseconds()} durationAsc, _ := encoding.EncodeDurationAscending(nil, duration) durationDesc, _ := encoding.EncodeDurationDescending(nil, duration) txnID := uuid.MakeV4() // The following test cases encode keys with a mixture of ascending and descending direction, // but always decode keys in the ascending direction. This is why some of the decoded values // seem bizarre. testCases := []struct { key roachpb.Key exp string }{ // local {StoreIdentKey(), "/Local/Store/storeIdent"}, {StoreGossipKey(), "/Local/Store/gossipBootstrap"}, {AbortCacheKey(roachpb.RangeID(1000001), txnID), fmt.Sprintf(`/Local/RangeID/1000001/r/AbortCache/%q`, txnID)}, {RaftTombstoneKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/r/RaftTombstone"}, {RaftAppliedIndexKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/r/RaftAppliedIndex"}, {LeaseAppliedIndexKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/r/LeaseAppliedIndex"}, {RaftTruncatedStateKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/r/RaftTruncatedState"}, {RangeLeaseKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/r/RangeLease"}, {RangeStatsKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/r/RangeStats"}, {RangeTxnSpanGCThresholdKey(roachpb.RangeID(1000001)), `/Local/RangeID/1000001/r/RangeTxnSpanGCThreshold`}, {RangeFrozenStatusKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/r/RangeFrozenStatus"}, {RangeLastGCKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/r/RangeLastGC"}, {RaftHardStateKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/u/RaftHardState"}, {RaftLastIndexKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/u/RaftLastIndex"}, {RaftLogKey(roachpb.RangeID(1000001), uint64(200001)), "/Local/RangeID/1000001/u/RaftLog/logIndex:200001"}, {RangeLastReplicaGCTimestampKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/u/RangeLastReplicaGCTimestamp"}, {RangeLastVerificationTimestampKeyDeprecated(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/u/RangeLastVerificationTimestamp"}, {MakeRangeKeyPrefix(roachpb.RKey("ok")), `/Local/Range/"ok"`}, {RangeDescriptorKey(roachpb.RKey("111")), `/Local/Range/"111"/RangeDescriptor`}, {TransactionKey(roachpb.Key("111"), txnID), fmt.Sprintf(`/Local/Range/"111"/Transaction/addrKey:/id:%q`, txnID)}, {LocalMax, `/Meta1/""`}, // LocalMax == Meta1Prefix // system {makeKey(Meta2Prefix, roachpb.Key("foo")), `/Meta2/"foo"`}, {makeKey(Meta1Prefix, roachpb.Key("foo")), `/Meta1/"foo"`}, {RangeMetaKey(roachpb.RKey("f")), `/Meta2/"f"`}, {NodeLivenessKey(10033), "/System/NodeLiveness/10033"}, {NodeStatusKey(1111), "/System/StatusNode/1111"}, {SystemMax, "/System/Max"}, // key of key {RangeMetaKey(roachpb.RKey(MakeRangeKeyPrefix(roachpb.RKey("ok")))), `/Meta2/Local/Range/"ok"`}, {RangeMetaKey(roachpb.RKey(makeKey(MakeTablePrefix(42), roachpb.RKey("foo")))), `/Meta2/Table/42/"foo"`}, {RangeMetaKey(roachpb.RKey(makeKey(Meta2Prefix, roachpb.Key("foo")))), `/Meta1/"foo"`}, // table {UserTableDataMin, "/Table/50"}, {MakeTablePrefix(111), "/Table/111"}, {makeKey(MakeTablePrefix(42), roachpb.RKey("foo")), `/Table/42/"foo"`}, {makeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeFloatAscending(nil, float64(233.221112)))), "/Table/42/233.221112"}, {makeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeFloatDescending(nil, float64(-233.221112)))), "/Table/42/233.221112"}, {makeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeFloatAscending(nil, math.Inf(1)))), "/Table/42/+Inf"}, {makeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeFloatAscending(nil, math.NaN()))), "/Table/42/NaN"}, {makeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeVarintAscending(nil, 1222)), roachpb.RKey(encoding.EncodeStringAscending(nil, "handsome man"))), `/Table/42/1222/"handsome man"`}, {makeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeVarintAscending(nil, 1222))), `/Table/42/1222`}, {makeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeVarintDescending(nil, 1222))), `/Table/42/-1223`}, {makeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeBytesAscending(nil, []byte{1, 2, 8, 255}))), `/Table/42/"\x01\x02\b\xff"`}, {makeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeBytesAscending(nil, []byte{1, 2, 8, 255})), roachpb.RKey("bar")), `/Table/42/"\x01\x02\b\xff"/"bar"`}, {makeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeBytesDescending(nil, []byte{1, 2, 8, 255})), roachpb.RKey("bar")), `/Table/42/"\x01\x02\b\xff"/"bar"`}, {makeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeNullAscending(nil))), "/Table/42/NULL"}, {makeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeNotNullAscending(nil))), "/Table/42/#"}, {makeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeTimeAscending(nil, tm))), "/Table/42/2016-03-30T13:40:35.053725008Z"}, {makeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeTimeDescending(nil, tm))), "/Table/42/1923-10-04T10:19:23.946274991Z"}, {makeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeDecimalAscending(nil, inf.NewDec(1234, 2)))), "/Table/42/12.34"}, {makeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeDecimalDescending(nil, inf.NewDec(1234, 2)))), "/Table/42/-12.34"}, {makeKey(MakeTablePrefix(42), roachpb.RKey(durationAsc)), "/Table/42/1m1d1s"}, {makeKey(MakeTablePrefix(42), roachpb.RKey(durationDesc)), "/Table/42/-2m-2d743h59m58.999999999s"}, // others {makeKey([]byte("")), "/Min"}, {Meta1KeyMax, "/Meta1/Max"}, {Meta2KeyMax, "/Meta2/Max"}, {makeKey(MakeTablePrefix(42), roachpb.RKey([]byte{0x12, 'a', 0x00, 0x02})), "/Table/42/<unknown escape sequence: 0x0 0x2>"}, } for i, test := range testCases { keyInfo := MassagePrettyPrintedSpanForTest(PrettyPrint(test.key), nil) exp := MassagePrettyPrintedSpanForTest(test.exp, nil) if exp != keyInfo { t.Errorf("%d: expected %s, got %s", i, exp, keyInfo) } if exp != MassagePrettyPrintedSpanForTest(test.key.String(), nil) { t.Errorf("%d: expected %s, got %s", i, exp, test.key.String()) } parsed, err := UglyPrint(keyInfo) if err != nil { if _, ok := err.(*errUglifyUnsupported); !ok { t.Errorf("%d: %s: %s", i, keyInfo, err) } else { t.Logf("%d: skipping parsing of %s; key is unsupported: %v", i, keyInfo, err) } } else if exp, act := test.key, parsed; !bytes.Equal(exp, act) { t.Errorf("%d: expected %q, got %q", i, exp, act) } if t.Failed() { return } } }
// makeDataKeySeriesPrefix creates a key prefix for a time series at a specific // resolution. func makeDataKeySeriesPrefix(name string, r Resolution) roachpb.Key { k := append(roachpb.Key(nil), keys.TimeseriesPrefix...) k = encoding.EncodeBytesAscending(k, []byte(name)) k = encoding.EncodeVarintAscending(k, int64(r)) return k }