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  }