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  }