github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/internal/list2/queue.go (about) 1 // Copyright 2021 The Bitalosdb author(hustxrb@163.com) and other contributors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package list2 16 17 import ( 18 "container/list" 19 "math/bits" 20 ) 21 22 type Queue struct { 23 list *list.List 24 } 25 26 func NewQueue() *Queue { 27 l := list.New() 28 return &Queue{l} 29 } 30 31 func (q *Queue) Push(value interface{}) { 32 q.list.PushFront(value) 33 } 34 35 func (q *Queue) Pop() interface{} { 36 e := q.list.Back() 37 if e != nil { 38 q.list.Remove(e) 39 return e.Value 40 } 41 return nil 42 } 43 44 func (q *Queue) Peak() interface{} { 45 e := q.list.Back() 46 if e != nil { 47 return e.Value 48 } 49 50 return nil 51 } 52 53 func (q *Queue) Len() int { 54 return q.list.Len() 55 } 56 57 func (q *Queue) Empty() bool { 58 return q.list.Len() == 0 59 } 60 61 const ( 62 dequeueBits = 32 63 mask = 1<<dequeueBits - 1 64 ) 65 66 type IntQueue struct { 67 headTail uint64 68 data []int32 69 } 70 71 func NewIntQueue(size uint32) *IntQueue { 72 sq := &IntQueue{headTail: 0} 73 sq.data = make([]int32, calcBitsSize(int(size))) 74 75 return sq 76 } 77 78 func (q *IntQueue) unpack(ptrs uint64) (head, tail uint32) { 79 head = uint32((ptrs >> dequeueBits) & mask) 80 tail = uint32(ptrs & mask) 81 return 82 } 83 84 func (q *IntQueue) pack(head, tail uint32) uint64 { 85 return (uint64(head) << dequeueBits) | uint64(tail&mask) 86 } 87 88 func (q *IntQueue) Push(value int32) { 89 head, _ := q.unpack(q.headTail) 90 q.data[head&uint32(len(q.data)-1)] = value 91 q.headTail += 1 << dequeueBits 92 } 93 94 func (q *IntQueue) Front() (int32, bool) { 95 head, tail := q.unpack(q.headTail) 96 if tail == head { 97 return 0, false 98 } 99 100 value := q.data[tail&uint32(len(q.data)-1)] 101 102 return value, true 103 } 104 105 func (q *IntQueue) Pop() (int32, bool) { 106 head, tail := q.unpack(q.headTail) 107 if tail == head { 108 return 0, false 109 } 110 111 index := tail & uint32(len(q.data)-1) 112 value := q.data[index] 113 q.data[index] = 0 114 115 q.headTail = q.pack(head, tail+1) 116 return value, true 117 } 118 119 func (q *IntQueue) Empty() bool { 120 head, tail := q.unpack(q.headTail) 121 return tail == head 122 } 123 124 func (q *IntQueue) Len() int { 125 head, tail := q.unpack(q.headTail) 126 return int(head) - int(tail) 127 } 128 129 type Int64Queue struct { 130 headTail uint64 131 data []int64 132 } 133 134 func NewInt64Queue(size uint32) *Int64Queue { 135 sq := &Int64Queue{headTail: 0} 136 sq.data = make([]int64, calcBitsSize(int(size))) 137 138 return sq 139 } 140 141 func (q *Int64Queue) unpack(ptrs uint64) (head, tail uint32) { 142 head = uint32((ptrs >> dequeueBits) & mask) 143 tail = uint32(ptrs & mask) 144 return 145 } 146 147 func (q *Int64Queue) pack(head, tail uint32) uint64 { 148 return (uint64(head) << dequeueBits) | uint64(tail&mask) 149 } 150 151 func (q *Int64Queue) Push(value int64) { 152 head, _ := q.unpack(q.headTail) 153 q.data[head&uint32(len(q.data)-1)] = value 154 q.headTail += 1 << dequeueBits 155 } 156 157 func (q *Int64Queue) Front() (int64, bool) { 158 head, tail := q.unpack(q.headTail) 159 if tail == head { 160 return 0, false 161 } 162 163 value := q.data[tail&uint32(len(q.data)-1)] 164 165 return value, true 166 } 167 168 func (q *Int64Queue) Pop() (int64, bool) { 169 head, tail := q.unpack(q.headTail) 170 if tail == head { 171 return 0, false 172 } 173 174 index := tail & uint32(len(q.data)-1) 175 value := q.data[index] 176 q.data[index] = 0 177 178 q.headTail = q.pack(head, tail+1) 179 return value, true 180 } 181 182 func (q *Int64Queue) Empty() bool { 183 head, tail := q.unpack(q.headTail) 184 return tail == head 185 } 186 187 func (q *Int64Queue) Len() int { 188 head, tail := q.unpack(q.headTail) 189 return int(head) - int(tail) 190 } 191 192 func calcBitsSize(sz int) int { 193 return 1 << bits.Len(uint(sz)) 194 }