-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdatum.go
More file actions
86 lines (71 loc) · 1.91 KB
/
datum.go
File metadata and controls
86 lines (71 loc) · 1.91 KB
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
package bugfruit
import (
"bytes"
)
// datum represents a key value pair and its metadata.
type datum struct {
meta *meta
key string
value []byte
idx uint32
}
// newDatum instantiates a new datum
func newDatum() *datum {
return &datum{meta: &meta{}}
}
// Set sets the key and value for a datum as well as its associated metadata.
func (d *datum) Set(key string, value []byte) error {
if !bytes.Equal(value, d.value) {
d.meta.valSize = uint32(len(value))
d.value = value
}
if key != d.key {
d.meta.keySize = uint32(len([]byte(key)))
d.key = key
}
return nil
}
// Clone returns a deep copy of a datum.
func (d *datum) Clone() *datum {
newD := newDatum()
newD.Set(d.key, d.value)
newD.idx = d.idx
return newD
}
// MarkDeleted marks a datum as deleted
func (d *datum) MarkDeleted() {
d.meta.deleted = byte(1)
}
// Deleted returns the deleted value of a datum's meta.
func (d *datum) Deleted() byte {
return d.meta.deleted
}
// Bytes converts a datum struct to a byte slice for writing to file.
func (d *datum) Bytes() []byte {
b := make([]byte, d.Size())
// add the metadata
copy(b[:metaSize], d.meta.Bytes())
// add the key
copy(b[metaSize:metaSize+d.meta.keySize], []byte(d.key))
// add the value
copy(b[metaSize+d.meta.keySize:], []byte(d.value))
return b
}
// KeyValFromBytes converts a byte slice to a key/value pair and saves it to the
// datum. It returns an error if the length of the byte slice does not equal the
// keySize plus the valSize.
func (d *datum) KeyValFromBytes(b []byte) (err error) {
if d.meta == nil {
return ErrNoMetadata
}
if uint32(len(b)) != d.meta.keySize+d.meta.valSize {
return ErrInvalidKeyValSlice
}
d.key = string(b[:d.meta.keySize])
d.value = b[d.meta.keySize : d.meta.keySize+d.meta.valSize]
return nil
}
// Size returns the size of the datum when written to file in bytes.
func (d *datum) Size() uint32 {
return d.meta.keySize + d.meta.valSize + metaSize
}