@cryptotaxi247 / kubo / commits / bef622222

refactor: wantlist splits into WL and ThreadSafe WL

bitswap keeps the threadsafe version. observing the ledger shows that it doesn't need it anymore (ledgermanager is protected and safe). License: MIT Signed-off-by: Brian Tiger Chow <brian@perfmode.com>

Brian Tiger Chow committed Dec 16, 2014 at 22:46 UTC bef622222da715561fb3ac963719a08ca2caf696
2 files changed +70 -24
exchange/bitswap/bitswap.go
+4 -4
@@ -15,7 +15,7 @@ import (
15 bsnet "github.com/jbenet/go-ipfs/exchange/bitswap/network"
16 notifications "github.com/jbenet/go-ipfs/exchange/bitswap/notifications"
17 strategy "github.com/jbenet/go-ipfs/exchange/bitswap/strategy"
18 - wl "github.com/jbenet/go-ipfs/exchange/bitswap/wantlist"
18 + wantlist "github.com/jbenet/go-ipfs/exchange/bitswap/wantlist"
19 peer "github.com/jbenet/go-ipfs/peer"
20 u "github.com/jbenet/go-ipfs/util"
21 eventlog "github.com/jbenet/go-ipfs/util/eventlog"
@@ -59,7 +59,7 @@ func New(parent context.Context, p peer.Peer, network bsnet.BitSwapNetwork, rout
59 ledgermanager: strategy.NewLedgerManager(ctx, bstore),
60 routing: routing,
61 sender: network,
62 - wantlist: wl.New(),
62 + wantlist: wantlist.NewThreadSafe(),
63 batchRequests: make(chan []u.Key, 32),
64 }
65 network.SetDelegate(bs)
@@ -95,7 +95,7 @@ type bitswap struct {
95
96 ledgermanager *strategy.LedgerManager
97
98 - wantlist *wl.Wantlist
98 + wantlist *wantlist.ThreadSafe
99
100 // cancelFunc signals cancellation to the bitswap event loop
101 cancelFunc func()
@@ -203,7 +203,7 @@ func (bs *bitswap) sendWantListTo(ctx context.Context, peers <-chan peer.Peer) e
203 return nil
204 }
205
206 -func (bs *bitswap) sendWantlistToProviders(ctx context.Context, wantlist *wl.Wantlist) {
206 +func (bs *bitswap) sendWantlistToProviders(ctx context.Context, wantlist *wantlist.ThreadSafe) {
207 ctx, cancel := context.WithCancel(ctx)
208 defer cancel()
209
exchange/bitswap/wantlist/wantlist.go
+66 -20
@@ -6,25 +6,86 @@ import (
6 "sync"
7 )
8
9 +type ThreadSafe struct {
10 + lk sync.RWMutex
11 + Wantlist
12 +}
13 +
14 +// not threadsafe
15 type Wantlist struct {
10 - lk sync.RWMutex
16 set map[u.Key]*Entry
17 }
18
19 +type Entry struct {
20 + Key u.Key
21 + Priority int
22 +}
23 +
24 +type entrySlice []*Entry
25 +
26 +func (es entrySlice) Len() int { return len(es) }
27 +func (es entrySlice) Swap(i, j int) { es[i], es[j] = es[j], es[i] }
28 +func (es entrySlice) Less(i, j int) bool { return es[i].Priority > es[j].Priority }
29 +
30 +func NewThreadSafe() *ThreadSafe {
31 + return &ThreadSafe{
32 + Wantlist: *New(),
33 + }
34 +}
35 +
36 func New() *Wantlist {
37 return &Wantlist{
38 set: make(map[u.Key]*Entry),
39 }
40 }
41
20 -type Entry struct {
21 - Key u.Key
22 - Priority int
42 +func (w *ThreadSafe) Add(k u.Key, priority int) {
43 + // TODO rm defer for perf
44 + w.lk.Lock()
45 + defer w.lk.Unlock()
46 + w.Wantlist.Add(k, priority)
47 }
48
25 -func (w *Wantlist) Add(k u.Key, priority int) {
49 +func (w *ThreadSafe) Remove(k u.Key) {
50 + // TODO rm defer for perf
51 w.lk.Lock()
52 defer w.lk.Unlock()
53 + w.Wantlist.Remove(k)
54 +}
55 +
56 +func (w *ThreadSafe) Contains(k u.Key) bool {
57 + // TODO rm defer for perf
58 + w.lk.RLock()
59 + defer w.lk.RUnlock()
60 + return w.Wantlist.Contains(k)
61 +}
62 +
63 +func (w *ThreadSafe) Entries() []*Entry {
64 + w.lk.RLock()
65 + defer w.lk.RUnlock()
66 + var es entrySlice
67 + for _, e := range w.set {
68 + es = append(es, e)
69 + }
70 + // TODO rename SortedEntries (state that they're sorted so callers know
71 + // they're paying an expense)
72 + sort.Sort(es)
73 + return es
74 +}
75 +
76 +func (w *ThreadSafe) SortedEntries() []*Entry {
77 + w.lk.RLock()
78 + defer w.lk.RUnlock()
79 + var es entrySlice
80 +
81 + for _, e := range w.set {
82 + es = append(es, e)
83 + }
84 + sort.Sort(es)
85 + return es
86 +}
87 +
88 +func (w *Wantlist) Add(k u.Key, priority int) {
89 if _, ok := w.set[k]; ok {
90 return
91 }
@@ -35,28 +96,15 @@ func (w *Wantlist) Add(k u.Key, priority int) {
96 }
97
98 func (w *Wantlist) Remove(k u.Key) {
38 - w.lk.Lock()
39 - defer w.lk.Unlock()
99 delete(w.set, k)
100 }
101
102 func (w *Wantlist) Contains(k u.Key) bool {
44 - w.lk.RLock()
45 - defer w.lk.RUnlock()
103 _, ok := w.set[k]
104 return ok
105 }
106
50 -type entrySlice []*Entry
51 -
52 -func (es entrySlice) Len() int { return len(es) }
53 -func (es entrySlice) Swap(i, j int) { es[i], es[j] = es[j], es[i] }
54 -func (es entrySlice) Less(i, j int) bool { return es[i].Priority > es[j].Priority }
55 -
107 func (w *Wantlist) Entries() []*Entry {
57 - w.lk.RLock()
58 - defer w.lk.RUnlock()
59 -
108 var es entrySlice
109
110 for _, e := range w.set {
@@ -67,8 +115,6 @@ func (w *Wantlist) Entries() []*Entry {
115 }
116
117 func (w *Wantlist) SortedEntries() []*Entry {
70 - w.lk.RLock()
71 - defer w.lk.RUnlock()
118 var es entrySlice
119
120 for _, e := range w.set {