chord/chord/id.go
2025-03-11 08:51:46 -04:00

62 lines
1.3 KiB
Go

package chord
import (
"bytes"
"crypto/sha1"
"encoding/hex"
"errors"
"net/netip"
)
type ID [20]byte
func addrID(addr netip.AddrPort) ID {
if !addr.IsValid() {
return ID{}
}
b := make([]byte, 0, len("[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%enp5s0]:65535"))
b = addr.AppendTo(b)
return keyID(b)
}
func keyID[T string | []byte](key T) ID {
s := sha1.Sum([]byte(key))
return s
}
// contains reports whether a clockwise traversal through the hash space
// starting immediately after left reaches x no later than it reaches right.
func contains(left, right, x ID) bool {
lr := bytes.Compare(left[:], right[:])
lx := bytes.Compare(left[:], x[:])
xr := bytes.Compare(x[:], right[:])
switch {
case lr < 0:
// left is less than right, so the interval does not cross the origin.
// | L-----R |
return (lx < 0) == (xr <= 0)
case lr > 0:
// The interval crosses the origin.
// |-----R L-----|
return (lx < 0) != (xr <= 0)
default:
// The interval is the entire hash space.
return true
}
}
func (id ID) String() string {
b := make([]byte, 0, len(ID{})*2)
b = hex.AppendEncode(b, id[:])
return string(b)
}
func ParseID(s string) (ID, error) {
if len(s) != len(ID{})*2 {
return ID{}, errors.New("invalid ID")
}
var id ID
_, err := hex.AppendDecode(id[:], []byte(s))
return id, err
}