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  }