kbucket use new keyspace
Juan Batiz-Benet committed
Sep 17, 2014 at 02:02 UTC
6c00938e7850fff98ac33ca064c79cf0549473f4
4 files changed
+13
-51
routing/kbucket/bucket.go
+1
-1
@@ -69,7 +69,7 @@ func (b *Bucket) Split(cpl int, target ID) *Bucket {
69
e := b.list.Front()
70
for e != nil {
71
peerID := ConvertPeerID(e.Value.(*peer.Peer).ID)
72
- peerCPL := prefLen(peerID, target)
72
+ peerCPL := commonPrefixLen(peerID, target)
73
if peerCPL > cpl {
74
cur := e
75
out.PushBack(e.Value)
routing/kbucket/table.go
+2
-2
@@ -44,7 +44,7 @@ func (rt *RoutingTable) Update(p *peer.Peer) *peer.Peer {
44
rt.tabLock.Lock()
45
defer rt.tabLock.Unlock()
46
peerID := ConvertPeerID(p.ID)
47
- cpl := xor(peerID, rt.local).commonPrefixLen()
47
+ cpl := commonPrefixLen(peerID, rt.local)
48
49
bucketID := cpl
50
if bucketID >= len(rt.Buckets) {
@@ -145,7 +145,7 @@ func (rt *RoutingTable) NearestPeer(id ID) *peer.Peer {
145
func (rt *RoutingTable) NearestPeers(id ID, count int) []*peer.Peer {
146
rt.tabLock.RLock()
147
defer rt.tabLock.RUnlock()
148
- cpl := prefLen(id, rt.local)
148
+ cpl := commonPrefixLen(id, rt.local)
149
150
// Get bucket at cpl index or last bucket
151
var bucket *Bucket
routing/kbucket/table_test.go
+2
-2
@@ -48,7 +48,7 @@ func TestBucket(t *testing.T) {
48
llist := b.list
49
for e := llist.Front(); e != nil; e = e.Next() {
50
p := ConvertPeerID(e.Value.(*peer.Peer).ID)
51
- cpl := xor(p, localID).commonPrefixLen()
51
+ cpl := commonPrefixLen(p, localID)
52
if cpl > 0 {
53
t.Fatalf("Split failed. found id with cpl > 0 in 0 bucket")
54
}
@@ -57,7 +57,7 @@ func TestBucket(t *testing.T) {
57
rlist := spl.list
58
for e := rlist.Front(); e != nil; e = e.Next() {
59
p := ConvertPeerID(e.Value.(*peer.Peer).ID)
60
- cpl := xor(p, localID).commonPrefixLen()
60
+ cpl := commonPrefixLen(p, localID)
61
if cpl == 0 {
62
t.Fatalf("Split failed. found id with cpl == 0 in non 0 bucket")
63
}
routing/kbucket/util.go
+8
-46
@@ -6,6 +6,7 @@ import (
6
"errors"
7
8
peer "github.com/jbenet/go-ipfs/peer"
9
+ ks "github.com/jbenet/go-ipfs/routing/keyspace"
10
u "github.com/jbenet/go-ipfs/util"
11
)
12
@@ -13,8 +14,7 @@ import (
14
// behaviour
15
var ErrLookupFailure = errors.New("failed to find any peer in table")
16
16
-// ID for IpfsDHT should be a byte slice, to allow for simpler operations
17
-// (xor). DHT ids are based on the peer.IDs.
17
+// ID for IpfsDHT is in the XORKeySpace
18
//
19
// The type dht.ID signifies that its contents have been hashed from either a
20
// peer.ID or a util.Key. This unifies the keyspace
@@ -25,55 +25,17 @@ func (id ID) equal(other ID) bool {
25
}
26
27
func (id ID) less(other ID) bool {
28
- a, b := equalizeSizes(id, other)
29
- for i := 0; i < len(a); i++ {
30
- if a[i] != b[i] {
31
- return a[i] < b[i]
32
- }
33
- }
34
- return len(a) < len(b)
35
-}
36
-
37
-func (id ID) commonPrefixLen() int {
38
- for i := 0; i < len(id); i++ {
39
- for j := 0; j < 8; j++ {
40
- if (id[i]>>uint8(7-j))&0x1 != 0 {
41
- return i*8 + j
42
- }
43
- }
44
- }
45
- return len(id)*8 - 1
46
-}
47
-
48
-func prefLen(a, b ID) int {
49
- return xor(a, b).commonPrefixLen()
28
+ a := ks.Key{Space: ks.XORKeySpace, Adjusted: id}
29
+ b := ks.Key{Space: ks.XORKeySpace, Adjusted: other}
30
+ return a.Less(b)
31
}
32
33
func xor(a, b ID) ID {
53
- a, b = equalizeSizes(a, b)
54
-
55
- c := make(ID, len(a))
56
- for i := 0; i < len(a); i++ {
57
- c[i] = a[i] ^ b[i]
58
- }
59
- return c
34
+ return ID(ks.XOR(a, b))
35
}
36
62
-func equalizeSizes(a, b ID) (ID, ID) {
63
- la := len(a)
64
- lb := len(b)
65
-
66
- if la < lb {
67
- na := make([]byte, lb)
68
- copy(na, a)
69
- a = na
70
- } else if lb < la {
71
- nb := make([]byte, la)
72
- copy(nb, b)
73
- b = nb
74
- }
75
-
76
- return a, b
37
+func commonPrefixLen(a, b ID) int {
38
+ return ks.ZeroPrefixLen(ks.XOR(a, b))
39
}
40
41
// ConvertPeerID creates a DHT ID by hashing a Peer ID (Multihash)