/
collection.go
124 lines (110 loc) · 3.05 KB
/
collection.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
package collections
import (
"errors"
"strconv"
)
type CollectionManifest struct {
UID string `json:"uid"`
Scopes []CollectionScope `json:"scopes"`
}
const COLLECTION_SUPPORTED_VERSION uint32 = 7
const CID_FOR_BUCKET uint32 = 0
type CollectionScope struct {
Name string `json:"name"`
UID string `json:"uid"` // base 16 string
Collections []Collection `json:"collections"`
}
type Collection struct {
Name string `json:"name"`
UID string `json:"uid"` // base-16 string
}
var COLLECTION_ID_NIL = errors.New("manifest not found")
var SCOPE_NOT_FOUND = errors.New("Scope Not defined")
var COLLECTION_NOT_FOUND = errors.New("Collection Not defined")
func (cm *CollectionManifest) GetScopes() map[string][]string {
s := make(map[string][]string)
for _, cmScope := range cm.Scopes {
collectionList := make([]string, 0, len(cmScope.Collections))
for _, c := range cmScope.Collections {
collectionList = append(collectionList, c.Name)
}
s[cmScope.Name] = collectionList
}
return s
}
func (cm *CollectionManifest) GetCollectionID(scope, collection string) (uint32, error) {
for _, cmScope := range cm.Scopes {
if cmScope.Name == scope {
for _, cmCollection := range cmScope.Collections {
if cmCollection.Name == collection {
return GetHexToUint32(cmCollection.UID)
}
}
return 0, COLLECTION_NOT_FOUND
}
}
return 0, SCOPE_NOT_FOUND
}
func (cm *CollectionManifest) GetScopeAndCollectionID(scope, collection string) (uint32, uint32, error) {
for _, cmScope := range cm.Scopes {
if cmScope.Name == scope {
// Don't care about collection id
if collection == "" {
scopeId, err := GetHexToUint32(cmScope.UID)
if err != nil {
return 0, 0, err
}
return scopeId, 0, nil
}
for _, cmCollection := range cmScope.Collections {
if cmCollection.Name == collection {
scopeId, err := GetHexToUint32(cmScope.UID)
if err != nil {
return 0, 0, err
}
colId, err := GetHexToUint32(cmCollection.UID)
if err != nil {
return 0, 0, err
}
return scopeId, colId, nil
}
}
return 0, 0, COLLECTION_NOT_FOUND
}
}
return 0, 0, SCOPE_NOT_FOUND
}
func (cm *CollectionManifest) GetManifestId() string {
return cm.UID
}
// Decodes the encoded value according to LEB128 uint32 scheme
// Returns the decoded key as byte stream, collectionID as uint32 value
func LEB128Dec(data []byte) ([]byte, uint32) {
if len(data) == 0 {
return data, 0
}
cid := (uint32)(data[0] & 0x7f)
end := 1
if data[0]&0x80 == 0x80 {
shift := 7
for end = 1; end < len(data); end++ {
cid |= ((uint32)(data[end]&0x7f) << (uint32)(shift))
if data[end]&0x80 == 0 {
break
}
shift += 7
}
end++
}
return data[end:], cid
}
func GetHexToUint32(keyspaceComponentHexId string) (uint32, error) {
if keyspaceComponentHexId == "" {
return CID_FOR_BUCKET, nil
}
keyspaceComponentId, err := strconv.ParseUint(keyspaceComponentHexId, 16, 32)
if err != nil {
return 0, errors.New("error decoding keyspaceComponentId")
}
return (uint32)(keyspaceComponentId), nil
}