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  }