github.com/coocood/badger@v1.5.1-0.20200528065104-c02ac3616d04/structs.go (about) 1 package badger 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "fmt" 7 "hash/crc32" 8 9 "github.com/coocood/badger/y" 10 ) 11 12 // header is used in value log as a header before Entry. 13 type header struct { 14 klen uint32 15 vlen uint32 16 ver uint64 17 meta byte 18 19 // umlen is the length of UserMeta 20 umlen byte 21 } 22 23 const ( 24 headerBufSize = 18 25 metaNotEntryEncoded = 0 26 ) 27 28 func (h header) Encode(out []byte) { 29 y.Assert(len(out) >= headerBufSize) 30 // Because meta can never be 0xff, so 0x00 in vlog file indicates there is not an entry. 31 out[0] = ^h.meta 32 binary.BigEndian.PutUint32(out[1:5], h.klen) 33 binary.BigEndian.PutUint32(out[5:9], h.vlen) 34 binary.BigEndian.PutUint64(out[9:17], h.ver) 35 out[17] = h.umlen 36 } 37 38 // Decodes h from buf. 39 func (h *header) Decode(buf []byte) { 40 h.meta = ^buf[0] 41 h.klen = binary.BigEndian.Uint32(buf[1:5]) 42 h.vlen = binary.BigEndian.Uint32(buf[5:9]) 43 h.ver = binary.BigEndian.Uint64(buf[9:17]) 44 h.umlen = buf[17] 45 } 46 47 func isEncodedHeader(data []byte) bool { 48 if len(data) < 1 { 49 return false 50 } 51 return data[0] != metaNotEntryEncoded 52 } 53 54 // Entry provides Key, Value, UserMeta. This struct can be used by the user to set data. 55 type Entry struct { 56 Key y.Key 57 Value []byte 58 UserMeta []byte 59 meta byte 60 logOffset logOffset 61 62 // Fields maintained internally. 63 offset uint32 64 } 65 66 func (e *Entry) SetDelete() { 67 e.meta |= bitDelete 68 } 69 70 func (e *Entry) estimateSize() int { 71 return e.Key.Len() + len(e.Value) + len(e.UserMeta) + 2 // Meta, UserMeta 72 } 73 74 // Encodes e to buf. Returns number of bytes written. 75 func encodeEntry(e *Entry, buf *bytes.Buffer) (int, error) { 76 h := header{ 77 klen: uint32(len(e.Key.UserKey)), 78 vlen: uint32(len(e.Value)), 79 ver: e.Key.Version, 80 meta: e.meta, 81 umlen: byte(len(e.UserMeta)), 82 } 83 84 var headerEnc [headerBufSize]byte 85 h.Encode(headerEnc[:]) 86 87 hash := crc32.New(y.CastagnoliCrcTable) 88 89 buf.Write(headerEnc[:]) 90 hash.Write(headerEnc[:]) 91 92 buf.Write(e.UserMeta) 93 hash.Write(e.UserMeta) 94 95 buf.Write(e.Key.UserKey) 96 hash.Write(e.Key.UserKey) 97 98 buf.Write(e.Value) 99 hash.Write(e.Value) 100 101 var crcBuf [4]byte 102 binary.BigEndian.PutUint32(crcBuf[:], hash.Sum32()) 103 buf.Write(crcBuf[:]) 104 105 return len(headerEnc) + len(e.UserMeta) + len(e.Key.UserKey) + len(e.Value) + len(crcBuf), nil 106 } 107 108 func (e Entry) print(prefix string) { 109 fmt.Printf("%s Key: %s Meta: %d UserMeta: %v Offset: %d len(val)=%d", 110 prefix, e.Key, e.meta, e.UserMeta, e.offset, len(e.Value)) 111 }