github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/queues/slice_mutex.go (about) 1 // implements locking queues, using list and mutex 2 package goqueuestest 3 4 import ( 5 "sync" 6 ) 7 8 type SmLifo struct { 9 l []interface{} 10 last int 11 m sync.Mutex 12 } 13 14 func NewSmLifo() *SmLifo { 15 q := &SmLifo{} 16 q.l = make([]interface{}, 0, growBy) 17 q.last = -1 18 return q 19 } 20 21 func (q *SmLifo) Enqueue(value interface{}) { 22 q.m.Lock() 23 q.l = append(q.l, value) 24 q.last += 1 25 q.m.Unlock() 26 } 27 28 func (q *SmLifo) Dequeue() (interface{}, bool) { 29 q.m.Lock() 30 if q.last < 0 { 31 q.m.Unlock() 32 return nil, false 33 } 34 value := q.l[q.last] 35 q.last -= 1 36 q.m.Unlock() 37 return value, true 38 } 39 40 type SmFifo struct { 41 l []interface{} 42 tail int 43 head int 44 length int 45 m sync.Mutex 46 } 47 48 func NewSmFifo() *SmFifo { 49 q := &SmFifo{} 50 q.l = make([]interface{}, growBy) 51 q.tail = 0 52 q.head = 0 53 q.length = 0 54 return q 55 } 56 57 func (q *SmFifo) Enqueue(value interface{}) { 58 q.m.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.m.Unlock() 69 } 70 71 func (q *SmFifo) Dequeue() (interface{}, bool) { 72 q.m.Lock() 73 if q.length == 0 { 74 q.m.Unlock() 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.m.Unlock() 81 return value, true 82 }