Skip to content

Commit

Permalink
Implement FWWRegister
Browse files Browse the repository at this point in the history
  • Loading branch information
dinoplatogo committed Nov 5, 2024
1 parent 9773ce2 commit 5419396
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
77 changes: 77 additions & 0 deletions lib/crdt/fww_register.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
defmodule CRDT.FWWRegister do
@moduledoc """
A first-write-wins register
Is used to store simple values with a timestamp. Using `merge` on two registers
will result in creating a register with the value corresponding to the oldest
timestamp
"""

@type t :: %CRDT.FWWRegister{
value: term() | nil,
timestamp: pos_integer()
}

defstruct value: nil, timestamp: System.system_time()

@doc """
Creates a new register with the value set to the supplied parameter or nil
and the current timestamp as returned by `System.system_time/0`
iex> CRDT.FWWRegister.new()
%CRDT.FWWRegister{value: nil}
iex> CRDT.FWWRegister.new("data")
%CRDT.FWWRegister{value: "data"}
"""
@spec new :: t()
def new, do: %CRDT.FWWRegister{}

@spec new(term()) :: t()
def new(data), do: %CRDT.FWWRegister{value: data}

@doc """
Sets the value of the register to the supplied parameter and updates the
timestamp to the current timestamp as returned by `System.system_time/0`
iex> CRDT.FWWRegister.new() |> CRDT.FWWRegister.set("data")
...> |> CRDT.value()
"data"
"""
@spec set(t(), term()) :: t()
def set(_register, data) do
%CRDT.FWWRegister{value: data, timestamp: System.system_time()}
end
end

defimpl CRDT, for: CRDT.FWWRegister do
@moduledoc """
Implements the CRDT behaviour for the FWWRegister
"""
@doc """
Returns the value of the register
iex> CRDT.FWWRegister.new("data") |> CRDT.value()
"data"
"""
def value(register), do: register.value

@doc """
Merges two registers and returns a new register with the value corresponding
to the oldest timestamp
iex> CRDT.FWWRegister.new("data") |> CRDT.merge(CRDT.FWWRegister.new("data2"))
...> |> CRDT.value()
"data"
"""

def merge(register1, register2) do
if register1.timestamp <= register2.timestamp do
register1
else
register2
end
end
end
5 changes: 5 additions & 0 deletions test/crdt/fww_register_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
defmodule CRDT.FWWRegisterTest do
use ExUnit.Case
doctest CRDT.FWWRegister
doctest CRDT.CRDT.FWWRegister
end

0 comments on commit 5419396

Please sign in to comment.