-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpaxos.go
76 lines (65 loc) · 1.35 KB
/
paxos.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package main
import "math"
type Paxos struct {
rs []string
n2 bool
leader string
latency *LatencyTable
}
func NewPaxos(rs []string, t *LatencyTable, n2 bool) *Paxos {
return &Paxos{
rs: rs,
n2: n2,
leader: "",
latency: t,
}
}
func (p *Paxos) SetReplicas(rs []string) {
p.rs = rs
}
func (p *Paxos) GetReplicas() []string {
return p.rs
}
func (p *Paxos) Accept(c string, _ bool) float64 {
closest := p.leader
if p.n2 {
closest = Client(c).ClosestReplica(p.rs, p.latency)
}
m := math.Inf(1)
slowQs := QuorumsOfSize(len(p.rs)/2+1, p.rs, NoFilter)
for _, q := range slowQs {
qm := 0.0
for r := range q {
l := p.m2b(c, r, closest)
qm = math.Max(qm, l)
}
m = math.Min(m, qm)
}
return Round(m + p.latency.OneWayLatency(closest, c))
}
func (p *Paxos) m2b(client, replica, closest string) float64 {
l1 := p.latency.OneWayLatency(client, p.leader)
l2 := p.latency.OneWayLatency(p.leader, replica)
l3 := p.latency.OneWayLatency(replica, closest)
return Round(l1 + l2 + l3)
}
func (p *Paxos) SetAverageBestLeader(cs []string) (string, float64) {
min := math.Inf(1)
leader := ""
for _, r := range p.rs {
p.leader = r
l := Average(p, cs, true)
if l < min {
min = l
leader = r
}
}
p.leader = leader
return leader, min
}
func (p *Paxos) String() string {
if p.n2 {
return "N²"
}
return "Pa"
}