adds round-robin update function

parent 40710a92
Pipeline #220859193 passed with stage
in 16 minutes and 9 seconds
......@@ -18,6 +18,7 @@ defmodule ClusterKV.DB do
| :last_30
| :unique
| :remove
| :round_robin
| fun()
@type t :: %__MODULE__{
......@@ -246,6 +247,7 @@ defmodule ClusterKV.DB do
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
......@@ -270,6 +272,22 @@ defmodule ClusterKV.DB do
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
......
......@@ -50,7 +50,7 @@ defmodule ClusterKV.Ring 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})
......@@ -61,7 +61,7 @@ defmodule ClusterKV.Ring do
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})
......
......@@ -68,6 +68,22 @@ defmodule ClusterKVTest do
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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment