github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/queues/pathological/lifo.go (about)

     1  package pathological
     2  
     3  import "sync"
     4  
     5  const growBy = 1000
     6  
     7  type Queue interface {
     8  	Enqueue(value interface{})
     9  	Dequeue() (value interface{}, ok bool)
    10  }
    11  
    12  type ScLifo struct {
    13  	l    []interface{}
    14  	last int
    15  	lock chan int
    16  }
    17  
    18  func NewScLifo() *ScLifo {
    19  	q := &ScLifo{}
    20  	q.l = make([]interface{}, 0, growBy)
    21  	q.last = -1
    22  	q.lock = make(chan int, 1)
    23  	q.lock <- 1
    24  	return q
    25  }
    26  
    27  func (q *ScLifo) Enqueue(value interface{}) {
    28  	<-q.lock
    29  	q.l = append(q.l, value)
    30  	q.last += 1
    31  	q.lock <- 1
    32  }
    33  
    34  func (q *ScLifo) Dequeue() (interface{}, bool) {
    35  	<-q.lock
    36  	if q.last < 0 {
    37  		q.lock <- 1
    38  		return nil, false
    39  	}
    40  	value := q.l[q.last]
    41  	q.last -= 1
    42  	q.lock <- 1
    43  	return value, true
    44  }
    45  
    46  type SmLifo struct {
    47  	l    []interface{}
    48  	last int
    49  	m    sync.Mutex
    50  }
    51  
    52  func NewSmLifo() *SmLifo {
    53  	q := &SmLifo{}
    54  	q.l = make([]interface{}, 0, growBy)
    55  	q.last = -1
    56  	return q
    57  }
    58  
    59  func (q *SmLifo) Enqueue(value interface{}) {
    60  	q.m.Lock()
    61  	q.l = append(q.l, value)
    62  	q.last += 1
    63  	q.m.Unlock()
    64  }
    65  
    66  func (q *SmLifo) Dequeue() (interface{}, bool) {
    67  	q.m.Lock()
    68  	if q.last < 0 {
    69  		q.m.Unlock()
    70  		return nil, false
    71  	}
    72  	value := q.l[q.last]
    73  	q.last -= 1
    74  	q.m.Unlock()
    75  	return value, true
    76  }