add closest-preceding-node operation
This commit is contained in:
parent
aa46693f58
commit
7dd2de5055
@ -32,6 +32,38 @@ func (n *Node) IsLocal(key string) bool {
|
|||||||
return contains(n.self.id, n.Successor().id, id)
|
return contains(n.self.id, n.Successor().id, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Closest finds the locally known peer which is the closest predecessor of key.
|
||||||
|
func (n *Node) Closest(key string) Peer {
|
||||||
|
self := n.self.id
|
||||||
|
id := keyID(key)
|
||||||
|
l := n.fingers
|
||||||
|
for i := len(l) - 1; i >= 0; i-- {
|
||||||
|
f := l[i]
|
||||||
|
if contains(self, id, f.id) {
|
||||||
|
// contains reports true if id == f.id, which is
|
||||||
|
// technically incorrect for this operation.
|
||||||
|
// We could reasonably skip double-checking and rely on the hash,
|
||||||
|
// but we can also not skip it and just be correct.
|
||||||
|
if id == f.id {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Also try successors.
|
||||||
|
l = n.succ
|
||||||
|
for i := len(l) - 1; i >= 0; i-- {
|
||||||
|
f := l[i]
|
||||||
|
if contains(self, id, f.id) {
|
||||||
|
if id == f.id {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n.self
|
||||||
|
}
|
||||||
|
|
||||||
// Peer is the ID and address of a node.
|
// Peer is the ID and address of a node.
|
||||||
type Peer struct {
|
type Peer struct {
|
||||||
id ID
|
id ID
|
||||||
@ -56,7 +88,7 @@ func Create(addr netip.AddrPort) (*Node, error) {
|
|||||||
n := &Node{
|
n := &Node{
|
||||||
self: self,
|
self: self,
|
||||||
succ: []Peer{self}[:1:1], // extra cautious about capacity
|
succ: []Peer{self}[:1:1], // extra cautious about capacity
|
||||||
fingers: make([]Peer, len(ID{})*8),
|
fingers: make([]Peer, 0, len(ID{})*8),
|
||||||
}
|
}
|
||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user