-
Notifications
You must be signed in to change notification settings - Fork 1
/
routing.go
146 lines (132 loc) · 4.55 KB
/
routing.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
145
146
package chord
import (
"fmt"
"math/big"
)
/*------------------------------------------------------------*/
/* Routing Functions By: Alexwell */
/*------------------------------------------------------------*/
// Local use functionFindSuccessorRPC
func (node *Node) closePrecedingNode(requestID *big.Int) NodeAddress {
// fmt.Println("************ Invoke closePrecedingNode function ************")
fingerTableSize := len(node.FingerTable)
for i := fingerTableSize - 1; i >= 1; i-- {
var reply GetNameRPCReply
err := ChordCall(node.FingerTable[i].Address, "Node.GetNameRPC", "", &reply)
if err != nil {
fmt.Println("Error in closePrecedingNode function: ", err)
continue
}
fingerId := StrHash(reply.Name)
fingerId.Mod(fingerId, hashMod)
if between(node.Identifier, fingerId, requestID, false) {
return node.FingerTable[i].Address
}
}
return node.Successors[0]
}
// Local use function
// Lookup
func find(id *big.Int, startNode NodeAddress) NodeAddress {
fmt.Println("****************** Invoke find function *********************")
fmt.Println("The id to be found is: ", id.Mod(id, hashMod))
found := false
nextNode := startNode
i := 0
maxSteps := 10 // 2^maxSteps
for !found && i < maxSteps {
// found, nextNode = nextNode.FindSuccessor(id)
result := FindSuccessorRPCReply{}
err := ChordCall(nextNode, "Node.FindSuccessorRPC", id, &result)
if err != nil {
fmt.Println("Error in find function: ", err)
}
found = result.Found
// fmt.Println("The result of find is: ", result)
// found = result.found
nextNode = result.SuccessorAddress
i++
}
if found {
fmt.Println("Find Success in ", i, " steps.")
return nextNode
} else {
fmt.Println("Find Failed, please try again.")
return "-1"
}
}
/*------------------------------------------------------------*/
/* RPC functions Below */
/*------------------------------------------------------------*/
// -------------------------- FindSuccessorRPCReply ----------------------------------//
type FindSuccessorRPCReply struct {
Found bool
SuccessorAddress NodeAddress
}
// Local use function
func (node *Node) FindSuccessorRPC(requestID *big.Int, reply *FindSuccessorRPCReply) error {
// fmt.Println("*************** Invoke findSuccessor function ***************")
successorName := ""
var getNameRPCReply GetNameRPCReply
err := ChordCall(node.Successors[0], "Node.GetNameRPC", "", &getNameRPCReply)
if err != nil {
fmt.Println("Error in findSuccessorRPC: ", err)
reply.Found = false
reply.SuccessorAddress = "Error in findSuccessorRPC at " + node.Successors[0]
return nil
}
successorName = getNameRPCReply.Name
successorId := StrHash(successorName)
successorId.Mod(successorId, hashMod)
requestID.Mod(requestID, hashMod)
if between(node.Identifier, requestID, successorId, true) {
// if requestID.String() == "29" {
// fmt.Println("Between rangeis ", node.Identifier, requestID, successorId)
// fmt.Println("Successor is: ", node.Successors[0])
// }
reply.Found = true
reply.SuccessorAddress = node.Successors[0]
// return &res
} else {
successorAddr := node.closePrecedingNode(requestID)
// if requestID.String() == "15" {
// fmt.Println("Find closest preceding node at ", node.Address, " for ", requestID, " is ", successorAddr, "")
// }
// Get the successor of the close preceding node
var findSuccessorRPCReply FindSuccessorRPCReply
err := ChordCall(successorAddr, "Node.FindSuccessorRPC", requestID, &findSuccessorRPCReply)
if err != nil {
fmt.Println("Error in findSuccessorRPC: ", err)
reply.Found = false
reply.SuccessorAddress = "Error in findSuccessorRPC at " + successorAddr
} else {
reply.Found = true
reply.SuccessorAddress = findSuccessorRPCReply.SuccessorAddress
}
// return &res
}
return nil
}
/*
* @description: RPC method Packaging for findSuccessor, running on remote node
* @param: requestID: the client address or file name to be searched
* @return: found: whether the key is found
* successor: the successor of the key
*/
// -------------------------- GetNameRPC ----------------------------------//
type GetNameRPCReply struct {
Name string
}
// Get target node name/id
func (node *Node) getName() string {
return node.Name
}
/*
* @description: RPC method Packaging for getName, running on remote node
* @param: fakeRequest: not used
* @return: reply: the name of the node, use for hash(name) to get the node id
*/
func (node *Node) GetNameRPC(fakeRequest string, reply *GetNameRPCReply) error {
reply.Name = node.getName()
return nil
}