github.com/lingyao2333/mo-zero@v1.4.1/core/collection/fifo.go (about)

     1  package collection
     2  
     3  import "sync"
     4  
     5  // A Queue is a FIFO queue.
     6  type Queue struct {
     7  	lock     sync.Mutex
     8  	elements []interface{}
     9  	size     int
    10  	head     int
    11  	tail     int
    12  	count    int
    13  }
    14  
    15  // NewQueue returns a Queue object.
    16  func NewQueue(size int) *Queue {
    17  	return &Queue{
    18  		elements: make([]interface{}, size),
    19  		size:     size,
    20  	}
    21  }
    22  
    23  // Empty checks if q is empty.
    24  func (q *Queue) Empty() bool {
    25  	q.lock.Lock()
    26  	empty := q.count == 0
    27  	q.lock.Unlock()
    28  
    29  	return empty
    30  }
    31  
    32  // Put puts element into q at the last position.
    33  func (q *Queue) Put(element interface{}) {
    34  	q.lock.Lock()
    35  	defer q.lock.Unlock()
    36  
    37  	if q.head == q.tail && q.count > 0 {
    38  		nodes := make([]interface{}, len(q.elements)+q.size)
    39  		copy(nodes, q.elements[q.head:])
    40  		copy(nodes[len(q.elements)-q.head:], q.elements[:q.head])
    41  		q.head = 0
    42  		q.tail = len(q.elements)
    43  		q.elements = nodes
    44  	}
    45  
    46  	q.elements[q.tail] = element
    47  	q.tail = (q.tail + 1) % len(q.elements)
    48  	q.count++
    49  }
    50  
    51  // Take takes the first element out of q if not empty.
    52  func (q *Queue) Take() (interface{}, bool) {
    53  	q.lock.Lock()
    54  	defer q.lock.Unlock()
    55  
    56  	if q.count == 0 {
    57  		return nil, false
    58  	}
    59  
    60  	element := q.elements[q.head]
    61  	q.head = (q.head + 1) % len(q.elements)
    62  	q.count--
    63  
    64  	return element, true
    65  }