-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathnode.go
144 lines (119 loc) · 2.86 KB
/
node.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
141
142
143
144
package chord
import (
"math/big"
"sync"
)
// Node represents a Node node involved in Chord protocol
type Node struct {
ID []byte
successor *RemoteNode
finger []*FingerEntry
predecessor *RemoteNode
fingerIndex int
sync.RWMutex
}
// RemoteNode represents a virtual remote Node involved in Chord protocol, containing hashed ID and host
type RemoteNode struct {
ID []byte
host string
}
// NewNode initializes a Node server involved in Chord protocol
func NewNode(config *Config) *Node {
node := &Node{
ID: generateID(config),
//successor: defaultSuccessor(config), // the successor is the node itself at the beginning
finger: make([]*FingerEntry, config.HashBits),
predecessor: nil,
fingerIndex: -1,
}
node.successor = defaultSuccessor(node.ID, config.Host)
return node
}
// NewRemoteNode initializes a remote Node server involved in Chord protocol
func NewRemoteNode(id []byte, host string) *RemoteNode {
return &RemoteNode{
ID: id,
host: host,
}
}
// generateId is helper function that uses configured hash function to generates Id for a Node server
func generateID(config *Config) []byte {
hash := config.HashFunc
hash.Write([]byte(config.Host))
b := hash.Sum(nil)
idInt := big.Int{}
idInt.SetBytes(b)
// Get the ceiling
two := big.NewInt(2)
ceil := big.Int{}
ceil.Exp(two, big.NewInt(int64(config.HashBits)), nil)
// Apply the mod
idInt.Mod(&idInt, &ceil)
// Add together
return idInt.Bytes()
}
/*
Getter
*/
// GetID returns the ID of the Node
func (n *Node) GetID() []byte {
return n.ID
}
// Successor returns the successor inside this local Node
func (n *Node) Successor() *RemoteNode {
n.Lock()
defer n.Unlock()
return n.successor
}
// Finger returns finger table inside the Node
func (n *Node) Finger() []*FingerEntry {
n.Lock()
defer n.Unlock()
return n.finger
}
// Predecessor returns the predecessor
func (n *Node) Predecessor() *RemoteNode {
n.Lock()
defer n.Unlock()
return n.predecessor
}
/*
Setter
*/
// SetID sets node's id
func (n *Node) SetID(id []byte) {
n.Lock()
defer n.Unlock()
n.ID = id
}
// SetSuccessor sets node's successor
func (n *Node) SetSuccessor(succ *RemoteNode) {
n.Lock()
defer n.Unlock()
n.successor = succ
}
// SetPredecessor sets node's predecessor
func (n *Node) SetPredecessor(pred *RemoteNode) {
n.Lock()
defer n.Unlock()
n.predecessor = pred
}
func defaultSuccessor(id []byte, host string) *RemoteNode {
return NewRemoteNode(id, host)
}
func defaultFingerEntry(id []byte, exp int, config *Config) *FingerEntry {
return &FingerEntry{
start: powerOffset(id, exp, config.HashBits),
node: id,
host: config.Host,
}
}
func defaultFingerTable(config *Config) []*FingerEntry {
hb := config.HashBits
id := generateID(config)
fingerTable := make([]*FingerEntry, hb)
for i := 0; i < hb; i++ {
fingerTable[i] = defaultFingerEntry(id, i, config)
}
return fingerTable
}