blob: 58d8833c1fae3cecea594a328373cfc0a4ecef03 [file] [log] [blame]
Manish R Jainffd14f02017-09-28 08:54:331package badger
2
3import (
4 "bytes"
5 "encoding/binary"
6 "fmt"
7 "hash/crc32"
8
9 "github.com/dgraph-io/badger/y"
10)
11
12type valuePointer struct {
13 Fid uint32
14 Len uint32
15 Offset uint32
16}
17
18func (p valuePointer) Less(o valuePointer) bool {
19 if p.Fid != o.Fid {
20 return p.Fid < o.Fid
21 }
22 if p.Offset != o.Offset {
23 return p.Offset < o.Offset
24 }
25 return p.Len < o.Len
26}
27
28func (p valuePointer) IsZero() bool {
29 return p.Fid == 0 && p.Offset == 0 && p.Len == 0
30}
31
32const vptrSize = 12
33
34// Encode encodes Pointer into byte buffer.
35func (p valuePointer) Encode(b []byte) []byte {
36 binary.BigEndian.PutUint32(b[:4], p.Fid)
37 binary.BigEndian.PutUint32(b[4:8], p.Len)
38 binary.BigEndian.PutUint32(b[8:12], p.Offset)
39 return b[:vptrSize]
40}
41
42func (p *valuePointer) Decode(b []byte) {
43 p.Fid = binary.BigEndian.Uint32(b[:4])
44 p.Len = binary.BigEndian.Uint32(b[4:8])
45 p.Offset = binary.BigEndian.Uint32(b[8:12])
46}
47
48// header is used in value log as a header before Entry.
49type header struct {
Deepak Joisa5499e52017-11-02 02:03:1450 klen uint32
51 vlen uint32
52 expiresAt uint64
53 meta byte
54 userMeta byte
Manish R Jainffd14f02017-09-28 08:54:3355}
56
57const (
Deepak Joisa5499e52017-11-02 02:03:1458 headerBufSize = 18
Manish R Jainffd14f02017-09-28 08:54:3359)
60
61func (h header) Encode(out []byte) {
62 y.AssertTrue(len(out) >= headerBufSize)
63 binary.BigEndian.PutUint32(out[0:4], h.klen)
64 binary.BigEndian.PutUint32(out[4:8], h.vlen)
Deepak Joisa5499e52017-11-02 02:03:1465 binary.BigEndian.PutUint64(out[8:16], h.expiresAt)
66 out[16] = h.meta
67 out[17] = h.userMeta
Manish R Jainffd14f02017-09-28 08:54:3368}
69
70// Decodes h from buf.
71func (h *header) Decode(buf []byte) {
72 h.klen = binary.BigEndian.Uint32(buf[0:4])
73 h.vlen = binary.BigEndian.Uint32(buf[4:8])
Deepak Joisa5499e52017-11-02 02:03:1474 h.expiresAt = binary.BigEndian.Uint64(buf[8:16])
75 h.meta = buf[16]
76 h.userMeta = buf[17]
Manish R Jainffd14f02017-09-28 08:54:3377}
78
Deepak Jois5bc2e162017-11-30 03:04:5779// Entry provides Key, Value, UserMeta and ExpiresAt. This struct can be used by the user to set data.
80type Entry struct {
Deepak Joisa5499e52017-11-02 02:03:1481 Key []byte
82 Value []byte
83 UserMeta byte
Deepak Jois33ae1e82017-12-05 04:53:0584 ExpiresAt uint64 // time.Unix
Deepak Joisa5499e52017-11-02 02:03:1485 meta byte
Manish R Jainffd14f02017-09-28 08:54:3386
87 // Fields maintained internally.
88 offset uint32
89}
90
Deepak Jois5bc2e162017-11-30 03:04:5791func (e *Entry) estimateSize(threshold int) int {
Manish R Jainffd14f02017-09-28 08:54:3392 if len(e.Value) < threshold {
93 return len(e.Key) + len(e.Value) + 2 // Meta, UserMeta
94 }
95 return len(e.Key) + 12 + 2 // 12 for ValuePointer, 2 for metas.
96}
97
98// Encodes e to buf. Returns number of bytes written.
Deepak Jois5bc2e162017-11-30 03:04:5799func encodeEntry(e *Entry, buf *bytes.Buffer) (int, error) {
Deepak Joisa5499e52017-11-02 02:03:14100 h := header{
101 klen: uint32(len(e.Key)),
102 vlen: uint32(len(e.Value)),
103 expiresAt: e.ExpiresAt,
104 meta: e.meta,
105 userMeta: e.UserMeta,
106 }
Manish R Jainffd14f02017-09-28 08:54:33107
108 var headerEnc [headerBufSize]byte
109 h.Encode(headerEnc[:])
110
111 hash := crc32.New(y.CastagnoliCrcTable)
112
113 buf.Write(headerEnc[:])
114 hash.Write(headerEnc[:])
115
116 buf.Write(e.Key)
117 hash.Write(e.Key)
118
119 buf.Write(e.Value)
120 hash.Write(e.Value)
121
Steven Allen5242a992018-10-04 21:40:52122 var crcBuf [crc32.Size]byte
Manish R Jainffd14f02017-09-28 08:54:33123 binary.BigEndian.PutUint32(crcBuf[:], hash.Sum32())
124 buf.Write(crcBuf[:])
125
126 return len(headerEnc) + len(e.Key) + len(e.Value) + len(crcBuf), nil
127}
128
Deepak Jois5bc2e162017-11-30 03:04:57129func (e Entry) print(prefix string) {
Manish R Jainffd14f02017-09-28 08:54:33130 fmt.Printf("%s Key: %s Meta: %d UserMeta: %d Offset: %d len(val)=%d",
Deepak Joisa5499e52017-11-02 02:03:14131 prefix, e.Key, e.meta, e.UserMeta, e.offset, len(e.Value))
Manish R Jainffd14f02017-09-28 08:54:33132}