add closest-preceding-node operation

This commit is contained in:
Branden J Brown 2025-03-08 13:20:23 -05:00
parent aa46693f58
commit 7dd2de5055

View File

@ -32,6 +32,38 @@ func (n *Node) IsLocal(key string) bool {
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.
type Peer struct {
id ID
@ -56,7 +88,7 @@ func Create(addr netip.AddrPort) (*Node, error) {
n := &Node{
self: self,
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
}