Files
zapdb/structs.go
Francesc Campoy 74d83eea3e Removing support for Go Modules
As explained in https://discuss.dgraph.io/t/go-modules-on-badger-and-dgraph/4662,
Go Modules force an import path rename that currently breaks support for most other
dependency management systems, including dep.

It seems an effort is being made to add support for this import path renaming by
patching the go tool itself, but until the community hasn't settled and Go Modules
is an easier option to adopt, we are simply not supporting them.

For those willing to use badger v2 from Go modules it is still very simple, you might
notice that once you set the version to be v2.0.0 a +incompatible will be added to it
indicating the dependency has not opted-in into Go Modules. That's normal and not to
be a concern.
2019-06-25 10:52:36 -07:00

187 lines
4.9 KiB
Go

package badger
import (
"bytes"
"encoding/binary"
"fmt"
"hash/crc32"
"time"
"github.com/dgraph-io/badger/y"
)
type valuePointer struct {
Fid uint32
Len uint32
Offset uint32
}
func (p valuePointer) Less(o valuePointer) bool {
if p.Fid != o.Fid {
return p.Fid < o.Fid
}
if p.Offset != o.Offset {
return p.Offset < o.Offset
}
return p.Len < o.Len
}
func (p valuePointer) IsZero() bool {
return p.Fid == 0 && p.Offset == 0 && p.Len == 0
}
const vptrSize = 12
// Encode encodes Pointer into byte buffer.
func (p valuePointer) Encode(b []byte) []byte {
binary.BigEndian.PutUint32(b[:4], p.Fid)
binary.BigEndian.PutUint32(b[4:8], p.Len)
binary.BigEndian.PutUint32(b[8:12], p.Offset)
return b[:vptrSize]
}
func (p *valuePointer) Decode(b []byte) {
p.Fid = binary.BigEndian.Uint32(b[:4])
p.Len = binary.BigEndian.Uint32(b[4:8])
p.Offset = binary.BigEndian.Uint32(b[8:12])
}
// header is used in value log as a header before Entry.
type header struct {
klen uint32
vlen uint32
expiresAt uint64
meta byte
userMeta byte
}
const (
headerBufSize = 18
)
func (h header) Encode(out []byte) {
y.AssertTrue(len(out) >= headerBufSize)
binary.BigEndian.PutUint32(out[0:4], h.klen)
binary.BigEndian.PutUint32(out[4:8], h.vlen)
binary.BigEndian.PutUint64(out[8:16], h.expiresAt)
out[16] = h.meta
out[17] = h.userMeta
}
// Decodes h from buf.
func (h *header) Decode(buf []byte) {
h.klen = binary.BigEndian.Uint32(buf[0:4])
h.vlen = binary.BigEndian.Uint32(buf[4:8])
h.expiresAt = binary.BigEndian.Uint64(buf[8:16])
h.meta = buf[16]
h.userMeta = buf[17]
}
// Entry provides Key, Value, UserMeta and ExpiresAt. This struct can be used by
// the user to set data.
type Entry struct {
Key []byte
Value []byte
UserMeta byte
ExpiresAt uint64 // time.Unix
meta byte
// Fields maintained internally.
offset uint32
skipVlog bool
}
func (e *Entry) estimateSize(threshold int) int {
if len(e.Value) < threshold {
return len(e.Key) + len(e.Value) + 2 // Meta, UserMeta
}
return len(e.Key) + 12 + 2 // 12 for ValuePointer, 2 for metas.
}
// Encodes e to buf. Returns number of bytes written.
func encodeEntry(e *Entry, buf *bytes.Buffer) (int, error) {
h := header{
klen: uint32(len(e.Key)),
vlen: uint32(len(e.Value)),
expiresAt: e.ExpiresAt,
meta: e.meta,
userMeta: e.UserMeta,
}
var headerEnc [headerBufSize]byte
h.Encode(headerEnc[:])
hash := crc32.New(y.CastagnoliCrcTable)
buf.Write(headerEnc[:])
if _, err := hash.Write(headerEnc[:]); err != nil {
return 0, err
}
buf.Write(e.Key)
if _, err := hash.Write(e.Key); err != nil {
return 0, err
}
buf.Write(e.Value)
if _, err := hash.Write(e.Value); err != nil {
return 0, err
}
var crcBuf [crc32.Size]byte
binary.BigEndian.PutUint32(crcBuf[:], hash.Sum32())
buf.Write(crcBuf[:])
return len(headerEnc) + len(e.Key) + len(e.Value) + len(crcBuf), nil
}
func (e Entry) print(prefix string) {
fmt.Printf("%s Key: %s Meta: %d UserMeta: %d Offset: %d len(val)=%d",
prefix, e.Key, e.meta, e.UserMeta, e.offset, len(e.Value))
}
// NewEntry creates a new entry with key and value passed in args. This newly created entry can be
// set in a transaction by calling txn.SetEntry(). All other properties of Entry can be set by
// calling WithMeta, WithDiscard, WithTTL methods on it.
// This function uses key and value reference, hence users must
// not modify key and value until the end of transaction.
func NewEntry(key, value []byte) *Entry {
return &Entry{
Key: key,
Value: value,
}
}
// WithMeta adds meta data to Entry e. This byte is stored alongside the key
// and can be used as an aid to interpret the value or store other contextual
// bits corresponding to the key-value pair of entry.
func (e *Entry) WithMeta(meta byte) *Entry {
e.UserMeta = meta
return e
}
// WithDiscard adds a marker to Entry e. This means all the previous versions of the key (of the
// Entry) will be eligible for garbage collection.
// This method is only useful if you have set a higher limit for options.NumVersionsToKeep. The
// default setting is 1, in which case, this function doesn't add any more benefit. If however, you
// have a higher setting for NumVersionsToKeep (in Dgraph, we set it to infinity), you can use this
// method to indicate that all the older versions can be discarded and removed during compactions.
func (e *Entry) WithDiscard() *Entry {
e.meta = bitDiscardEarlierVersions
return e
}
// WithTTL adds time to live duration to Entry e. Entry stored with a TTL would automatically expire
// after the time has elapsed, and will be eligible for garbage collection.
func (e *Entry) WithTTL(dur time.Duration) *Entry {
e.ExpiresAt = uint64(time.Now().Add(dur).Unix())
return e
}
// withMergeBit sets merge bit in entry's metadata. This
// function is called by MergeOperator's Add method.
func (e *Entry) withMergeBit() *Entry {
e.meta = bitMergeEntry
return e
}