-
Notifications
You must be signed in to change notification settings - Fork 0
/
members.go
109 lines (100 loc) · 2.48 KB
/
members.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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package alternator
import (
"container/list"
"fmt"
"sync"
)
// Members stores the members of a node
type Members struct {
sync.RWMutex
List *list.List
Map map[Key]*list.Element
}
// Init initializes a Members struct. It must be called before any other call
// to a Members method.
func (members *Members) init() {
members.List = list.New()
members.Map = make(map[Key]*list.Element)
// altNode.Members.Add(&selfExt)
}
// getPeer gets a peer from an element of Members.List
func getPeer(e *list.Element) *Peer {
if e != nil {
return e.Value.(*Peer)
}
return nil
}
// findSuccessor finds the successor of a key in the ring
func (members *Members) findSuccessor(key Key) *list.Element {
// Find ID of successor
for e := members.List.Front(); e != nil; e = e.Next() {
if getPeer(e).ID.Compare(key) > 0 {
return e
}
}
// Nothing bigger in ring, successor is first node
return members.List.Front()
}
// insert adds a node to the members if not already there, returns true if added
func (members *Members) insert(peer *Peer) *list.Element {
i := 0
// Iterate through members
for e := members.List.Front(); e != nil; e = e.Next() {
if e == nil {
break
}
current := getPeer(e)
var prevID Key
if prev := e.Prev(); prev != nil {
prevID = getPeer(prev).ID
} else {
prevID = MinKey
}
// Already in Members
if peer.ID.Compare(current.ID) == 0 {
return nil
} else if (peer.ID.Compare(prevID) > 0) && (peer.ID.Compare(current.ID) < 0) {
// Correct spot to add, add to list and map
e := members.List.InsertBefore(peer, e)
members.Map[peer.ID] = e
return e
}
i++
}
// Append at end if not in members and not added by loop
e := members.List.PushBack(peer)
members.Map[peer.ID] = e
return e
}
// remove deletes a node from members
func (members *Members) remove(del *Peer) {
for e := members.List.Front(); e != nil; e = e.Next() {
if getPeer(e).ID == del.ID {
members.List.Remove(e)
delete(members.Map, del.ID)
}
}
}
func (members Members) String() (str string) {
i := 0
for e := members.List.Front(); e != nil; e = e.Next() {
str += fmt.Sprintf("member %d: %s\n", i, getPeer(e).String())
i++
}
return
}
// getRandom returns a random member from the ring
func (members *Members) getRandom() *Peer {
// i := 0
// random := rand.Intn(len(members.Map))
// for _, member := range members.Map {
// if i == random {
// return getPeer(member)
// }
// i++
// }
for _, member := range members.Map {
return getPeer(member)
}
return nil
}