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 }