github.com/mailgun/holster/v4@v4.20.0/collections/priority_queue.go (about) 1 /* 2 Copyright 2017 Mailgun Technologies Inc 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 package collections 17 18 import ( 19 "container/heap" 20 ) 21 22 // An PQItem is something we manage in a priority queue. 23 type PQItem struct { 24 Value interface{} 25 Priority int // The priority of the item in the queue. 26 // The index is needed by update and is maintained by the heap.Interface methods. 27 index int // The index of the item in the heap. 28 } 29 30 // Implements a PriorityQueue 31 type PriorityQueue struct { 32 impl *pqImpl 33 } 34 35 func NewPriorityQueue() *PriorityQueue { 36 mh := &pqImpl{} 37 heap.Init(mh) 38 return &PriorityQueue{impl: mh} 39 } 40 41 func (p PriorityQueue) Len() int { return p.impl.Len() } 42 43 func (p *PriorityQueue) Push(el *PQItem) { 44 heap.Push(p.impl, el) 45 } 46 47 func (p *PriorityQueue) Pop() *PQItem { 48 el := heap.Pop(p.impl) 49 return el.(*PQItem) 50 } 51 52 func (p *PriorityQueue) Peek() *PQItem { 53 return (*p.impl)[0] 54 } 55 56 // Modifies the priority and value of an Item in the queue. 57 func (p *PriorityQueue) Update(el *PQItem, priority int) { 58 heap.Remove(p.impl, el.index) 59 el.Priority = priority 60 heap.Push(p.impl, el) 61 } 62 63 func (p *PriorityQueue) Remove(el *PQItem) { 64 heap.Remove(p.impl, el.index) 65 } 66 67 // Actual Implementation using heap.Interface 68 type pqImpl []*PQItem 69 70 func (mh pqImpl) Len() int { return len(mh) } 71 72 func (mh pqImpl) Less(i, j int) bool { 73 return mh[i].Priority < mh[j].Priority 74 } 75 76 func (mh pqImpl) Swap(i, j int) { 77 mh[i], mh[j] = mh[j], mh[i] 78 mh[i].index = i 79 mh[j].index = j 80 } 81 82 func (mh *pqImpl) Push(x interface{}) { 83 n := len(*mh) 84 item := x.(*PQItem) 85 item.index = n 86 *mh = append(*mh, item) 87 } 88 89 func (mh *pqImpl) Pop() interface{} { 90 old := *mh 91 n := len(old) 92 item := old[n-1] 93 item.index = -1 // for safety 94 *mh = old[0 : n-1] 95 return item 96 }