@cryptotaxi247 / kubo / commits / e92a33f44

routing/kbucket: cleaner "public" interface for bucket

Juan Batiz-Benet committed Feb 5, 2015 at 06:22 UTC e92a33f442a00a2d7d12afc6cdc637efcb8e08c2
3 files changed +51 -49
routing/kbucket/bucket.go
+14 -10
@@ -30,18 +30,18 @@ func (b *Bucket) Peers() []peer.ID {
30 return ps
31 }
32
33 -func (b *Bucket) find(id peer.ID) *list.Element {
33 +func (b *Bucket) Has(id peer.ID) bool {
34 b.lk.RLock()
35 defer b.lk.RUnlock()
36 for e := b.list.Front(); e != nil; e = e.Next() {
37 if e.Value.(peer.ID) == id {
38 - return e
38 + return true
39 }
40 }
41 - return nil
41 + return false
42 }
43
44 -func (b *Bucket) remove(id peer.ID) {
44 +func (b *Bucket) Remove(id peer.ID) {
45 b.lk.Lock()
46 defer b.lk.Unlock()
47 for e := b.list.Front(); e != nil; e = e.Next() {
@@ -51,19 +51,23 @@ func (b *Bucket) remove(id peer.ID) {
51 }
52 }
53
54 -func (b *Bucket) moveToFront(e *list.Element) {
54 +func (b *Bucket) MoveToFront(id peer.ID) {
55 b.lk.Lock()
56 - b.list.MoveToFront(e)
57 - b.lk.Unlock()
56 + defer b.lk.Unlock()
57 + for e := b.list.Front(); e != nil; e = e.Next() {
58 + if e.Value.(peer.ID) == id {
59 + b.list.MoveToFront(e)
60 + }
61 + }
62 }
63
60 -func (b *Bucket) pushFront(p peer.ID) {
64 +func (b *Bucket) PushFront(p peer.ID) {
65 b.lk.Lock()
66 b.list.PushFront(p)
67 b.lk.Unlock()
68 }
69
66 -func (b *Bucket) popBack() peer.ID {
70 +func (b *Bucket) PopBack() peer.ID {
71 b.lk.Lock()
72 defer b.lk.Unlock()
73 last := b.list.Back()
@@ -71,7 +75,7 @@ func (b *Bucket) popBack() peer.ID {
75 return last.Value.(peer.ID)
76 }
77
74 -func (b *Bucket) len() int {
78 +func (b *Bucket) Len() int {
79 b.lk.RLock()
80 defer b.lk.RUnlock()
81 return b.list.Len()
routing/kbucket/table.go
+34 -32
@@ -46,7 +46,7 @@ func NewRoutingTable(bucketsize int, localID ID, latency time.Duration, m peer.M
46
47 // Update adds or moves the given peer to the front of its respective bucket
48 // If a peer gets removed from a bucket, it is returned
49 -func (rt *RoutingTable) Update(p peer.ID) peer.ID {
49 +func (rt *RoutingTable) Update(p peer.ID) {
50 rt.tabLock.Lock()
51 defer rt.tabLock.Unlock()
52 peerID := ConvertPeerID(p)
@@ -58,33 +58,35 @@ func (rt *RoutingTable) Update(p peer.ID) peer.ID {
58 }
59
60 bucket := rt.Buckets[bucketID]
61 - e := bucket.find(p)
62 - if e == nil {
63 - // New peer, add to bucket
64 - if rt.metrics.LatencyEWMA(p) > rt.maxLatency {
65 - // Connection doesnt meet requirements, skip!
66 - return ""
67 - }
68 - bucket.pushFront(p)
69 -
70 - // Are we past the max bucket size?
71 - if bucket.len() > rt.bucketsize {
72 - // If this bucket is the rightmost bucket, and its full
73 - // we need to split it and create a new bucket
74 - if bucketID == len(rt.Buckets)-1 {
75 - return rt.nextBucket()
76 - } else {
77 - // If the bucket cant split kick out least active node
78 - return bucket.popBack()
79 - }
61 + if bucket.Has(p) {
62 + // If the peer is already in the table, move it to the front.
63 + // This signifies that it it "more active" and the less active nodes
64 + // Will as a result tend towards the back of the list
65 + bucket.MoveToFront(p)
66 + return
67 + }
68 +
69 + if rt.metrics.LatencyEWMA(p) > rt.maxLatency {
70 + // Connection doesnt meet requirements, skip!
71 + return
72 + }
73 +
74 + // New peer, add to bucket
75 + bucket.PushFront(p)
76 +
77 + // Are we past the max bucket size?
78 + if bucket.Len() > rt.bucketsize {
79 + // If this bucket is the rightmost bucket, and its full
80 + // we need to split it and create a new bucket
81 + if bucketID == len(rt.Buckets)-1 {
82 + rt.nextBucket()
83 + return
84 + } else {
85 + // If the bucket cant split kick out least active node
86 + bucket.PopBack()
87 + return
88 }
81 - return ""
89 }
83 - // If the peer is already in the table, move it to the front.
84 - // This signifies that it it "more active" and the less active nodes
85 - // Will as a result tend towards the back of the list
86 - bucket.moveToFront(e)
87 - return ""
90 }
91
92 // Remove deletes a peer from the routing table. This is to be used
@@ -101,20 +103,20 @@ func (rt *RoutingTable) Remove(p peer.ID) {
103 }
104
105 bucket := rt.Buckets[bucketID]
104 - bucket.remove(p)
106 + bucket.Remove(p)
107 }
108
109 func (rt *RoutingTable) nextBucket() peer.ID {
110 bucket := rt.Buckets[len(rt.Buckets)-1]
111 newBucket := bucket.Split(len(rt.Buckets)-1, rt.local)
112 rt.Buckets = append(rt.Buckets, newBucket)
111 - if newBucket.len() > rt.bucketsize {
113 + if newBucket.Len() > rt.bucketsize {
114 return rt.nextBucket()
115 }
116
117 // If all elements were on left side of split...
116 - if bucket.len() > rt.bucketsize {
117 - return bucket.popBack()
118 + if bucket.Len() > rt.bucketsize {
119 + return bucket.PopBack()
120 }
121 return ""
122 }
@@ -153,7 +155,7 @@ func (rt *RoutingTable) NearestPeers(id ID, count int) []peer.ID {
155 bucket = rt.Buckets[cpl]
156
157 var peerArr peerSorterArr
156 - if bucket.len() == 0 {
158 + if bucket.Len() == 0 {
159 // In the case of an unusual split, one bucket may be empty.
160 // if this happens, search both surrounding buckets for nearest peer
161 if cpl > 0 {
@@ -184,7 +186,7 @@ func (rt *RoutingTable) NearestPeers(id ID, count int) []peer.ID {
186 func (rt *RoutingTable) Size() int {
187 var tot int
188 for _, buck := range rt.Buckets {
187 - tot += buck.len()
189 + tot += buck.Len()
190 }
191 return tot
192 }
routing/kbucket/table_test.go
+3 -7
@@ -17,15 +17,14 @@ func TestBucket(t *testing.T) {
17 peers := make([]peer.ID, 100)
18 for i := 0; i < 100; i++ {
19 peers[i] = tu.RandPeerIDFatal(t)
20 - b.pushFront(peers[i])
20 + b.PushFront(peers[i])
21 }
22
23 local := tu.RandPeerIDFatal(t)
24 localID := ConvertPeerID(local)
25
26 i := rand.Intn(len(peers))
27 - e := b.find(peers[i])
28 - if e == nil {
27 + if !b.Has(peers[i]) {
28 t.Errorf("Failed to find peer: %v", peers[i])
29 }
30
@@ -62,10 +61,7 @@ func TestTableUpdate(t *testing.T) {
61
62 // Testing Update
63 for i := 0; i < 10000; i++ {
65 - p := rt.Update(peers[rand.Intn(len(peers))])
66 - if p != "" {
67 - //t.Log("evicted peer.")
68 - }
64 + rt.Update(peers[rand.Intn(len(peers))])
65 }
66
67 for i := 0; i < 100; i++ {