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
|
2022-05-29 12:40:18 +00:00
|
|
|
index uint64 // monotonusly increasing index to sort values with same priority
|
2021-10-20 14:02:55 +00:00
|
|
|
}
|
|
|
|
|
2022-05-29 12:40:18 +00:00
|
|
|
type priorityQueue struct {
|
|
|
|
nextIndex uint64
|
|
|
|
tasks []*priorityQueueTask
|
|
|
|
}
|
2021-10-20 14:02:55 +00:00
|
|
|
|
2022-05-29 12:40:18 +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 {
|
2022-05-29 12:40:18 +00:00
|
|
|
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) {
|
2022-05-29 12:40:18 +00:00
|
|
|
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)
|
2022-05-29 12:40:18 +00:00
|
|
|
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{} {
|
2022-05-29 12:40:18 +00:00
|
|
|
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
|
|
|
|
}
|