func newRangeDataIterator(d *proto.RangeDescriptor, e engine.Engine) *rangeDataIterator { // The first range in the keyspace starts at KeyMin, which includes the node-local // space. We need the original StartKey to find the range metadata, but the // actual data starts at LocalMax. dataStartKey := d.StartKey if d.StartKey.Equal(proto.KeyMin) { dataStartKey = keys.LocalMax } ri := &rangeDataIterator{ ranges: []keyRange{ { start: engine.MVCCEncodeKey(keys.MakeKey(keys.LocalRangeIDPrefix, encoding.EncodeUvarint(nil, uint64(d.RangeID)))), end: engine.MVCCEncodeKey(keys.MakeKey(keys.LocalRangeIDPrefix, encoding.EncodeUvarint(nil, uint64(d.RangeID+1)))), }, { start: engine.MVCCEncodeKey(keys.MakeKey(keys.LocalRangePrefix, encoding.EncodeBytes(nil, d.StartKey))), end: engine.MVCCEncodeKey(keys.MakeKey(keys.LocalRangePrefix, encoding.EncodeBytes(nil, d.EndKey))), }, { start: engine.MVCCEncodeKey(dataStartKey), end: engine.MVCCEncodeKey(d.EndKey), }, }, iter: e.NewIterator(), } ri.iter.Seek(ri.ranges[ri.curIndex].start) ri.advance() return ri }
// encodeTableKey encodes a single element of a table key, appending the // encoded value to b. func encodeTableKey(b []byte, v reflect.Value) ([]byte, error) { switch t := v.Interface().(type) { case []byte: return roachencoding.EncodeBytes(b, t), nil case string: return roachencoding.EncodeBytes(b, []byte(t)), nil } switch v.Kind() { case reflect.Bool: if v.Bool() { return roachencoding.EncodeVarint(b, 1), nil } return roachencoding.EncodeVarint(b, 0), nil case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return roachencoding.EncodeVarint(b, v.Int()), nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return roachencoding.EncodeUvarint(b, v.Uint()), nil case reflect.Float32, reflect.Float64: return roachencoding.EncodeNumericFloat(b, v.Float()), nil case reflect.String: return roachencoding.EncodeBytes(b, []byte(v.String())), nil } return nil, fmt.Errorf("unable to encode key: %s", v) }
func newRangeDataIterator(r *Range, e engine.Engine) *rangeDataIterator { r.RLock() startKey := r.Desc().StartKey if startKey.Equal(engine.KeyMin) { startKey = engine.KeyLocalMax } endKey := r.Desc().EndKey r.RUnlock() ri := &rangeDataIterator{ ranges: []keyRange{ { start: engine.MVCCEncodeKey(engine.MakeKey(engine.KeyLocalRangeIDPrefix, encoding.EncodeUvarint(nil, uint64(r.Desc().RaftID)))), end: engine.MVCCEncodeKey(engine.MakeKey(engine.KeyLocalRangeIDPrefix, encoding.EncodeUvarint(nil, uint64(r.Desc().RaftID+1)))), }, { start: engine.MVCCEncodeKey(engine.MakeKey(engine.KeyLocalRangeKeyPrefix, encoding.EncodeBytes(nil, startKey))), end: engine.MVCCEncodeKey(engine.MakeKey(engine.KeyLocalRangeKeyPrefix, encoding.EncodeBytes(nil, endKey))), }, { start: engine.MVCCEncodeKey(startKey), end: engine.MVCCEncodeKey(endKey), }, }, iter: e.NewIterator(), } ri.iter.Seek(ri.ranges[ri.curIndex].start) ri.advance() return ri }
// MakeRangeKey creates a range-local key based on the range // start key, metadata key suffix, and optional detail (e.g. the // transaction ID for a txn record, etc.). func MakeRangeKey(key, suffix, detail roachpb.Key) roachpb.Key { if len(suffix) != LocalSuffixLength { panic(fmt.Sprintf("suffix len(%q) != %d", suffix, LocalSuffixLength)) } return MakeKey(LocalRangePrefix, encoding.EncodeBytes(nil, key), suffix, detail) }
func encodeTableKey(b []byte, v sqlwire.Datum) ([]byte, error) { if v.BoolVal != nil { if *v.BoolVal { return encoding.EncodeVarint(b, 1), nil } return encoding.EncodeVarint(b, 0), nil } else if v.IntVal != nil { return encoding.EncodeVarint(b, *v.IntVal), nil } else if v.FloatVal != nil { return encoding.EncodeNumericFloat(b, *v.FloatVal), nil } else if v.BytesVal != nil { return encoding.EncodeBytes(b, v.BytesVal), nil } else if v.StringVal != nil { return encoding.EncodeBytes(b, []byte(*v.StringVal)), nil } return nil, fmt.Errorf("unable to encode table key: %T", v) }
// populateTableIndexKey populates the key passed in with the // order encoded values forming the index key. func populateTableIndexKey(key []byte, tableID, indexID uint32, columnValues ...[]byte) []byte { key = append(key, TableDataPrefix...) key = encoding.EncodeUvarint(key, uint64(tableID)) key = encoding.EncodeUvarint(key, uint64(indexID)) for _, value := range columnValues { key = encoding.EncodeBytes(key, value) } return key }
func encodeTableKey(b []byte, v parser.Datum) ([]byte, error) { switch t := v.(type) { case parser.DBool: if t { return encoding.EncodeVarint(b, 1), nil } return encoding.EncodeVarint(b, 0), nil case parser.DInt: return encoding.EncodeVarint(b, int64(t)), nil case parser.DFloat: return encoding.EncodeNumericFloat(b, float64(t)), nil case parser.DString: return encoding.EncodeBytes(b, []byte(t)), nil case parser.DNull: // TODO(tamird,pmattis): This is a hack; we should have proper nil encoding. return encoding.EncodeBytes(b, nil), nil } return nil, fmt.Errorf("unable to encode table key: %T", v) }
// MakeDataKey creates a time series data key for the given series name, source, // Resolution and timestamp. The timestamp is expressed in nanoseconds since the // epoch; it will be truncated to an exact multiple of the supplied // Resolution's KeyDuration. func MakeDataKey(name string, source string, r Resolution, timestamp int64) roachpb.Key { // Normalize timestamp into a timeslot before recording. timeslot := timestamp / r.KeyDuration() k := append(roachpb.Key(nil), keyDataPrefix...) k = encoding.EncodeBytes(k, []byte(name)) k = encoding.EncodeVarint(k, int64(r)) k = encoding.EncodeVarint(k, timeslot) k = append(k, source...) return k }
// 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 { name = normalizeName(name) k := keys.MakeTablePrefix(uint32(NamespaceTable.ID)) k = encoding.EncodeUvarint(k, uint64(NamespaceTable.PrimaryIndex.ID)) k = encoding.EncodeUvarint(k, uint64(parentID)) if name != "" { k = encoding.EncodeBytes(k, []byte(name)) k = keys.MakeColumnKey(k, uint32(NamespaceTable.Columns[2].ID)) } return k }
func encodeTableKey(b []byte, v driver.Value) ([]byte, error) { switch t := v.(type) { case int64: return encoding.EncodeVarint(b, t), nil case float64: return encoding.EncodeNumericFloat(b, t), nil case bool: if t { return encoding.EncodeVarint(b, 1), nil } return encoding.EncodeVarint(b, 0), nil case []byte: return encoding.EncodeBytes(b, t), nil case string: return encoding.EncodeBytes(b, []byte(t)), nil case time.Time: return nil, fmt.Errorf("TODO(pmattis): encode index key: time.Time") } return nil, fmt.Errorf("unable to encode table key: %T", v) }
func encodeTableKey(b []byte, v parser.Datum) ([]byte, error) { switch t := v.(type) { case parser.DBool: if t { return encoding.EncodeVarint(b, 1), nil } return encoding.EncodeVarint(b, 0), nil case parser.DInt: return encoding.EncodeVarint(b, int64(t)), nil case parser.DFloat: return encoding.EncodeNumericFloat(b, float64(t)), nil case parser.DString: return encoding.EncodeBytes(b, []byte(t)), nil } return nil, fmt.Errorf("unable to encode table key: %T", v) }
// MakeRangeKeyPrefix creates a key prefix under which all range-local keys // can be found. func MakeRangeKeyPrefix(key roachpb.RKey) roachpb.Key { return MakeKey(LocalRangePrefix, encoding.EncodeBytes(nil, key)) }
// ResponseCacheKey returns a range-local key by Range ID for a // response cache entry, with detail specified by encoding the // supplied client command ID. func ResponseCacheKey(rangeID roachpb.RangeID, family []byte) roachpb.Key { return MakeRangeIDKey(rangeID, LocalResponseCacheSuffix, encoding.EncodeBytes(nil, family)) }
// SequenceCacheKey returns a range-local key by Range ID for a // sequence cache entry, with detail specified by encoding the // supplied transaction ID, epoch and sequence number. func SequenceCacheKey(rangeID roachpb.RangeID, id []byte, epoch uint32, seq uint32) roachpb.Key { return MakeRangeIDKey(rangeID, LocalSequenceCacheSuffix, encoding.EncodeUint32Decreasing( encoding.EncodeUint32Decreasing( encoding.EncodeBytes(nil, id), epoch), seq)) }
// MakeRangeKey creates a range-local key based on the range // start key, metadata key suffix, and optional detail (e.g. the // transaction UUID for a txn record, etc.). func MakeRangeKey(key, suffix, detail proto.Key) proto.Key { if len(suffix) != KeyLocalSuffixLength { panic(fmt.Sprintf("suffix len(%q) != %d", suffix, KeyLocalSuffixLength)) } return MakeKey(KeyLocalRangeKeyPrefix, encoding.EncodeBytes(nil, key), suffix, detail) }
func TestMakeTableIndexKey(t *testing.T) { defer leaktest.AfterTest(t) key := MakeTableIndexKey(12, 345, []byte("foo"), []byte("bar")) expKey := MakeKey(TableDataPrefix, encoding.EncodeUvarint(nil, 12), encoding.EncodeUvarint(nil, 345), encoding.EncodeBytes(nil, []byte("foo")), encoding.EncodeBytes(nil, []byte("bar"))) if !key.Equal(expKey) { t.Errorf("key %q doesn't match expected %q", key, expKey) } // Check that keys are ordered keys := []proto.Key{ MakeTableIndexKey(0, 0, []byte("foo")), MakeTableIndexKey(0, 0, []byte("fooo")), MakeTableIndexKey(0, 1, []byte("bar")), MakeTableIndexKey(1, 0, []byte("bar")), MakeTableIndexKey(1, 0, []byte("bar"), []byte("foo")), MakeTableIndexKey(1, 1, []byte("bar"), []byte("fo")), MakeTableIndexKey(1, 1, []byte("bar"), []byte("foo")), MakeTableIndexKey(1, 2, []byte("bar")), MakeTableIndexKey(2, 2, []byte("ba")), } for i := 1; i < len(keys); i++ { if bytes.Compare(keys[i-1], keys[i]) >= 0 { t.Errorf("key %d >= key %d", i-1, i) } } }
func TestPrettyPrint(t *testing.T) { defer leaktest.AfterTest(t) tm, _ := time.Parse(time.UnixDate, "Sat Mar 7 11:06:39 UTC 2015") testCases := []struct { key roachpb.Key exp string }{ // local {StoreIdentKey(), "/Local/Store/storeIdent"}, {StoreGossipKey(), "/Local/Store/gossipBootstrap"}, {SequenceCacheKeyPrefix(roachpb.RangeID(1000001), []byte("test0")), `/Local/RangeID/1000001/SequenceCache/"test0"`}, {SequenceCacheKey(roachpb.RangeID(1000001), []byte("test0"), uint32(111), uint32(222)), `/Local/RangeID/1000001/SequenceCache/"test0"/epoch:111/seq:222`}, {RaftLeaderLeaseKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RaftLeaderLease"}, {RaftTombstoneKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RaftTombstone"}, {RaftHardStateKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RaftHardState"}, {RaftAppliedIndexKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RaftAppliedIndex"}, {RaftLogKey(roachpb.RangeID(1000001), uint64(200001)), "/Local/RangeID/1000001/RaftLog/logIndex:200001"}, {RaftTruncatedStateKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RaftTruncatedState"}, {RaftLastIndexKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RaftLastIndex"}, {RangeLastVerificationTimestampKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RangeLastVerificationTimestamp"}, {RangeStatsKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RangeStats"}, {MakeRangeKeyPrefix(roachpb.RKey("ok")), `/Local/Range/"ok"`}, {RangeDescriptorKey(roachpb.RKey("111")), `/Local/Range/RangeDescriptor/"111"`}, {RangeTreeNodeKey(roachpb.RKey("111")), `/Local/Range/RangeTreeNode/"111"`}, {TransactionKey(roachpb.Key("111"), []byte("22222")), `/Local/Range/Transaction/addrKey:/"111"/id:"22222"`}, {LocalMax, "/Local/Max"}, // system {roachpb.MakeKey(Meta2Prefix, roachpb.Key("foo")), `/Meta2/"foo"`}, {roachpb.MakeKey(Meta1Prefix, roachpb.Key("foo")), `/Meta1/"foo"`}, {StoreStatusKey(2222), "/System/StatusStore/2222"}, {NodeStatusKey(1111), "/System/StatusNode/1111"}, {SystemMax, "/System/Max"}, // table {UserTableDataMin, "/Table/50"}, {MakeTablePrefix(111), "/Table/111"}, {MakeKey(MakeTablePrefix(42), roachpb.RKey("foo")), `/Table/42/"foo"`}, {MakeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeFloat(nil, float64(233.221112)))), "/Table/42/233.221112"}, {MakeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeVarint(nil, 1222)), roachpb.RKey(encoding.EncodeString(nil, "handsome man"))), `/Table/42/1222/"handsome man"`}, {MakeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeBytes(nil, []byte{1, 2, 8, 255}))), `/Table/42/"\x01\x02\b\xff"`}, {MakeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeBytes(nil, []byte{1, 2, 8, 255})), roachpb.RKey("bar")), `/Table/42/"\x01\x02\b\xff"/"bar"`}, {MakeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeNull(nil))), "/Table/42/NULL"}, {MakeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeNotNull(nil))), "/Table/42/#"}, {MakeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeTime(nil, tm))), "/Table/42/Sat Mar 7 11:06:39 UTC 2015"}, // others {MakeKey([]byte("")), "/Min"}, {MakeKey(MakeTablePrefix(42), roachpb.RKey([]byte{0x20, 'a', 0x00, 0x02})), "/Table/42/<util/encoding/encoding.go:407: unknown escape>"}, } for i, test := range testCases { keyInfo := PrettyPrint(test.key) if test.exp != keyInfo { t.Fatalf("%d: expected %s, got %s", i, test.exp, keyInfo) } if test.exp != test.key.String() { t.Fatalf("%d: expected %s, got %s", i, test.exp, keyInfo) } } }
// SequenceCacheKeyPrefix returns the prefix common to all sequence cache keys // for the given ID. func SequenceCacheKeyPrefix(rangeID roachpb.RangeID, id []byte) roachpb.Key { return MakeRangeIDKey(rangeID, LocalSequenceCacheSuffix, encoding.EncodeBytes(nil, id)) }