gitlab.com/beacon-software/gadget@v0.0.0-20181217202115-54565ea1ed5e/collection/specialized/priorityqueue.go (about) 1 package specialized 2 3 import "gitlab.com/beacon-software/gadget/collection" 4 5 // Priority is for use in collections that require elements to resolve 6 // their own priority. 7 type Priority interface { 8 // GetPriority of this element as an int where lower priority < higher priority 9 GetPriority() int 10 } 11 12 // PriorityQueue for queueing elements that implement priority and returning 13 // elements in the order of highest to lowest priority. 14 type PriorityQueue interface { 15 // Size of this queue 16 Size() int 17 // Push the passed element onto this queue 18 Push(element Priority) 19 // Pop the highest priority element off the queue 20 Pop() (Priority, bool) 21 // Peek at the highest priority element without modifying the queue 22 Peek() (Priority, bool) 23 } 24 25 type priorityQueue struct { 26 list collection.DList 27 } 28 29 // NewPriorityQueue for queueing elements according to their priority 30 func NewPriorityQueue() PriorityQueue { 31 return &priorityQueue{list: collection.NewDList()} 32 } 33 34 func (q *priorityQueue) Size() int { 35 return q.list.Size() 36 } 37 38 func (q *priorityQueue) Push(p Priority) { 39 var e *collection.DListElement 40 for elm := q.list.Head(); elm != nil; elm = elm.Next() { 41 d := q.convert(elm.Data()) 42 if d.GetPriority() > p.GetPriority() { 43 e = elm 44 } 45 } 46 if nil == e { 47 q.list.InsertPrevious(q.list.Head(), p) 48 } else { 49 q.list.InsertNext(e, p) 50 } 51 } 52 53 func (q *priorityQueue) nextElement(remove bool) (Priority, bool) { 54 var p Priority 55 success := false 56 if q.list.Head() != nil { 57 success = true 58 p = q.convert(q.list.Head().Data()) 59 if remove { 60 q.list.Remove(q.list.Head()) 61 } 62 } 63 return p, success 64 } 65 66 func (q *priorityQueue) Pop() (Priority, bool) { 67 return q.nextElement(true) 68 } 69 70 func (q *priorityQueue) Peek() (Priority, bool) { 71 return q.nextElement(false) 72 } 73 74 func (q *priorityQueue) convert(data interface{}) Priority { 75 p, _ := data.(Priority) 76 return p 77 }