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.

143 lines
2.6 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. package common
  2. import (
  3. "container/heap"
  4. "sync"
  5. )
  6. /*
  7. Example usage:
  8. func main() {
  9. h := NewHeap()
  10. h.Push(String("msg1"), 1)
  11. h.Push(String("msg3"), 3)
  12. h.Push(String("msg2"), 2)
  13. fmt.Println(h.Pop())
  14. fmt.Println(h.Pop())
  15. fmt.Println(h.Pop())
  16. }
  17. */
  18. type Comparable interface {
  19. Less(o interface{}) bool
  20. }
  21. //-----------------------------------------------------------------------------
  22. type Heap struct {
  23. pq priorityQueue
  24. }
  25. func NewHeap() *Heap {
  26. return &Heap{pq: make([]*pqItem, 0)}
  27. }
  28. func (h *Heap) Len() int64 {
  29. return int64(len(h.pq))
  30. }
  31. func (h *Heap) Push(value interface{}, priority Comparable) {
  32. heap.Push(&h.pq, &pqItem{value: value, priority: priority})
  33. }
  34. func (h *Heap) Peek() interface{} {
  35. if len(h.pq) == 0 {
  36. return nil
  37. }
  38. return h.pq[0].value
  39. }
  40. func (h *Heap) Pop() interface{} {
  41. item := heap.Pop(&h.pq).(*pqItem)
  42. return item.value
  43. }
  44. //-----------------------------------------------------------------------------
  45. type CHeap struct {
  46. mtx sync.Mutex
  47. pq priorityQueue
  48. }
  49. func NewCHeap() *CHeap {
  50. return &CHeap{pq: make([]*pqItem, 0)}
  51. }
  52. func (h *CHeap) Len() int64 {
  53. h.mtx.Lock()
  54. defer h.mtx.Unlock()
  55. return int64(len(h.pq))
  56. }
  57. func (h *CHeap) Push(value interface{}, priority Comparable) {
  58. h.mtx.Lock()
  59. defer h.mtx.Unlock()
  60. heap.Push(&h.pq, &pqItem{value: value, priority: priority})
  61. }
  62. func (h *CHeap) Peek() interface{} {
  63. h.mtx.Lock()
  64. defer h.mtx.Unlock()
  65. if len(h.pq) == 0 {
  66. return nil
  67. }
  68. return h.pq[0].value
  69. }
  70. func (h *CHeap) Pop() interface{} {
  71. h.mtx.Lock()
  72. defer h.mtx.Unlock()
  73. item := heap.Pop(&h.pq).(*pqItem)
  74. return item.value
  75. }
  76. //-----------------------------------------------------------------------------
  77. ///////////////////////
  78. // From: http://golang.org/pkg/container/heap/#example__priorityQueue
  79. type pqItem struct {
  80. value interface{}
  81. priority Comparable
  82. index int
  83. }
  84. type priorityQueue []*pqItem
  85. func (pq priorityQueue) Len() int { return len(pq) }
  86. func (pq priorityQueue) Less(i, j int) bool {
  87. return pq[i].priority.Less(pq[j].priority)
  88. }
  89. func (pq priorityQueue) Swap(i, j int) {
  90. pq[i], pq[j] = pq[j], pq[i]
  91. pq[i].index = i
  92. pq[j].index = j
  93. }
  94. func (pq *priorityQueue) Push(x interface{}) {
  95. n := len(*pq)
  96. item := x.(*pqItem)
  97. item.index = n
  98. *pq = append(*pq, item)
  99. }
  100. func (pq *priorityQueue) Pop() interface{} {
  101. old := *pq
  102. n := len(old)
  103. item := old[n-1]
  104. item.index = -1 // for safety
  105. *pq = old[0 : n-1]
  106. return item
  107. }
  108. func (pq *priorityQueue) Update(item *pqItem, value interface{}, priority Comparable) {
  109. heap.Remove(pq, item.index)
  110. item.value = value
  111. item.priority = priority
  112. heap.Push(pq, item)
  113. }