storj/pkg/kademlia/utils.go

104 lines
2.1 KiB
Go
Raw Normal View History

2019-01-02 18:57:11 +00:00
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
package kademlia
import (
"math/bits"
"sort"
"github.com/zeebo/errs"
"storj.io/storj/pkg/storj"
"storj.io/storj/storage"
)
func cloneNodeIDs(ids storj.NodeIDList) storj.NodeIDList {
clone := make(storj.NodeIDList, len(ids))
copy(clone, ids)
return clone
}
// compareByXor compares left, right xorred by reference
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 sortByXOR(nodeIDs storj.NodeIDList, ref storj.NodeID) {
sort.Slice(nodeIDs, func(i, k int) bool {
return compareByXor(nodeIDs[i], nodeIDs[k], ref) < 0
})
}
func keysToNodeIDs(keys storage.Keys) (ids storj.NodeIDList, err error) {
var idErrs []error
for _, k := range keys {
id, err := storj.NodeIDFromBytes(k[:])
if err != nil {
idErrs = append(idErrs, err)
}
ids = append(ids, id)
}
if err := errs.Combine(idErrs...); err != nil {
return nil, err
}
return ids, nil
}
func keyToBucketID(key storage.Key) (bID bucketID) {
copy(bID[:], key)
return bID
}
// xorNodeID returns the xor of each byte in NodeID
func xorNodeID(a, b storj.NodeID) storj.NodeID {
r := storj.NodeID{}
for i, av := range a {
r[i] = av ^ b[i]
}
return r
}
// xorBucketID returns the xor of each byte in bucketID
func xorBucketID(a, b bucketID) bucketID {
r := bucketID{}
for i, av := range a {
r[i] = av ^ b[i]
}
return r
}
// determineDifferingBitIndex: helper, returns the last bit differs starting from prefix to suffix
func determineDifferingBitIndex(bID, comparisonID bucketID) (int, error) {
if bID == comparisonID {
return -2, RoutingErr.New("compared two equivalent k bucket ids")
}
if comparisonID == emptyBucketID {
comparisonID = firstBucketID
}
xorID := xorBucketID(bID, comparisonID)
if xorID == firstBucketID {
return -1, nil
}
for i, v := range xorID {
if v != 0 {
return i*8 + 7 - bits.TrailingZeros8(v), nil
}
}
return -1, nil
}