diff --git a/priorityqueue.go b/priorityqueue.go new file mode 100644 index 0000000..7d700a3 --- /dev/null +++ b/priorityqueue.go @@ -0,0 +1,77 @@ +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 { + return nil, false + } + + 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]{} +}