mirror of
https://github.com/bitmagnet-io/bitmagnet.git
synced 2026-07-24 13:11:05 -04:00
110 lines
2.2 KiB
Go
110 lines
2.2 KiB
Go
package ktable
|
|
|
|
import (
|
|
"net/netip"
|
|
"sort"
|
|
"time"
|
|
)
|
|
|
|
type Query[T any] interface {
|
|
execReturn(*table) T
|
|
}
|
|
|
|
var _ Query[[]Node] = GetClosestPeers{}
|
|
|
|
type GetClosestPeers struct {
|
|
ID ID
|
|
}
|
|
|
|
func (c GetClosestPeers) execReturn(t *table) []Node {
|
|
return t.nodes.getClosest(c.ID)
|
|
}
|
|
|
|
var _ Query[[]Node] = GetOldestPeers{}
|
|
|
|
type GetOldestPeers struct {
|
|
Cutoff time.Time
|
|
N int
|
|
}
|
|
|
|
func (c GetOldestPeers) execReturn(t *table) []Node {
|
|
peers := t.nodes.getLastRespondedBefore(c.Cutoff)
|
|
sort.Slice(peers, func(i, j int) bool {
|
|
return peers[i].Time().Before(peers[j].Time())
|
|
})
|
|
if c.N > 0 && len(peers) > c.N {
|
|
peers = peers[:c.N]
|
|
}
|
|
return peers
|
|
}
|
|
|
|
var _ Query[[]netip.Addr] = FilterKnownAddrs{}
|
|
|
|
type FilterKnownAddrs struct {
|
|
Addrs []netip.Addr
|
|
}
|
|
|
|
func (c FilterKnownAddrs) execReturn(t *table) []netip.Addr {
|
|
var unknown []netip.Addr
|
|
for _, addr := range c.Addrs {
|
|
if _, ok := t.addrs.addrs[addr.String()]; !ok {
|
|
unknown = append(unknown, addr)
|
|
}
|
|
}
|
|
return unknown
|
|
}
|
|
|
|
var _ Query[[]Node] = GetNodesForSampleInfoHashes{}
|
|
|
|
type GetNodesForSampleInfoHashes struct {
|
|
N int
|
|
}
|
|
|
|
func (c GetNodesForSampleInfoHashes) execReturn(t *table) []Node {
|
|
peers := make([]Node, 0, c.N)
|
|
for _, p := range t.nodes.getCandidatesForSampleInfoHashes(c.N) {
|
|
peers = append(peers, p)
|
|
if len(peers) >= c.N {
|
|
break
|
|
}
|
|
}
|
|
return peers
|
|
}
|
|
|
|
var _ Query[GetHashOrClosestNodesResult] = GetHashOrClosestNodes{}
|
|
|
|
type GetHashOrClosestNodes struct {
|
|
ID ID
|
|
}
|
|
|
|
func (c GetHashOrClosestNodes) execReturn(t *table) GetHashOrClosestNodesResult {
|
|
h, ok := t.hashes.get(c.ID)
|
|
if ok {
|
|
return GetHashOrClosestNodesResult{
|
|
Hash: h,
|
|
Found: true,
|
|
}
|
|
}
|
|
closestNodes := t.nodes.getClosest(c.ID)
|
|
return GetHashOrClosestNodesResult{
|
|
ClosestNodes: closestNodes,
|
|
}
|
|
}
|
|
|
|
var _ Query[SampleHashesAndNodesResult] = SampleHashesAndNodes{}
|
|
|
|
type SampleHashesAndNodes struct{}
|
|
|
|
func (c SampleHashesAndNodes) execReturn(t *table) SampleHashesAndNodesResult {
|
|
nHashes := 20
|
|
hashes := t.hashes.getRandom(nHashes)
|
|
nNodes := 20 + (nHashes - len(hashes))
|
|
nodes := t.nodes.getRandom(nNodes)
|
|
totalHashes := t.hashes.count()
|
|
return SampleHashesAndNodesResult{
|
|
Hashes: hashes,
|
|
Nodes: nodes,
|
|
TotalHashes: totalHashes,
|
|
}
|
|
}
|