github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/queue/blockfreequeue/queue.go (about) 1 package blockfreequeue 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 free *Block 14 blocks uint32 15 } 16 17 type Block struct { 18 Items [BlockSize]interface{} 19 Next *Block 20 } 21 22 func New() *Queue { return &Queue{} } 23 24 func (q *Queue) Len() int { 25 return int(q.blocks)*BlockSize - BlockSize + int(q.tailx) - int(q.headx) 26 } 27 28 func (q *Queue) newBlock() *Block { 29 block := q.free 30 if block == nil { 31 return &Block{} 32 } else { 33 q.free = nil 34 } 35 return block 36 } 37 38 func (q *Queue) tailBlock() *Block { 39 if q.tail != nil { 40 return q.tail 41 } 42 43 q.tail = q.newBlock() 44 q.head = q.tail 45 46 return q.tail 47 } 48 49 func (q *Queue) Push(v interface{}) { 50 first := q.tailBlock() 51 first.Items[q.tailx&BlockMask] = v 52 q.tailx++ 53 if q.tailx == BlockSize { 54 q.tailx = 0 55 tail := q.tail 56 q.tail = q.newBlock() 57 tail.Next = q.tail 58 q.blocks++ 59 } 60 } 61 62 func (q *Queue) Pop() (interface{}, bool) { 63 if q.head == nil { 64 return nil, false 65 } 66 67 value := q.head.Items[q.headx&BlockMask] 68 q.head.Items[q.headx&BlockMask] = nil 69 q.headx++ 70 if q.headx == BlockSize { 71 q.headx = 0 72 q.blocks-- 73 q.free, q.head = q.head, q.head.Next 74 q.free.Next = nil 75 } 76 77 return value, true 78 }