-
Notifications
You must be signed in to change notification settings - Fork 35
/
Copy pathcolony.go
140 lines (115 loc) · 2.72 KB
/
colony.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package beehive
import (
"encoding/gob"
"encoding/json"
"fmt"
)
const (
Nil uint64 = 0
)
// Colony is the colony of bees that maintain a consistent state.
type Colony struct {
ID uint64 `json:"id"`
Leader uint64 `json:"leader"`
Followers []uint64 `json:"followers"`
}
func (c Colony) String() string {
return fmt.Sprintf("colony(id=%v, leader=%v, followers=%+v)", c.ID, c.Leader,
c.Followers)
}
// IsNil returns whether the colony does not represent a valid colony.
func (c Colony) IsNil() bool {
return c.ID == Nil && c.Leader == Nil && len(c.Followers) == 0
}
// IsLeader returns whether id is the leader of this colony.
func (c Colony) IsLeader(id uint64) bool {
return c.Leader == id
}
// IsFollower retursn whether id is the follower in this colony.
func (c Colony) IsFollower(id uint64) bool {
for _, s := range c.Followers {
if s == id {
return true
}
}
return false
}
// Contains returns whether id is the leader or a follower in this colony.
func (c Colony) Contains(id uint64) bool {
return c.IsLeader(id) || c.IsFollower(id)
}
// AddFollower adds a follower to the colony. Returns false if id is already a
// follower.
func (c *Colony) AddFollower(id uint64) bool {
if id == Nil {
return false
}
if c.IsLeader(id) {
return false
}
if c.IsFollower(id) {
return false
}
c.Followers = append(c.Followers, id)
return true
}
// DelFollower deletes id from the followers of this colony. Returns false if
// id is not already a follower.
func (c *Colony) DelFollower(id uint64) bool {
for i, s := range c.Followers {
if s == id {
c.Followers = append(c.Followers[:i], c.Followers[i+1:]...)
return true
}
}
return false
}
// DeepCopy creates a cloned copy of the colony.
func (c Colony) DeepCopy() Colony {
f := make([]uint64, len(c.Followers))
copy(f, c.Followers)
c.Followers = f
return c
}
// Equals return whether c is equal to thatC.
func (c Colony) Equals(thatC Colony) bool {
if c.ID != thatC.ID {
return false
}
if c.Leader != thatC.Leader {
return false
}
if len(c.Followers) != len(thatC.Followers) {
return false
}
if len(c.Followers) == 0 && len(thatC.Followers) == 0 {
return true
}
f := make(map[uint64]bool)
for _, b := range c.Followers {
f[b] = true
}
for _, b := range thatC.Followers {
if _, ok := f[b]; !ok {
return false
}
}
return true
}
// Bytes returns the []byte representation of this colony.
func (c *Colony) Bytes() ([]byte, error) {
j, err := json.Marshal(c)
if err != nil {
return nil, err
}
return j, nil
}
// ColonyFromBytes creates a colony from its []byte representation.
func ColonyFromBytes(b []byte) (Colony, error) {
c := Colony{}
err := json.Unmarshal(b, &c)
return c, err
}
func init() {
gob.Register(Colony{})
}