forked from dgraph-io/dgraph
-
Notifications
You must be signed in to change notification settings - Fork 0
/
keys.go
134 lines (107 loc) · 2.44 KB
/
keys.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package x
import (
"encoding/binary"
"math"
)
const (
byteData = byte(0x00)
byteIndex = byte(0x01)
byteReverse = byte(0x02)
)
func writeAttr(buf []byte, attr string) []byte {
AssertTrue(len(attr) < math.MaxUint16)
binary.BigEndian.PutUint16(buf[:2], uint16(len(attr)))
rest := buf[2:]
AssertTrue(len(attr) == copy(rest, attr[:]))
return rest[len(attr):]
}
func DataKey(attr string, uid uint64) []byte {
buf := make([]byte, 2+len(attr)+1+8)
rest := writeAttr(buf, attr)
rest[0] = byteData
rest = rest[1:]
binary.BigEndian.PutUint64(rest, uid)
return buf
}
func ReverseKey(attr string, uid uint64) []byte {
buf := make([]byte, 2+len(attr)+1+8)
rest := writeAttr(buf, attr)
rest[0] = byteReverse
rest = rest[1:]
binary.BigEndian.PutUint64(rest, uid)
return buf
}
func IndexKey(attr, term string) []byte {
buf := make([]byte, 2+len(attr)+1+len(term))
rest := writeAttr(buf, attr)
rest[0] = byteIndex
rest = rest[1:]
AssertTrue(len(term) == copy(rest, term[:]))
return buf
}
type ParsedKey struct {
byteType byte
Attr string
Uid uint64
Term string
}
func (p ParsedKey) IsData() bool {
return p.byteType == byteData
}
func (p ParsedKey) IsReverse() bool {
return p.byteType == byteReverse
}
func (p ParsedKey) IsIndex() bool {
return p.byteType == byteIndex
}
func (p ParsedKey) SkipPredicate() []byte {
buf := make([]byte, 2+len(p.Attr)+1)
k := writeAttr(buf, p.Attr)
AssertTrue(len(k) == 1)
k[0] = 0xFF
return buf
}
func (p ParsedKey) SkipRangeOfSameType() []byte {
buf := make([]byte, 2+len(p.Attr)+1)
k := writeAttr(buf, p.Attr)
AssertTrue(len(k) == 1)
k[0] = p.byteType + 1
return buf
}
// DataPrefix returns the prefix for data keys.
func (p ParsedKey) DataPrefix() []byte {
buf := make([]byte, 2+len(p.Attr)+1)
k := writeAttr(buf, p.Attr)
AssertTrue(len(k) == 1)
k[0] = byteData
return buf
}
// IndexPrefix returns the prefix for index keys.
func (p ParsedKey) IndexPrefix() []byte {
buf := make([]byte, 2+len(p.Attr)+1)
k := writeAttr(buf, p.Attr)
AssertTrue(len(k) == 1)
k[0] = byteIndex
return buf
}
func Parse(key []byte) *ParsedKey {
p := &ParsedKey{}
sz := int(binary.BigEndian.Uint16(key[0:2]))
k := key[2:]
p.Attr = string(k[:sz])
k = k[sz:]
p.byteType = k[0]
k = k[1:]
switch p.byteType {
case byteData:
fallthrough
case byteReverse:
p.Uid = binary.BigEndian.Uint64(k)
case byteIndex:
p.Term = string(k)
default:
// Some other data type.
return nil
}
return p
}