The built-in merge operators, and helpers for their operand formats.
A merge operator lets you update a value without reading it first:
Slap.SlateDB.merge/4 writes an operand, and SlateDB combines the operands with
the key's value when the key is read or compacted. Choose one when opening
the database:
{:ok, db} = Slap.SlateDB.open("counters", store: store, merge_operator: :u64_add)
{:ok, _} = Slap.SlateDB.increment(db, "page:home:views")
{:ok, _} = Slap.SlateDB.merge(db, "page:home:views", Slap.SlateDB.MergeOperator.encode_u64(10))
{:ok, bin} = Slap.SlateDB.get(db, "page:home:views")
11 = Slap.SlateDB.MergeOperator.decode_u64(bin)| Operator | Operand and value | Result |
|---|---|---|
:u64_add | unsigned 64-bit little-endian integer (8 bytes) | sum, wrapping at 2^64 |
:i64_add | signed 64-bit little-endian integer (8 bytes) | sum, wrapping |
:u64_max | unsigned 64-bit little-endian integer (8 bytes) | largest |
:u64_min | unsigned 64-bit little-endian integer (8 bytes) | smallest |
:append | any binary | the value followed by each operand, oldest first |
A put/4 sets the base value that later operands merge into, and a
delete/3 clears it.
Things to know
- The operators run in Rust. SlateDB calls a merge operator from its own threads on reads, flushes and compactions, where calling back into Elixir would be slow and could deadlock. So custom Elixir operators are not supported.
- Operands are checked when they are written: a numeric operand that is
not 8 bytes is rejected with an
:invaliderror. - A
put/4value for a key that numeric operands merge into must also be 8 bytes. SlateDB cannot check that at write time. If it is not, reads of that key fail, and so does any compaction that includes it. - Every process that opens the database (writers,
Slap.SlateDB.Readers, a separate compactor) needs the same operator. Without one, reading a key that has operands fails with an:invaliderror.
Summary
Functions
Decodes a value written by :i64_add. nil stays nil.
Decodes a value written by a :u64_* operator. nil stays nil.
Encodes a signed integer as an :i64_add operand.
Encodes an unsigned integer as a :u64_add, :u64_max or :u64_min operand.
Functions
Decodes a value written by :i64_add. nil stays nil.
@spec decode_u64(binary() | nil) :: non_neg_integer() | nil
Decodes a value written by a :u64_* operator. nil stays nil.
Encodes a signed integer as an :i64_add operand.
@spec encode_u64(non_neg_integer()) :: binary()
Encodes an unsigned integer as a :u64_add, :u64_max or :u64_min operand.