pqueue.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. package pqueue
  2. import (
  3. "container/heap"
  4. )
  5. type Item struct {
  6. Value interface{}
  7. Priority int64
  8. Index int
  9. }
  10. // this is a priority queue as implemented by a min heap
  11. // ie. the 0th element is the *lowest* value
  12. type PriorityQueue []*Item
  13. func New(capacity int) PriorityQueue {
  14. return make(PriorityQueue, 0, capacity)
  15. }
  16. func (pq PriorityQueue) Len() int {
  17. return len(pq)
  18. }
  19. func (pq PriorityQueue) Less(i, j int) bool {
  20. return pq[i].Priority < pq[j].Priority
  21. }
  22. func (pq PriorityQueue) Swap(i, j int) {
  23. pq[i], pq[j] = pq[j], pq[i]
  24. pq[i].Index = i
  25. pq[j].Index = j
  26. }
  27. func (pq *PriorityQueue) Push(x interface{}) {
  28. n := len(*pq)
  29. c := cap(*pq)
  30. if n+1 > c {
  31. npq := make(PriorityQueue, n, c*2)
  32. copy(npq, *pq)
  33. *pq = npq
  34. }
  35. *pq = (*pq)[0 : n+1]
  36. item := x.(*Item)
  37. item.Index = n
  38. (*pq)[n] = item
  39. }
  40. func (pq *PriorityQueue) Pop() interface{} {
  41. n := len(*pq)
  42. c := cap(*pq)
  43. if n < (c/2) && c > 25 {
  44. npq := make(PriorityQueue, n, c/2)
  45. copy(npq, *pq)
  46. *pq = npq
  47. }
  48. item := (*pq)[n-1]
  49. item.Index = -1
  50. *pq = (*pq)[0 : n-1]
  51. return item
  52. }
  53. func (pq *PriorityQueue) PeekAndShift(max int64) (*Item, int64) {
  54. if pq.Len() == 0 {
  55. return nil, 0
  56. }
  57. item := (*pq)[0]
  58. if item.Priority > max {
  59. return nil, item.Priority - max
  60. }
  61. heap.Remove(pq, 0)
  62. return item, 0
  63. }