2022-09-10 21:01:40 -04:00
|
|
|
package containers
|
|
|
|
|
|
|
|
import "sync"
|
|
|
|
|
|
|
|
type element[T any] struct {
|
|
|
|
priority int
|
|
|
|
value T
|
|
|
|
}
|
|
|
|
|
|
|
|
type PriorityQueue[T any] struct {
|
|
|
|
lock sync.RWMutex
|
|
|
|
items []*element[T]
|
|
|
|
}
|
|
|
|
|
|
|
|
func (q *PriorityQueue[T]) Add(priority int, value T) {
|
|
|
|
q.lock.Lock()
|
|
|
|
defer q.lock.Unlock()
|
|
|
|
|
|
|
|
item := &element[T]{
|
|
|
|
priority: priority,
|
|
|
|
value: value,
|
|
|
|
}
|
|
|
|
|
|
|
|
inserted := false
|
|
|
|
for k, v := range q.items {
|
|
|
|
if item.priority > v.priority {
|
|
|
|
q.items = append(q.items[:k], append([]*element[T]{item}, q.items[k+1:]...)...)
|
|
|
|
inserted = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !inserted {
|
|
|
|
q.items = append(q.items, item)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func (q *PriorityQueue[T]) Pop() (T, bool) {
|
|
|
|
q.lock.Lock()
|
|
|
|
defer q.lock.Unlock()
|
|
|
|
|
|
|
|
if len(q.items) == 0 {
|
2022-09-10 21:43:31 -04:00
|
|
|
var res T
|
|
|
|
return res, false
|
2022-09-10 21:01:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
item := q.items[0]
|
|
|
|
q.items = q.items[1:]
|
|
|
|
|
|
|
|
return item.value, true
|
|
|
|
}
|
|
|
|
|
|
|
|
func (q *PriorityQueue[T]) Len() int {
|
|
|
|
q.lock.RLock()
|
|
|
|
defer q.lock.RUnlock()
|
|
|
|
|
|
|
|
return len(q.items)
|
|
|
|
}
|
|
|
|
|
2022-09-23 22:03:13 -04:00
|
|
|
// offset should be between 0 and Len() - 1
|
|
|
|
func (q *PriorityQueue[T]) Peek(offset int) (T, bool) {
|
2022-09-10 21:01:40 -04:00
|
|
|
q.lock.RLock()
|
|
|
|
defer q.lock.RUnlock()
|
|
|
|
|
2022-09-23 22:03:13 -04:00
|
|
|
if offset < 0 || offset >= len(q.items) {
|
|
|
|
var t T
|
|
|
|
return t, false
|
2022-09-10 21:01:40 -04:00
|
|
|
}
|
|
|
|
|
2022-09-23 22:03:13 -04:00
|
|
|
return q.items[offset].value, true
|
2022-09-10 21:01:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func (q *PriorityQueue[T]) Clear() {
|
|
|
|
q.lock.Lock()
|
|
|
|
defer q.lock.Unlock()
|
|
|
|
|
|
|
|
q.items = []*element[T]{}
|
|
|
|
}
|
2022-10-15 10:25:40 -04:00
|
|
|
|
|
|
|
func (q *PriorityQueue[T]) ForEach(fn func(*T)) {
|
|
|
|
q.lock.RLock()
|
|
|
|
defer q.lock.RUnlock()
|
|
|
|
|
|
|
|
for _, v := range q.items {
|
|
|
|
fn(&v.value)
|
|
|
|
}
|
|
|
|
}
|