github.com/supragya/TendermintConnector@v0.0.0-20210619045051-113e32b84fb1/_deprecated_chains/cosmos/libs/common/heap.go (about) 1 package common 2 3 import ( 4 "bytes" 5 "container/heap" 6 ) 7 8 /* 9 Example usage: 10 11 ``` 12 h := NewHeap() 13 14 h.Push("msg1", 1) 15 h.Push("msg3", 3) 16 h.Push("msg2", 2) 17 18 fmt.Println(h.Pop()) // msg1 19 fmt.Println(h.Pop()) // msg2 20 fmt.Println(h.Pop()) // msg3 21 ``` 22 */ 23 type Heap struct { 24 pq priorityQueue 25 } 26 27 func NewHeap() *Heap { 28 return &Heap{pq: make([]*pqItem, 0)} 29 } 30 31 func (h *Heap) Len() int64 { 32 return int64(len(h.pq)) 33 } 34 35 func (h *Heap) Push(value interface{}, priority int) { 36 heap.Push(&h.pq, &pqItem{value: value, priority: cmpInt(priority)}) 37 } 38 39 func (h *Heap) PushBytes(value interface{}, priority []byte) { 40 heap.Push(&h.pq, &pqItem{value: value, priority: cmpBytes(priority)}) 41 } 42 43 func (h *Heap) PushComparable(value interface{}, priority Comparable) { 44 heap.Push(&h.pq, &pqItem{value: value, priority: priority}) 45 } 46 47 func (h *Heap) Peek() interface{} { 48 if len(h.pq) == 0 { 49 return nil 50 } 51 return h.pq[0].value 52 } 53 54 func (h *Heap) Update(value interface{}, priority Comparable) { 55 h.pq.Update(h.pq[0], value, priority) 56 } 57 58 func (h *Heap) Pop() interface{} { 59 item := heap.Pop(&h.pq).(*pqItem) 60 return item.value 61 } 62 63 //----------------------------------------------------------------------------- 64 // From: http://golang.org/pkg/container/heap/#example__priorityQueue 65 66 type pqItem struct { 67 value interface{} 68 priority Comparable 69 index int 70 } 71 72 type priorityQueue []*pqItem 73 74 func (pq priorityQueue) Len() int { return len(pq) } 75 76 func (pq priorityQueue) Less(i, j int) bool { 77 return pq[i].priority.Less(pq[j].priority) 78 } 79 80 func (pq priorityQueue) Swap(i, j int) { 81 pq[i], pq[j] = pq[j], pq[i] 82 pq[i].index = i 83 pq[j].index = j 84 } 85 86 func (pq *priorityQueue) Push(x interface{}) { 87 n := len(*pq) 88 item := x.(*pqItem) 89 item.index = n 90 *pq = append(*pq, item) 91 } 92 93 func (pq *priorityQueue) Pop() interface{} { 94 old := *pq 95 n := len(old) 96 item := old[n-1] 97 item.index = -1 // for safety 98 *pq = old[0 : n-1] 99 return item 100 } 101 102 func (pq *priorityQueue) Update(item *pqItem, value interface{}, priority Comparable) { 103 item.value = value 104 item.priority = priority 105 heap.Fix(pq, item.index) 106 } 107 108 //-------------------------------------------------------------------------------- 109 // Comparable 110 111 type Comparable interface { 112 Less(o interface{}) bool 113 } 114 115 type cmpInt int 116 117 func (i cmpInt) Less(o interface{}) bool { 118 return int(i) < int(o.(cmpInt)) 119 } 120 121 type cmpBytes []byte 122 123 func (bz cmpBytes) Less(o interface{}) bool { 124 return bytes.Compare([]byte(bz), []byte(o.(cmpBytes))) < 0 125 }