github.com/operator-framework/operator-lifecycle-manager@v0.30.0/test/e2e/util/resource_queue.go (about) 1 package util 2 3 import ( 4 "fmt" 5 k8scontrollerclient "sigs.k8s.io/controller-runtime/pkg/client" 6 "sync" 7 ) 8 9 type ResourceQueue struct { 10 queue []k8scontrollerclient.Object 11 lookupTable map[k8scontrollerclient.Object]bool 12 lock *sync.Mutex 13 } 14 15 func NewResourceQueue() *ResourceQueue { 16 return &ResourceQueue{ 17 queue: []k8scontrollerclient.Object{}, 18 lookupTable: map[k8scontrollerclient.Object]bool{}, 19 lock: &sync.Mutex{}, 20 } 21 } 22 23 func (q *ResourceQueue) Enqueue(obj k8scontrollerclient.Object) error { 24 q.lock.Lock() 25 defer q.lock.Unlock() 26 27 if _, ok := q.lookupTable[obj]; ok { 28 return fmt.Errorf("error inserting duplicate object: %s", obj) 29 } 30 q.queue = append(q.queue, obj) 31 q.lookupTable[obj] = true 32 return nil 33 } 34 35 func (q *ResourceQueue) EnqueueIgnoreExisting(obj k8scontrollerclient.Object) { 36 q.lock.Lock() 37 defer q.lock.Unlock() 38 39 if _, ok := q.lookupTable[obj]; ok { 40 return 41 } 42 q.queue = append(q.queue, obj) 43 q.lookupTable[obj] = true 44 } 45 46 func (q *ResourceQueue) Length() int { 47 return len(q.queue) 48 } 49 50 func (q *ResourceQueue) RemoveIgnoreNotFound(obj k8scontrollerclient.Object) { 51 q.lock.Lock() 52 defer q.lock.Unlock() 53 54 if _, ok := q.lookupTable[obj]; ok { 55 for index, existingObj := range q.queue { 56 if q.equals(existingObj, obj) { 57 _ = q.removeItem(index) 58 delete(q.lookupTable, obj) 59 return 60 } 61 } 62 } 63 } 64 65 func (q *ResourceQueue) equals(objOne k8scontrollerclient.Object, objTwo k8scontrollerclient.Object) bool { 66 return objOne.GetName() == objTwo.GetName() && objOne.GetNamespace() == objTwo.GetNamespace() 67 } 68 69 func (q *ResourceQueue) DequeueHead() (k8scontrollerclient.Object, bool) { 70 q.lock.Lock() 71 defer q.lock.Unlock() 72 73 if q.Length() == 0 { 74 return nil, false 75 } 76 return q.removeItem(0), true 77 } 78 79 func (q *ResourceQueue) DequeueTail() (k8scontrollerclient.Object, bool) { 80 q.lock.Lock() 81 defer q.lock.Unlock() 82 83 if len(q.queue) == 0 { 84 return nil, false 85 } 86 return q.removeItem(q.Length() - 1), true 87 } 88 89 func (q *ResourceQueue) removeItem(index int) k8scontrollerclient.Object { 90 if index < 0 || index >= q.Length() { 91 panic("index out of bounds") 92 } 93 item := q.queue[index] 94 copy(q.queue[index:], q.queue[index+1:]) 95 q.queue[len(q.queue)-1] = nil 96 q.queue = q.queue[:len(q.queue)-1] 97 delete(q.lookupTable, item) 98 99 return item 100 }