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  }