/
keys.go
113 lines (96 loc) · 3.01 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
/*
This file supports keyspaces for point annotation data type.
*/
package annotation
import (
"encoding/binary"
"fmt"
"github.com/janelia-flyem/dvid/datastore"
"github.com/janelia-flyem/dvid/dvid"
"github.com/janelia-flyem/dvid/storage"
)
const (
// keyUnknown should never be used and is a check for corrupt or incorrectly set keys
keyUnknown storage.TKeyClass = iota
// reserved type-specific key for metadata
keyProperties = datastore.PropertyTKeyClass
// key is tag id. value is serialization of the tag name and all synaptic elements it contains.
keyTag = 70
// key is label. value is serialization of all synaptic elements associated with a label.
keyLabel = 71
// key is block coordinate. value is serialization of synaptic elements.
keyBlock = 72
)
// DescribeTKeyClass returns a string explanation of what a particular TKeyClass
// is used for. Implements the datastore.TKeyClassDescriber interface.
func (d *Data) DescribeTKeyClass(tkc storage.TKeyClass) string {
switch tkc {
case keyTag:
return "annotation tag key"
case keyLabel:
return "annotation label key"
case keyBlock:
return "annotation block coord key"
default:
}
return "unknown annotation key"
}
// NewTagTKey returns a TKey for a given tag.
func NewTagTKey(tag Tag) (storage.TKey, error) {
if len(tag) == 0 {
return nil, fmt.Errorf("empty tag not permitted")
}
return storage.NewTKey(keyTag, append([]byte(tag), 0)), nil
}
// DecodeTagTKey returns the Tag corresponding to this type-specific key.
func DecodeTagTKey(tk storage.TKey) (Tag, error) {
ibytes, err := tk.ClassBytes(keyTag)
if err != nil {
return "", err
}
sz := len(ibytes) - 1
if sz <= 0 {
return "", fmt.Errorf("empty tag")
}
if ibytes[sz] != 0 {
return "", fmt.Errorf("expected 0 byte ending tag key, got %d", ibytes[sz])
}
return Tag(ibytes[:sz]), nil
}
func NewLabelTKey(label uint64) storage.TKey {
buf := make([]byte, 8)
binary.BigEndian.PutUint64(buf, label)
return storage.NewTKey(keyLabel, buf)
}
func DecodeLabelTKey(tk storage.TKey) (label uint64, err error) {
ibytes, err := tk.ClassBytes(keyLabel)
if err != nil {
return
}
label = binary.BigEndian.Uint64(ibytes[0:8])
return
}
func BlockTKeyRange() (min, max storage.TKey) {
return NewBlockTKey(dvid.MinChunkPoint3d), NewBlockTKey(dvid.MaxChunkPoint3d)
}
func BlockTKeyZRange(begBlockCoord, endBlockCoord dvid.ChunkPoint3d) (min, max storage.TKey) {
begTKey := NewBlockTKey(dvid.ChunkPoint3d{dvid.MinChunkPoint3d[0], dvid.MinChunkPoint3d[1], begBlockCoord[2]})
endTKey := NewBlockTKey(dvid.ChunkPoint3d{dvid.MaxChunkPoint3d[0], dvid.MaxChunkPoint3d[1], endBlockCoord[2]})
return begTKey, endTKey
}
func NewBlockTKey(pt dvid.ChunkPoint3d) storage.TKey {
idx := dvid.IndexZYX(pt)
return storage.NewTKey(keyBlock, idx.Bytes())
}
func DecodeBlockTKey(tk storage.TKey) (pt dvid.ChunkPoint3d, err error) {
ibytes, err := tk.ClassBytes(keyBlock)
if err != nil {
return
}
var idx dvid.IndexZYX
if err = idx.IndexFromBytes(ibytes); err != nil {
return
}
pt = dvid.ChunkPoint3d(idx)
return
}