| :last_30
| :unique
| :remove
+ | :round_robin
| fun()
@type t :: %__MODULE__{
defp get_update_function(:last_30), do: &last_30/2
defp get_update_function(:unique), do: &unique/2
defp get_update_function(:remove), do: &remove/2
+ defp get_update_function(:round_robin), do: &round_robin/2
defp get_update_function(fun) when is_function(fun), do: fun
defp get_update_function(_), do: fn _, _ -> :noop end
defp unique({k, old}, value), do: {k, [value | old] |> Enum.uniq()}
defp remove({k, values}, value), do: {k, List.delete(values, value)}
+ defp round_robin({id, v}, value) do
+ val =
+ case v do
+ [values] -> values
+ [_ | t] -> Enum.reduce(t, 0, fn a, _acc -> a end)
+ end
+
+ case val + 1 do
+ ni when ni < value ->
+ {id, [ni]}
+
+ _ ->
+ {id, [0]}
+ end
+ end
+
@spec do_get(db :: module(), key :: String.t()) :: element() | :not_found
defp do_get(db, key) do
case :ets.lookup(db, key) do
keyspace :: String.t(),
key :: String.t(),
value :: any(),
- fun :: atom()
+ fun :: DB.update_function()
) :: :ok
def update(name, keyspace, key, value, fun) do
:gen_statem.cast(ClusterKV.ring_name(name), {:update, keyspace, key, value, fun})
keyspace :: String.t(),
key :: String.t(),
value :: any(),
- fun :: atom()
+ fun :: DB.update_function()
) :: :updated | :noop
def update_if(name, keyspace, key, value, fun) do
:gen_statem.call(ClusterKV.ring_name(name), {:update_if, keyspace, key, value, fun})
assert {"test1:test", [:beautiful, :hello, :world]} =
ClusterKV.get(db, @keyspace, "test1:test")
+
+ ClusterKV.put(db, @keyspace, "test1:round-robin", 0)
+
+ assert {"test1:round-robin", [0]} = ClusterKV.get(db, @keyspace, "test1:round-robin")
+
+ ClusterKV.update(db, @keyspace, "test1:round-robin", 3, :round_robin)
+
+ assert {"test1:round-robin", [1]} = ClusterKV.get(db, @keyspace, "test1:round-robin")
+
+ ClusterKV.update(db, @keyspace, "test1:round-robin", 3, :round_robin)
+
+ assert {"test1:round-robin", [2]} = ClusterKV.get(db, @keyspace, "test1:round-robin")
+
+ ClusterKV.update(db, @keyspace, "test1:round-robin", 3, :round_robin)
+
+ assert {"test1:round-robin", [0]} = ClusterKV.get(db, @keyspace, "test1:round-robin")
end
test "update_if", %{db: db} do