priopool/queue.go

45 lines
1.1 KiB
Go
Raw Permalink Normal View History

2021-10-23 15:16:40 +00:00
package priopool
2021-10-20 14:02:55 +00:00
2021-10-23 15:16:40 +00:00
// Priority pool based on implementation example from heap package.
// Priority queue itself is not thread safe.
// See https://cs.opensource.google/go/go/+/refs/tags/go1.17.2:src/container/heap/example_pq_test.go
2021-10-20 14:02:55 +00:00
2021-10-23 15:16:40 +00:00
type priorityQueueTask struct {
value func()
priority int
index uint64 // monotonusly increasing index to sort values with same priority
2021-10-20 14:02:55 +00:00
}
type priorityQueue struct {
nextIndex uint64
tasks []*priorityQueueTask
}
2021-10-20 14:02:55 +00:00
func (pq priorityQueue) Len() int { return len(pq.tasks) }
2021-10-20 14:02:55 +00:00
2021-10-23 15:16:40 +00:00
func (pq priorityQueue) Less(i, j int) bool {
if pq.tasks[i].priority == pq.tasks[j].priority {
return pq.tasks[i].index < pq.tasks[j].index
}
return pq.tasks[i].priority > pq.tasks[j].priority
2021-10-20 14:02:55 +00:00
}
2021-10-23 15:16:40 +00:00
func (pq priorityQueue) Swap(i, j int) {
pq.tasks[i], pq.tasks[j] = pq.tasks[j], pq.tasks[i]
2021-10-20 14:02:55 +00:00
}
2021-10-23 15:16:40 +00:00
func (pq *priorityQueue) Push(x interface{}) {
item := x.(*priorityQueueTask)
item.index = pq.nextIndex
pq.nextIndex++
pq.tasks = append(pq.tasks, item)
2021-10-20 14:02:55 +00:00
}
2021-10-23 15:16:40 +00:00
func (pq *priorityQueue) Pop() interface{} {
n := len(pq.tasks)
item := pq.tasks[n-1]
pq.tasks[n-1] = nil
pq.tasks = pq.tasks[0 : n-1]
2021-10-20 14:02:55 +00:00
return item
}