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)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (q *PriorityQueue[T]) Peek() (T, bool) {
|
|
|
|
q.lock.RLock()
|
|
|
|
defer q.lock.RUnlock()
|
|
|
|
|
|
|
|
if len(q.items) == 0 {
|
|
|
|
var def T
|
|
|
|
return def, false
|
|
|
|
}
|
|
|
|
|
|
|
|
return q.items[0].value, true
|
|
|
|
}
|
|
|
|
|
|
|
|
func (q *PriorityQueue[T]) Clear() {
|
|
|
|
q.lock.Lock()
|
|
|
|
defer q.lock.Unlock()
|
|
|
|
|
|
|
|
q.items = []*element[T]{}
|
|
|
|
}
|