github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/queues/ring_mutex.go (about) 1 package goqueuestest 2 3 import ( 4 "container/ring" 5 "sync" 6 ) 7 8 type RmLifo struct { 9 head *ring.Ring // last enqueued value 10 length int 11 capacity int 12 m sync.Mutex 13 } 14 15 func NewRmLifo() *RmLifo { 16 q := &RmLifo{} 17 q.length = 0 18 q.capacity = growBy 19 q.head = ring.New(growBy) 20 q.m = sync.Mutex{} 21 return q 22 } 23 24 func (q *RmLifo) Enqueue(value interface{}) { 25 q.m.Lock() 26 if q.length >= q.capacity { 27 q.capacity = q.capacity + growBy 28 q.head.Link(ring.New(growBy)) 29 } 30 q.head = q.head.Next() 31 q.head.Value = value 32 q.length += 1 33 q.m.Unlock() 34 } 35 36 func (q *RmLifo) Dequeue() (value interface{}, ok bool) { 37 q.m.Lock() 38 if q.length == 0 { 39 q.m.Unlock() 40 return nil, false 41 } 42 value = q.head.Value 43 q.head = q.head.Prev() 44 q.length -= 1 45 q.m.Unlock() 46 return value, true 47 } 48 49 type RmFifo struct { 50 head *ring.Ring // last enqueued value 51 tail *ring.Ring // last dequeued value 52 length int 53 capacity int 54 m sync.Mutex 55 } 56 57 func NewRmFifo() *RmFifo { 58 q := &RmFifo{} 59 q.length = 0 60 q.capacity = growBy 61 q.head = ring.New(growBy) 62 q.tail = q.head 63 q.m = sync.Mutex{} 64 return q 65 } 66 67 func (q *RmFifo) Enqueue(value interface{}) { 68 q.m.Lock() 69 if q.length+1 >= q.capacity { 70 q.capacity = q.capacity + growBy 71 q.head.Link(ring.New(growBy)) 72 } 73 q.head = q.head.Next() 74 q.head.Value = value 75 q.length += 1 76 q.m.Unlock() 77 } 78 79 func (q *RmFifo) Dequeue() (value interface{}, ok bool) { 80 q.m.Lock() 81 if q.length == 0 { 82 q.m.Unlock() 83 return nil, false 84 } 85 q.tail = q.tail.Next() 86 value = q.tail.Value 87 q.length -= 1 88 q.m.Unlock() 89 return value, true 90 }