github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/exchange/bitswap/wantlist/wantlist.go (about) 1 // package wantlist implements an object for bitswap that contains the keys 2 // that a given peer wants. 3 package wantlist 4 5 import ( 6 key "github.com/ipfs/go-ipfs/blocks/key" 7 "sort" 8 "sync" 9 ) 10 11 type ThreadSafe struct { 12 lk sync.RWMutex 13 Wantlist Wantlist 14 } 15 16 // not threadsafe 17 type Wantlist struct { 18 set map[key.Key]Entry 19 // TODO provide O(1) len accessor if cost becomes an issue 20 } 21 22 type Entry struct { 23 // TODO consider making entries immutable so they can be shared safely and 24 // slices can be copied efficiently. 25 Key key.Key 26 Priority int 27 } 28 29 type entrySlice []Entry 30 31 func (es entrySlice) Len() int { return len(es) } 32 func (es entrySlice) Swap(i, j int) { es[i], es[j] = es[j], es[i] } 33 func (es entrySlice) Less(i, j int) bool { return es[i].Priority > es[j].Priority } 34 35 func NewThreadSafe() *ThreadSafe { 36 return &ThreadSafe{ 37 Wantlist: *New(), 38 } 39 } 40 41 func New() *Wantlist { 42 return &Wantlist{ 43 set: make(map[key.Key]Entry), 44 } 45 } 46 47 func (w *ThreadSafe) Add(k key.Key, priority int) { 48 // TODO rm defer for perf 49 w.lk.Lock() 50 defer w.lk.Unlock() 51 w.Wantlist.Add(k, priority) 52 } 53 54 func (w *ThreadSafe) Remove(k key.Key) { 55 // TODO rm defer for perf 56 w.lk.Lock() 57 defer w.lk.Unlock() 58 w.Wantlist.Remove(k) 59 } 60 61 func (w *ThreadSafe) Contains(k key.Key) (Entry, bool) { 62 // TODO rm defer for perf 63 w.lk.RLock() 64 defer w.lk.RUnlock() 65 return w.Wantlist.Contains(k) 66 } 67 68 func (w *ThreadSafe) Entries() []Entry { 69 w.lk.RLock() 70 defer w.lk.RUnlock() 71 return w.Wantlist.Entries() 72 } 73 74 func (w *ThreadSafe) SortedEntries() []Entry { 75 w.lk.RLock() 76 defer w.lk.RUnlock() 77 return w.Wantlist.SortedEntries() 78 } 79 80 func (w *ThreadSafe) Len() int { 81 w.lk.RLock() 82 defer w.lk.RUnlock() 83 return w.Wantlist.Len() 84 } 85 86 func (w *Wantlist) Len() int { 87 return len(w.set) 88 } 89 90 func (w *Wantlist) Add(k key.Key, priority int) { 91 if _, ok := w.set[k]; ok { 92 return 93 } 94 w.set[k] = Entry{ 95 Key: k, 96 Priority: priority, 97 } 98 } 99 100 func (w *Wantlist) Remove(k key.Key) { 101 delete(w.set, k) 102 } 103 104 func (w *Wantlist) Contains(k key.Key) (Entry, bool) { 105 e, ok := w.set[k] 106 return e, ok 107 } 108 109 func (w *Wantlist) Entries() []Entry { 110 var es entrySlice 111 for _, e := range w.set { 112 es = append(es, e) 113 } 114 return es 115 } 116 117 func (w *Wantlist) SortedEntries() []Entry { 118 var es entrySlice 119 for _, e := range w.set { 120 es = append(es, e) 121 } 122 sort.Sort(es) 123 return es 124 }