Grove.Map.ORMap (Grove v0.1.1)

View Source

An Observed-Remove Map (OR-Map) CRDT.

Keys are managed using OR-Set semantics, allowing keys to be removed and re-added. Values can be any CRDT that implements Grove.CRDT.

Semantics

  • Key management: Keys use OR-Set semantics (add-wins)
  • Value merging: Values are recursively merged using their CRDT merge
  • Nested CRDTs: Values can be counters, registers, sets, or other maps

Delta-State Support

This CRDT supports delta-state replication:

  • delta/1 - Returns accumulated changes since last reset
  • reset_delta/1 - Clears the delta buffer after synchronization

Example

iex> alias Grove.Map.ORMap
iex> alias Grove.Counter.GCounter
iex> map = ORMap.new(:node_a)
iex> map = ORMap.put(map, "views", GCounter.new(:node_a))
iex> map = ORMap.update(map, "views", &GCounter.increment(&1, 5))
iex> ORMap.get(map, "views") |> GCounter.value()
5

Summary

Functions

Deletes a key from the map.

Returns the accumulated delta since the last reset.

Gets the value at the given key.

Gets the value at the given key, or returns the default.

Checks if the map contains the given key.

Returns the list of keys.

Merges two OR-Maps.

Creates a new OR-Map for the given actor.

Puts a value at the given key.

Resets the delta buffer after synchronization.

Returns the number of keys.

Updates the value at the given key using the provided function.

Returns the map as an Elixir map of key => CRDT value.

Types

actor()

@type actor() :: term()

t()

@type t() :: %Grove.Map.ORMap{
  actor: actor(),
  delta_buffer: t() | nil,
  keys: Grove.Set.ORSet.t(),
  values: %{required(term()) => term()}
}

Functions

delete(map, key)

@spec delete(t(), term()) :: t()

Deletes a key from the map.

Uses OR-Set remove semantics - concurrent puts will survive.

delta(or_map)

@spec delta(t()) :: t()

Returns the accumulated delta since the last reset.

get(or_map, key)

@spec get(t(), term()) :: term() | nil

Gets the value at the given key.

Returns nil if the key doesn't exist.

get(map, key, default)

@spec get(t(), term(), term()) :: term()

Gets the value at the given key, or returns the default.

has_key?(or_map, key)

@spec has_key?(t(), term()) :: boolean()

Checks if the map contains the given key.

keys(or_map)

@spec keys(t()) :: [term()]

Returns the list of keys.

merge(map1, map2)

@spec merge(t(), t()) :: t()

Merges two OR-Maps.

Keys are merged via OR-Set semantics. Values for common keys are merged using Grove.Mergeable.merge/2.

new(actor)

@spec new(actor()) :: t()

Creates a new OR-Map for the given actor.

put(map, key, value)

@spec put(t(), term(), term()) :: t()

Puts a value at the given key.

If the key already exists, the value is replaced. The value should be a CRDT that implements Grove.CRDT.

reset_delta(map)

@spec reset_delta(t()) :: t()

Resets the delta buffer after synchronization.

size(or_map)

@spec size(t()) :: non_neg_integer()

Returns the number of keys.

update(map, key, fun)

@spec update(t(), term(), (term() -> term())) :: t()

Updates the value at the given key using the provided function.

The function receives the current value and should return the new value. If the key doesn't exist, does nothing.

value(or_map)

@spec value(t()) :: map()

Returns the map as an Elixir map of key => CRDT value.