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