Merge Operations
Badger provides support for ordered merge operations. You can define a func of type MergeFunc
which takes in an existing value, and a value to be merged with it. It returns a new value which is the result of the merge operation. All values are specified in byte arrays. For e.g., here is a merge function (add
) which appends a []byte
value to an existing []byte
value.
// Merge function to append one byte slice to another
func add(originalValue, newValue []byte) []byte {
return append(originalValue, newValue...)
}
This function can then be passed to the DB.GetMergeOperator()
method, along with a key, and a duration value. The duration specifies how often the merge function is run on values that have been added using the MergeOperator.Add()
method.
MergeOperator.Get()
method can be used to retrieve the cumulative value of the key associated with the merge operation.
key := []byte("merge")
m := db.GetMergeOperator(key, add, 200*time.Millisecond)
defer m.Stop()
m.Add([]byte("A"))
m.Add([]byte("B"))
m.Add([]byte("C"))
res, _ := m.Get() // res should have value ABC encoded
Example: Merge operator which increments a counter
func uint64ToBytes(i uint64) []byte {
var buf [8]byte
binary.BigEndian.PutUint64(buf[:], i)
return buf[:]
}
func bytesToUint64(b []byte) uint64 {
return binary.BigEndian.Uint64(b)
}
// Merge function to add two uint64 numbers
func add(existing, new []byte) []byte {
return uint64ToBytes(bytesToUint64(existing) + bytesToUint64(new))
}
It can be used as
key := []byte("merge")
m := db.GetMergeOperator(key, add, 200*time.Millisecond)
defer m.Stop()
m.Add(uint64ToBytes(1))
m.Add(uint64ToBytes(2))
m.Add(uint64ToBytes(3))
res, _ := m.Get() // res should have value 6 encoded