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 }