b5447c6608
This PR includes a new package called testrouting, which implements a very algorithmically slow but hopefully easy-to-keep-operationally-correct in-memory routing table. The routing table also supports writing out its current structure as a DOT graph for visualization. testrouting is primarily meant to help in coming up with generic routing table integration tests. This PR also includes a new routing table integration test suite that runs against all current routing table implementations. Our existing routing table passes a lot of the tests, but not all of them, still debugging why. I have confirmed the tests should pass with the visualization graphs though.
66 lines
1.3 KiB
Go
66 lines
1.3 KiB
Go
// Copyright (C) 2019 Storj Labs, Inc.
|
|
// See LICENSE for copying information.
|
|
|
|
package testrouting
|
|
|
|
import (
|
|
"storj.io/storj/pkg/storj"
|
|
)
|
|
|
|
type nodeDataDistanceSorter struct {
|
|
self storj.NodeID
|
|
nodes []*nodeData
|
|
}
|
|
|
|
func (s nodeDataDistanceSorter) Len() int { return len(s.nodes) }
|
|
|
|
func (s nodeDataDistanceSorter) Swap(i, j int) {
|
|
s.nodes[i], s.nodes[j] = s.nodes[j], s.nodes[i]
|
|
}
|
|
|
|
func (s nodeDataDistanceSorter) Less(i, j int) bool {
|
|
return compareByXor(s.nodes[i].node.Id, s.nodes[j].node.Id, s.self) < 0
|
|
}
|
|
|
|
func compareByXor(left, right, reference storj.NodeID) int {
|
|
for i, r := range reference {
|
|
a, b := left[i]^r, right[i]^r
|
|
if a != b {
|
|
if a < b {
|
|
return -1
|
|
}
|
|
return 1
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func bitAtDepth(id storj.NodeID, bitDepth int) bool {
|
|
// we could make this a fun one-liner but this is more understandable
|
|
byteDepth := bitDepth / 8
|
|
bitOffset := bitDepth % 8
|
|
power := uint(7 - bitOffset)
|
|
bitMask := byte(1 << power)
|
|
b := id[byteDepth]
|
|
if b&bitMask > 0 {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func extendPrefix(prefix string, bit bool) string {
|
|
if bit {
|
|
return prefix + "1"
|
|
}
|
|
return prefix + "0"
|
|
}
|
|
|
|
func isNearest(id storj.NodeID, nearest []*nodeData) bool {
|
|
for _, near := range nearest {
|
|
if near.node.Id == id {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|