You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

103 lines
1.9 KiB

9 years ago
  1. package common
  2. import (
  3. "container/heap"
  4. )
  5. type Comparable interface {
  6. Less(o interface{}) bool
  7. }
  8. //-----------------------------------------------------------------------------
  9. /*
  10. Example usage:
  11. h := NewHeap()
  12. h.Push(String("msg1"), 1)
  13. h.Push(String("msg3"), 3)
  14. h.Push(String("msg2"), 2)
  15. fmt.Println(h.Pop())
  16. fmt.Println(h.Pop())
  17. fmt.Println(h.Pop())
  18. */
  19. type Heap struct {
  20. pq priorityQueue
  21. }
  22. func NewHeap() *Heap {
  23. return &Heap{pq: make([]*pqItem, 0)}
  24. }
  25. func (h *Heap) Len() int64 {
  26. return int64(len(h.pq))
  27. }
  28. func (h *Heap) Push(value interface{}, priority Comparable) {
  29. heap.Push(&h.pq, &pqItem{value: value, priority: priority})
  30. }
  31. func (h *Heap) Peek() interface{} {
  32. if len(h.pq) == 0 {
  33. return nil
  34. }
  35. return h.pq[0].value
  36. }
  37. func (h *Heap) Update(value interface{}, priority Comparable) {
  38. h.pq.Update(h.pq[0], value, priority)
  39. }
  40. func (h *Heap) Pop() interface{} {
  41. item := heap.Pop(&h.pq).(*pqItem)
  42. return item.value
  43. }
  44. //-----------------------------------------------------------------------------
  45. ///////////////////////
  46. // From: http://golang.org/pkg/container/heap/#example__priorityQueue
  47. type pqItem struct {
  48. value interface{}
  49. priority Comparable
  50. index int
  51. }
  52. type priorityQueue []*pqItem
  53. func (pq priorityQueue) Len() int { return len(pq) }
  54. func (pq priorityQueue) Less(i, j int) bool {
  55. return pq[i].priority.Less(pq[j].priority)
  56. }
  57. func (pq priorityQueue) Swap(i, j int) {
  58. pq[i], pq[j] = pq[j], pq[i]
  59. pq[i].index = i
  60. pq[j].index = j
  61. }
  62. func (pq *priorityQueue) Push(x interface{}) {
  63. n := len(*pq)
  64. item := x.(*pqItem)
  65. item.index = n
  66. *pq = append(*pq, item)
  67. }
  68. func (pq *priorityQueue) Pop() interface{} {
  69. old := *pq
  70. n := len(old)
  71. item := old[n-1]
  72. item.index = -1 // for safety
  73. *pq = old[0 : n-1]
  74. return item
  75. }
  76. func (pq *priorityQueue) Update(item *pqItem, value interface{}, priority Comparable) {
  77. item.value = value
  78. item.priority = priority
  79. heap.Fix(pq, item.index)
  80. }