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  }