github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/queue/blockqueue/queue.go (about)

     1  package blockqueue
     2  
     3  const (
     4  	BlockSize = 1024
     5  	BlockMask = BlockSize - 1
     6  )
     7  
     8  type Queue struct {
     9  	headx  uint32
    10  	tailx  uint32
    11  	head   *Block
    12  	tail   *Block
    13  	blocks uint32
    14  }
    15  
    16  type Block struct {
    17  	Items [BlockSize]interface{}
    18  	Next  *Block
    19  }
    20  
    21  func New() *Queue { return &Queue{} }
    22  
    23  func (q *Queue) Len() int {
    24  	return int(q.blocks)*BlockSize - BlockSize + int(q.tailx) - int(q.headx)
    25  }
    26  
    27  func (q *Queue) Empty() bool { return q.head == nil }
    28  
    29  func (q *Queue) newBlock() *Block {
    30  	return &Block{}
    31  }
    32  
    33  func (q *Queue) tailBlock() *Block {
    34  	if q.tail != nil {
    35  		return q.tail
    36  	}
    37  
    38  	q.tail = q.newBlock()
    39  	q.head = q.tail
    40  
    41  	return q.tail
    42  }
    43  
    44  func (q *Queue) Push(v interface{}) {
    45  	first := q.tailBlock()
    46  	first.Items[q.tailx&BlockMask] = v
    47  	q.tailx++
    48  	if q.tailx == BlockSize {
    49  		q.tailx = 0
    50  		tail := q.tail
    51  		q.tail = q.newBlock()
    52  		tail.Next = q.tail
    53  		q.blocks++
    54  	}
    55  }
    56  
    57  func (q *Queue) Pop() (interface{}, bool) {
    58  	if q.head == nil {
    59  		return nil, false
    60  	}
    61  
    62  	value := q.head.Items[q.headx&BlockMask]
    63  	q.head.Items[q.headx&BlockMask] = nil
    64  	q.headx++
    65  	if q.headx == BlockSize {
    66  		q.headx = 0
    67  		q.blocks--
    68  		q.head.Next, q.head = nil, q.head.Next
    69  	}
    70  
    71  	return value, true
    72  }