mirror of
https://github.com/PeernetOfficial/core.git
synced 2026-07-23 05:07:51 +01:00
DHT: Starting with the fork, initially only the hash table.
The distributed part follows.
This commit is contained in:
110
dht/Node.go
Normal file
110
dht/Node.go
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
File Name: Node.go
|
||||
Copyright: 2021 Peernet s.r.o.
|
||||
Author: Peter Kleissner
|
||||
*/
|
||||
|
||||
package dht
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math/big"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Node is the over-the-wire representation of a node
|
||||
type Node struct {
|
||||
// ID is the unique identifier
|
||||
ID []byte
|
||||
|
||||
// LastSeen when was this node last considered seen by the DHT
|
||||
LastSeen time.Time
|
||||
}
|
||||
|
||||
// nodeList is used in order to sort a list of arbitrary nodes against a
|
||||
// comparator. These nodes are sorted by xor distance
|
||||
type shortList struct {
|
||||
// Nodes are a list of nodes to be compared
|
||||
Nodes []Node
|
||||
|
||||
// Comparator is the ID to compare to
|
||||
Comparator []byte
|
||||
}
|
||||
|
||||
func areNodesEqual(n1 *Node, n2 *Node, allowNilID bool) bool {
|
||||
if n1 == nil || n2 == nil {
|
||||
return false
|
||||
}
|
||||
if !allowNilID {
|
||||
if n1.ID == nil || n2.ID == nil {
|
||||
return false
|
||||
}
|
||||
if bytes.Compare(n1.ID, n2.ID) != 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (n *shortList) RemoveNode(node Node) {
|
||||
for i := 0; i < n.Len(); i++ {
|
||||
if bytes.Compare(n.Nodes[i].ID, node.ID) == 0 {
|
||||
n.Nodes = append(n.Nodes[:i], n.Nodes[i+1:]...)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (n *shortList) AppendUniqueNodes(nodes ...Node) {
|
||||
for _, vv := range nodes {
|
||||
exists := false
|
||||
for _, v := range n.Nodes {
|
||||
if bytes.Compare(v.ID, vv.ID) == 0 {
|
||||
exists = true
|
||||
}
|
||||
}
|
||||
if !exists {
|
||||
n.Nodes = append(n.Nodes, vv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (n *shortList) AppendUnique(nodes ...Node) {
|
||||
for _, vv := range nodes {
|
||||
exists := false
|
||||
for _, v := range n.Nodes {
|
||||
if bytes.Compare(v.ID, vv.ID) == 0 {
|
||||
exists = true
|
||||
}
|
||||
}
|
||||
if !exists {
|
||||
n.Nodes = append(n.Nodes, vv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (n *shortList) Len() int {
|
||||
return len(n.Nodes)
|
||||
}
|
||||
|
||||
func (n *shortList) Swap(i, j int) {
|
||||
n.Nodes[i], n.Nodes[j] = n.Nodes[j], n.Nodes[i]
|
||||
}
|
||||
|
||||
func (n *shortList) Less(i, j int) bool {
|
||||
iDist := getDistance(n.Nodes[i].ID, n.Comparator)
|
||||
jDist := getDistance(n.Nodes[j].ID, n.Comparator)
|
||||
|
||||
if iDist.Cmp(jDist) == -1 {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func getDistance(id1 []byte, id2 []byte) *big.Int {
|
||||
buf1 := new(big.Int).SetBytes(id1)
|
||||
buf2 := new(big.Int).SetBytes(id2)
|
||||
result := new(big.Int).Xor(buf1, buf2)
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user