wantlist.go 1.93 KB
Newer Older
Jeromy's avatar
Jeromy committed
1 2 3 4 5
package wantlist

import (
	u "github.com/jbenet/go-ipfs/util"
	"sort"
6
	"sync"
Jeromy's avatar
Jeromy committed
7 8
)

9 10 11 12 13 14
type ThreadSafe struct {
	lk sync.RWMutex
	Wantlist
}

// not threadsafe
Jeromy's avatar
Jeromy committed
15 16 17 18
type Wantlist struct {
	set map[u.Key]*Entry
}

19
type Entry struct {
Brian Tiger Chow's avatar
Brian Tiger Chow committed
20 21
	// TODO consider making entries immutable so they can be shared safely and
	// slices can be copied efficiently.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
	Key      u.Key
	Priority int
}

type entrySlice []*Entry

func (es entrySlice) Len() int           { return len(es) }
func (es entrySlice) Swap(i, j int)      { es[i], es[j] = es[j], es[i] }
func (es entrySlice) Less(i, j int) bool { return es[i].Priority > es[j].Priority }

func NewThreadSafe() *ThreadSafe {
	return &ThreadSafe{
		Wantlist: *New(),
	}
}

38
func New() *Wantlist {
Jeromy's avatar
Jeromy committed
39 40 41 42 43
	return &Wantlist{
		set: make(map[u.Key]*Entry),
	}
}

44 45 46 47 48
func (w *ThreadSafe) Add(k u.Key, priority int) {
	// TODO rm defer for perf
	w.lk.Lock()
	defer w.lk.Unlock()
	w.Wantlist.Add(k, priority)
Jeromy's avatar
Jeromy committed
49 50
}

51 52
func (w *ThreadSafe) Remove(k u.Key) {
	// TODO rm defer for perf
53 54
	w.lk.Lock()
	defer w.lk.Unlock()
55 56 57 58 59 60 61 62 63 64 65 66 67
	w.Wantlist.Remove(k)
}

func (w *ThreadSafe) Contains(k u.Key) bool {
	// TODO rm defer for perf
	w.lk.RLock()
	defer w.lk.RUnlock()
	return w.Wantlist.Contains(k)
}

func (w *ThreadSafe) Entries() []*Entry {
	w.lk.RLock()
	defer w.lk.RUnlock()
68
	return w.Wantlist.Entries()
69 70 71 72 73
}

func (w *ThreadSafe) SortedEntries() []*Entry {
	w.lk.RLock()
	defer w.lk.RUnlock()
74
	return w.Wantlist.SortedEntries()
75 76 77
}

func (w *Wantlist) Add(k u.Key, priority int) {
Jeromy's avatar
Jeromy committed
78 79 80 81
	if _, ok := w.set[k]; ok {
		return
	}
	w.set[k] = &Entry{
82
		Key:      k,
Jeromy's avatar
Jeromy committed
83 84 85 86 87 88 89 90 91 92 93 94 95 96
		Priority: priority,
	}
}

func (w *Wantlist) Remove(k u.Key) {
	delete(w.set, k)
}

func (w *Wantlist) Contains(k u.Key) bool {
	_, ok := w.set[k]
	return ok
}

func (w *Wantlist) Entries() []*Entry {
Jeromy's avatar
Jeromy committed
97 98 99 100 101 102 103 104
	var es entrySlice
	for _, e := range w.set {
		es = append(es, e)
	}
	return es
}

func (w *Wantlist) SortedEntries() []*Entry {
Jeromy's avatar
Jeromy committed
105 106 107 108 109 110 111
	var es entrySlice
	for _, e := range w.set {
		es = append(es, e)
	}
	sort.Sort(es)
	return es
}