go.temporal.io/server@v1.23.0/common/collection/priority_queue.go (about) 1 // The MIT License 2 // 3 // Copyright (c) 2020 Temporal Technologies Inc. All rights reserved. 4 // 5 // Copyright (c) 2020 Uber Technologies, Inc. 6 // 7 // Permission is hereby granted, free of charge, to any person obtaining a copy 8 // of this software and associated documentation files (the "Software"), to deal 9 // in the Software without restriction, including without limitation the rights 10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 // copies of the Software, and to permit persons to whom the Software is 12 // furnished to do so, subject to the following conditions: 13 // 14 // The above copyright notice and this permission notice shall be included in 15 // all copies or substantial portions of the Software. 16 // 17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 // THE SOFTWARE. 24 25 package collection 26 27 import ( 28 "container/heap" 29 ) 30 31 type ( 32 priorityQueueImpl[T any] struct { 33 compareLess func(this T, other T) bool 34 items []T 35 } 36 ) 37 38 // NewPriorityQueue create a new priority queue 39 func NewPriorityQueue[T any]( 40 compareLess func(this T, other T) bool, 41 ) Queue[T] { 42 return &priorityQueueImpl[T]{ 43 compareLess: compareLess, 44 } 45 } 46 47 // NewPriorityQueueWithItems creats a new priority queue 48 // with the provided list of items. 49 // PriorityQueue will take ownership of the passed in items, 50 // so caller should stop modifying it. 51 // The complexity is O(n) where n is the number of items 52 func NewPriorityQueueWithItems[T any]( 53 compareLess func(this T, other T) bool, 54 items []T, 55 ) Queue[T] { 56 pq := &priorityQueueImpl[T]{ 57 compareLess: compareLess, 58 items: items, 59 } 60 heap.Init(pq) 61 return pq 62 } 63 64 // Peek returns the top item of the priority queue 65 func (pq *priorityQueueImpl[T]) Peek() T { 66 if pq.IsEmpty() { 67 panic("Cannot peek item because priority queue is empty") 68 } 69 return pq.items[0] 70 } 71 72 // Add push an item to priority queue 73 func (pq *priorityQueueImpl[T]) Add(item T) { 74 heap.Push(pq, item) 75 } 76 77 // Remove pop an item from priority queue 78 func (pq *priorityQueueImpl[T]) Remove() T { 79 return heap.Pop(pq).(T) 80 } 81 82 // IsEmpty indicate if the priority queue is empty 83 func (pq *priorityQueueImpl[T]) IsEmpty() bool { 84 return pq.Len() == 0 85 } 86 87 // below are the functions used by heap.Interface and go internal heap implementation 88 89 // Len implements sort.Interface 90 func (pq *priorityQueueImpl[T]) Len() int { 91 return len(pq.items) 92 } 93 94 // Less implements sort.Interface 95 func (pq *priorityQueueImpl[T]) Less(i, j int) bool { 96 return pq.compareLess(pq.items[i], pq.items[j]) 97 } 98 99 // Swap implements sort.Interface 100 func (pq *priorityQueueImpl[T]) Swap(i, j int) { 101 pq.items[i], pq.items[j] = pq.items[j], pq.items[i] 102 } 103 104 // Push push an item to priority queue, used by go internal heap implementation 105 func (pq *priorityQueueImpl[T]) Push(item interface{}) { 106 pq.items = append(pq.items, item.(T)) 107 } 108 109 // Pop pop an item from priority queue, used by go internal heap implementation 110 func (pq *priorityQueueImpl[T]) Pop() interface{} { 111 pqItem := pq.items[pq.Len()-1] 112 pq.items = pq.items[0 : pq.Len()-1] 113 return pqItem 114 }