github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/queues/slice_chan.go (about) 1 // implements locking queues, using list and mutex 2 package goqueuestest 3 4 type ScLifo struct { 5 l []interface{} 6 last int 7 lock chan int 8 } 9 10 func NewScLifo() *ScLifo { 11 q := &ScLifo{} 12 q.l = make([]interface{}, 0, growBy) 13 q.last = -1 14 q.lock = make(chan int, 1) 15 q.lock <- 1 16 return q 17 } 18 19 func (q *ScLifo) Enqueue(value interface{}) { 20 <-q.lock 21 q.l = append(q.l, value) 22 q.last += 1 23 q.lock <- 1 24 } 25 26 func (q *ScLifo) Dequeue() (interface{}, bool) { 27 <-q.lock 28 if q.last < 0 { 29 q.lock <- 1 30 return nil, false 31 } 32 value := q.l[q.last] 33 q.last -= 1 34 q.lock <- 1 35 return value, true 36 } 37 38 type ScFifo struct { 39 l []interface{} 40 tail int 41 head int 42 length int 43 lock chan int 44 } 45 46 func NewScFifo() *ScFifo { 47 q := &ScFifo{} 48 q.l = make([]interface{}, growBy) 49 q.tail = 0 50 q.head = 0 51 q.length = 0 52 q.lock = make(chan int, 1) 53 q.lock <- 1 54 return q 55 } 56 57 func (q *ScFifo) Enqueue(value interface{}) { 58 <-q.lock 59 if q.length >= len(q.l) { 60 q.l = append(q.l[q.tail:], q.l[:q.head]...) 61 q.l = append(q.l, make([]interface{}, growBy)...) 62 q.tail = 0 63 q.head = q.length 64 } 65 q.l[q.head] = value 66 q.head = (q.head + 1) % len(q.l) 67 q.length += 1 68 q.lock <- 1 69 } 70 71 func (q *ScFifo) Dequeue() (interface{}, bool) { 72 <-q.lock 73 if q.length == 0 { 74 q.lock <- 1 75 return nil, false 76 } 77 value := q.l[q.tail] 78 q.tail = (q.tail + 1) % len(q.l) 79 q.length -= 1 80 q.lock <- 1 81 return value, true 82 }