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.

  1. // Merge function to append one byte slice to another
  2. func add(originalValue, newValue []byte) []byte {
  3. return append(originalValue, newValue...)
  4. }

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.

  1. key := []byte("merge")
  2. m := db.GetMergeOperator(key, add, 200*time.Millisecond)
  3. defer m.Stop()
  4. m.Add([]byte("A"))
  5. m.Add([]byte("B"))
  6. m.Add([]byte("C"))
  7. res, _ := m.Get() // res should have value ABC encoded

Example: Merge operator which increments a counter

  1. func uint64ToBytes(i uint64) []byte {
  2. var buf [8]byte
  3. binary.BigEndian.PutUint64(buf[:], i)
  4. return buf[:]
  5. }
  6. func bytesToUint64(b []byte) uint64 {
  7. return binary.BigEndian.Uint64(b)
  8. }
  9. // Merge function to add two uint64 numbers
  10. func add(existing, new []byte) []byte {
  11. return uint64ToBytes(bytesToUint64(existing) + bytesToUint64(new))
  12. }

It can be used as

  1. key := []byte("merge")
  2. m := db.GetMergeOperator(key, add, 200*time.Millisecond)
  3. defer m.Stop()
  4. m.Add(uint64ToBytes(1))
  5. m.Add(uint64ToBytes(2))
  6. m.Add(uint64ToBytes(3))
  7. res, _ := m.Get() // res should have value 6 encoded