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 {