sessionwantlist.go 2.18 KB
Newer Older
dirkmc's avatar
dirkmc committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
package sessionwantlist

import (
	"sync"

	cid "github.com/ipfs/go-cid"
)

type SessionWantlist struct {
	sync.RWMutex
	wants map[cid.Cid]map[uint64]struct{}
}

func NewSessionWantlist() *SessionWantlist {
	return &SessionWantlist{
		wants: make(map[cid.Cid]map[uint64]struct{}),
	}
}

func (swl *SessionWantlist) Add(ks []cid.Cid, ses uint64) {
	swl.Lock()
	defer swl.Unlock()

	for _, c := range ks {
		if _, ok := swl.wants[c]; !ok {
			swl.wants[c] = make(map[uint64]struct{})
		}
		swl.wants[c][ses] = struct{}{}
	}
}

func (swl *SessionWantlist) RemoveKeys(ks []cid.Cid) {
	swl.Lock()
	defer swl.Unlock()

	for _, c := range ks {
		delete(swl.wants, c)
	}
}

func (swl *SessionWantlist) RemoveSession(ses uint64) []cid.Cid {
	swl.Lock()
	defer swl.Unlock()

	deletedKs := make([]cid.Cid, 0)
	for c := range swl.wants {
		delete(swl.wants[c], ses)
		if len(swl.wants[c]) == 0 {
			delete(swl.wants, c)
			deletedKs = append(deletedKs, c)
		}
	}

	return deletedKs
}

func (swl *SessionWantlist) RemoveSessionKeys(ses uint64, ks []cid.Cid) {
	swl.Lock()
	defer swl.Unlock()

	for _, c := range ks {
		if _, ok := swl.wants[c]; ok {
			delete(swl.wants[c], ses)
			if len(swl.wants[c]) == 0 {
				delete(swl.wants, c)
			}
		}
	}
}

func (swl *SessionWantlist) Keys() []cid.Cid {
	swl.RLock()
	defer swl.RUnlock()

	ks := make([]cid.Cid, 0, len(swl.wants))
	for c := range swl.wants {
		ks = append(ks, c)
	}
	return ks
}

func (swl *SessionWantlist) SessionsFor(ks []cid.Cid) []uint64 {
	swl.RLock()
	defer swl.RUnlock()

	sesMap := make(map[uint64]struct{})
	for _, c := range ks {
		for s := range swl.wants[c] {
			sesMap[s] = struct{}{}
		}
	}

	ses := make([]uint64, 0, len(sesMap))
	for s := range sesMap {
		ses = append(ses, s)
	}
	return ses
}

func (swl *SessionWantlist) Has(ks []cid.Cid) *cid.Set {
	swl.RLock()
	defer swl.RUnlock()

	has := cid.NewSet()
	for _, c := range ks {
		if _, ok := swl.wants[c]; ok {
			has.Add(c)
		}
	}
	return has
}

func (swl *SessionWantlist) SessionHas(ses uint64, ks []cid.Cid) *cid.Set {
	swl.RLock()
	defer swl.RUnlock()

	has := cid.NewSet()
	for _, c := range ks {
		if sesMap, cok := swl.wants[c]; cok {
			if _, sok := sesMap[ses]; sok {
				has.Add(c)
			}
		}
	}
	return has
}