simplified paxos added more tests
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
101
lib/paxos.ex
101
lib/paxos.ex
@@ -1,51 +1,3 @@
|
||||
|
||||
|
||||
defmodule Ballot do
|
||||
|
||||
def init(name, number \\ 0) do
|
||||
{name, number}
|
||||
end
|
||||
|
||||
def inc(b, name \\ nil) do
|
||||
{old_name, number} = b
|
||||
|
||||
{
|
||||
if name == nil do
|
||||
old_name
|
||||
else
|
||||
name
|
||||
end,
|
||||
|
||||
number + 1
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
defp lexicographical_compare(a, b) do
|
||||
cond do
|
||||
a == b -> 0
|
||||
a > b -> 1
|
||||
true -> -1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
defp diff({name1, number1}, {name2, number2}) do
|
||||
diff = number1 - number2
|
||||
if diff == 0 do
|
||||
lexicographical_compare(name1, name2)
|
||||
else
|
||||
diff
|
||||
end
|
||||
end
|
||||
|
||||
def compare(b1, operator, b2) do
|
||||
operator.(diff(b1, b2), 0)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
#
|
||||
# Possible actions
|
||||
@@ -76,7 +28,6 @@ defmodule Paxos do
|
||||
processes: processes,
|
||||
leader: nil,
|
||||
instmap: %{},
|
||||
other_values: %{},
|
||||
decided: %{}
|
||||
}
|
||||
|
||||
@@ -90,6 +41,7 @@ defmodule Paxos do
|
||||
instmap =
|
||||
Map.put(state.instmap, inst, %{
|
||||
value: value,
|
||||
other_value: nil,
|
||||
ballot: Ballot.init(state.name, 0),
|
||||
aborted: false,
|
||||
ballot_value: nil,
|
||||
@@ -172,8 +124,6 @@ defmodule Paxos do
|
||||
end
|
||||
|
||||
{:rb_deliver, proc, {:other_propose, inst, value}} ->
|
||||
state = %{state | other_values: Map.put(state.other_values, inst, value)}
|
||||
|
||||
cond do
|
||||
has_finished(state, inst, true) ->
|
||||
EagerReliableBroadcast.broadcast(
|
||||
@@ -184,6 +134,7 @@ defmodule Paxos do
|
||||
|
||||
true ->
|
||||
state = has_or_create(state, inst)
|
||||
state = set_instmap(state, inst, fn map -> %{map | other_value: value} end)
|
||||
prepare(state, inst)
|
||||
end
|
||||
|
||||
@@ -399,7 +350,7 @@ defmodule Paxos do
|
||||
state.instmap[inst] == nil ->
|
||||
state
|
||||
|
||||
state.instmap[inst].value == nil and state.other_values[inst] == nil ->
|
||||
state.instmap[inst].value == nil and state.instmap[inst].other_value == nil ->
|
||||
state
|
||||
|
||||
state.instmap[inst] != nil and state.instmap[inst].has_sent_prepare ->
|
||||
@@ -449,7 +400,7 @@ defmodule Paxos do
|
||||
a_val =
|
||||
if a_val == nil do
|
||||
if state.instmap[inst].value == nil do
|
||||
state.other_values[inst]
|
||||
state.instmap[inst].other_value
|
||||
else
|
||||
state.instmap[inst].value
|
||||
end
|
||||
@@ -556,3 +507,47 @@ defmodule Paxos do
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Ballot do
|
||||
|
||||
def init(name, number \\ 0) do
|
||||
{name, number}
|
||||
end
|
||||
|
||||
def inc(b, name \\ nil) do
|
||||
{old_name, number} = b
|
||||
|
||||
{
|
||||
if name == nil do
|
||||
old_name
|
||||
else
|
||||
name
|
||||
end,
|
||||
|
||||
number + 1
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
defp lexicographical_compare(a, b) do
|
||||
cond do
|
||||
a == b -> 0
|
||||
a > b -> 1
|
||||
true -> -1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
defp diff({name1, number1}, {name2, number2}) do
|
||||
diff = number1 - number2
|
||||
if diff == 0 do
|
||||
lexicographical_compare(name1, name2)
|
||||
else
|
||||
diff
|
||||
end
|
||||
end
|
||||
|
||||
def compare(b1, operator, b2) do
|
||||
operator.(diff(b1, b2), 0)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user