github.com/haraldrudell/parl@v0.4.176/pqs/priority-queue-thread-safe.go (about) 1 /* 2 © 2022–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/) 3 ISC License 4 */ 5 6 // RankingThreadSafe is a thread-safe pointer-identity-to-value map of updatable values traversable by rank. 7 // RankingThreadSafe implements [parl.Ranking][V comparable, R constraints.Ordered]. 8 package pqs 9 10 import ( 11 "sync" 12 13 "github.com/haraldrudell/parl" 14 "golang.org/x/exp/constraints" 15 ) 16 17 // PriorityQueueThreadSafe is a thread-safe pointer-identity-to-value map of updatable values traversable by rank. 18 // PriorityQueueThreadSafe implements [parl.Ranking][V comparable, R constraints.Ordered]. 19 // - V is a value reference composite type that is comparable, ie. not slice map function. 20 // Preferrably, V is interface or pointer to struct type. 21 // - P is an ordered type such as int floating-point string, used to rank the V values 22 // - values are added or updated using AddOrUpdate method distinguished by 23 // (computer science) identity 24 // - if the same comparable value V is added again, that value is re-ranked 25 // - rank R is computed from a value V using the ranker function. 26 // The ranker function may be examining field values of a struct 27 // - values can have the same rank. If they do, equal rank is provided in insertion order 28 type PriorityQueueThreadSafe[V any, P constraints.Ordered] struct { 29 lock sync.RWMutex 30 parl.PriorityQueue[V, P] 31 } 32 33 // NewRanking returns a thread-safe map of updatable values traversable by rank 34 func NewPriorityQueueThreadSafe[V any, P constraints.Ordered]( 35 ranker func(value *V) (rank P), 36 ) (o1 parl.PriorityQueue[V, P]) { 37 return &PriorityQueueThreadSafe[V, P]{ 38 PriorityQueue: NewPriorityQueue(ranker), 39 } 40 } 41 42 // AddOrUpdate adds a new value to the ranking or updates the ranking of a value 43 // that has changed. 44 func (mp *PriorityQueueThreadSafe[V, P]) AddOrUpdate(value *V) { 45 mp.lock.Lock() 46 defer mp.lock.Unlock() 47 48 mp.PriorityQueue.AddOrUpdate(value) 49 } 50 51 // List returns the first n or default all values by rank 52 func (mp *PriorityQueueThreadSafe[V, P]) List(n ...int) (list []*V) { 53 mp.lock.RLock() 54 defer mp.lock.RUnlock() 55 56 return mp.PriorityQueue.List(n...) 57 }