internal/utils/priority_queue.go (66 lines of code) (raw):
/*
* Copyright (c) 2023 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package utils
import (
"container/heap"
"sync"
)
type PriorityQueue struct {
items []ComparatorItem
mu sync.RWMutex
}
type ComparatorItem interface {
Priority() int64
Value() interface{}
}
func NewPriorityQueue(initialCapacity int) *PriorityQueue {
return &PriorityQueue{
items: make([]ComparatorItem, 0, initialCapacity),
}
}
func (pq *PriorityQueue) Len() int {
pq.mu.RLock()
defer pq.mu.RUnlock()
return len(pq.items)
}
func (pq *PriorityQueue) Less(i, j int) bool {
pq.mu.RLock()
defer pq.mu.RUnlock()
return pq.items[i].Priority() < pq.items[j].Priority()
}
func (pq *PriorityQueue) Swap(i, j int) {
pq.mu.Lock()
defer pq.mu.Unlock()
pq.items[i], pq.items[j] = pq.items[j], pq.items[i]
}
func (pq *PriorityQueue) Push(x interface{}) {
pq.mu.Lock()
defer pq.mu.Unlock()
item := x.(ComparatorItem)
pq.items = append(pq.items, item)
}
func (pq *PriorityQueue) Pop() interface{} {
pq.mu.Lock()
defer pq.mu.Unlock()
n := len(pq.items)
item := pq.items[n-1]
pq.items = pq.items[0 : n-1]
return item
}
func (pq *PriorityQueue) PushItem(item ComparatorItem) {
heap.Push(pq, item)
}
func (pq *PriorityQueue) PopItem() ComparatorItem {
return heap.Pop(pq).(ComparatorItem)
}
func (pq *PriorityQueue) Peek() ComparatorItem {
var ret ComparatorItem
if item := heap.Pop(pq); item != nil {
ret = item.(ComparatorItem)
heap.Push(pq, item)
}
return ret
}
func (pq *PriorityQueue) Clear() {
for pq.Len() > 0 {
pq.PopItem()
}
}