gitee.com/sy_183/go-common@v1.0.5-0.20231205030221-958cfe129b47/container/queue.go (about) 1 package container 2 3 import _ "unsafe" 4 5 //go:linkname goPanicIndex runtime.goPanicIndex 6 func goPanicIndex(x int, y int) 7 8 //go:linkname goPanicSliceAcap runtime.goPanicSliceAcap 9 func goPanicSliceAcap(x int, y int) 10 11 //go:linkname goPanicSliceB runtime.goPanicSliceB 12 func goPanicSliceB(x int, y int) 13 14 type Queue[E any] struct { 15 raw []E 16 head int 17 tail int 18 len int 19 cap int 20 } 21 22 func NewQueue[E any](cap int) *Queue[E] { 23 return &Queue[E]{ 24 raw: make([]E, cap, cap), 25 cap: cap, 26 } 27 } 28 29 func (q *Queue[E]) Init(cap int) { 30 *q = Queue[E]{ 31 raw: make([]E, cap, cap), 32 cap: cap, 33 } 34 } 35 36 func (q *Queue[E]) IsNil() bool { 37 return q.raw == nil 38 } 39 40 // Len 返回队列的长度 41 func (q *Queue[E]) Len() int { 42 return q.len 43 } 44 45 // Cap 返回队列的容量 46 func (q *Queue[E]) Cap() int { 47 return q.cap 48 } 49 50 // Empty 判断队列是否为空 51 func (q *Queue[E]) Empty() bool { 52 return q.len == 0 53 } 54 55 // Full 判断队列是否为满 56 func (q *Queue[E]) Full() bool { 57 return q.len == q.cap 58 } 59 60 func (q *Queue[E]) checkIndex(i int) { 61 if i >= q.len || i < 0 { 62 goPanicIndex(i, q.len) 63 } 64 } 65 66 func (q *Queue[E]) tailIndex() int { 67 tail := q.tail - 1 68 if tail < 0 { 69 tail = q.cap - 1 70 } 71 return tail 72 } 73 74 func (q *Queue[E]) rawIndex(i int) int { 75 if i += q.head; i >= q.cap { 76 return i - q.cap 77 } 78 return i 79 } 80 81 // Get 获取队列指定索引位置的元素 82 func (q *Queue[E]) Get(i int) E { 83 q.checkIndex(i) 84 return q.raw[q.rawIndex(i)] 85 } 86 87 // Use 获取队列指定索引位置的元素指针 88 func (q *Queue[E]) Use(i int) *E { 89 q.checkIndex(i) 90 return &q.raw[q.rawIndex(i)] 91 } 92 93 // Head 获取队列头部的元素,返回值 exist 为 false 表示队列为空 94 func (q *Queue[E]) Head() (e E, exist bool) { 95 if q.len > 0 { 96 return q.raw[q.head], true 97 } 98 return 99 } 100 101 // UseHead 获取队列头部的元素指针,返回 nil 表示队列为空 102 func (q *Queue[E]) UseHead() *E { 103 if q.len > 0 { 104 return &q.raw[q.head] 105 } 106 return nil 107 } 108 109 // Tail 获取队列尾部的元素,返回值 exist 为 false 表示队列为空 110 func (q *Queue[E]) Tail() (e E, exist bool) { 111 if q.len > 0 { 112 return q.raw[q.tailIndex()], true 113 } 114 return 115 } 116 117 // UseTail 获取队列尾部的元素指针,返回 nil 表示队列为空 118 func (q *Queue[E]) UseTail() *E { 119 if q.len > 0 { 120 return &q.raw[q.tailIndex()] 121 } 122 return nil 123 } 124 125 // Slice 获取队列空间指定范围内对应的切片,返回值 prefix, suffix 代表队列空间的前半部分(在范 126 // 围内头部指针后的空间)和后半部分(在范围内头部指针前的空间) 127 func (q *Queue[E]) Slice(start, end int) (prefix, suffix []E) { 128 if end < 0 { 129 end = q.len 130 } else if end > q.cap { 131 goPanicSliceAcap(end, q.cap) 132 } 133 if start < 0 { 134 start = 0 135 } else if start > end { 136 goPanicSliceB(start, end) 137 } 138 if start += q.head; start >= q.cap { 139 start -= q.cap 140 end += q.head - q.cap 141 return nil, q.raw[start:end] 142 } else if end += q.head; end > q.cap { 143 end -= q.cap 144 return q.raw[start:], q.raw[:end] 145 } else { 146 return q.raw[start:end], nil 147 } 148 } 149 150 // Copy 拷贝队列指定位置后的元素到指定切片,返回拷贝元素的个数 151 func (q *Queue[E]) Copy(dst []E, start int) (n int) { 152 if start < 0 { 153 start = 0 154 } else if start > q.len { 155 goPanicSliceB(start, q.len) 156 } 157 end := start + len(dst) 158 if end > q.len { 159 end = q.len 160 } 161 if start += q.head; start >= q.cap { 162 start -= q.cap 163 end += q.head - q.cap 164 return copy(dst, q.raw[start:end]) 165 } else if end += q.head; end > q.cap { 166 end -= q.cap 167 n = copy(dst, q.raw[start:]) 168 n += copy(dst[n:], q.raw[:end]) 169 return 170 } else { 171 return copy(dst, q.raw[start:end]) 172 } 173 } 174 175 // Range 遍历队列中的所有元素,fn 为遍历函数,遍历函数返回 false 则终止遍历,并使得此函数返回 176 // false。若遍历过程中没有因遍历函数终止遍历(即遍历完所有元素),则此函数返回 true 177 func (q *Queue[E]) Range(fn func(i int, e E) bool) bool { 178 head := q.head 179 for i := 0; i < q.len; i++ { 180 if !fn(i, q.raw[head]) { 181 return false 182 } 183 if head++; head == q.cap { 184 head = 0 185 } 186 } 187 return true 188 } 189 190 func (q *Queue[E]) tailGrow() { 191 if q.tail++; q.tail == q.cap { 192 q.tail = 0 193 } 194 q.len++ 195 } 196 197 func (q *Queue[E]) headGrow() { 198 if q.head--; q.head < 0 { 199 q.head = q.cap - 1 200 } 201 q.len++ 202 } 203 204 // Append 在队列尾部添加元素,队列满则不执行任何操作 205 func (q *Queue[E]) Append(e E) { 206 if q.len == q.cap { 207 return 208 } 209 q.raw[q.tail] = e 210 q.tailGrow() 211 } 212 213 // Append 在队列尾部添加元素,队列满则抛出错误 214 func (q *Queue[E]) MustAppend(e E) { 215 if q.len == q.cap { 216 goPanicSliceAcap(q.len+1, q.cap) 217 } 218 q.raw[q.tail] = e 219 q.tailGrow() 220 } 221 222 // Push 在队列尾部添加元素,添加成功返回 true,由于队列满添加失败返回 false 223 func (q *Queue[E]) Push(e E) bool { 224 if q.len == q.cap { 225 return false 226 } 227 q.raw[q.tail] = e 228 q.tailGrow() 229 return true 230 } 231 232 // Alloc 在队列尾部申请一个元素的空间,申请成功返回此元素空间的地址,由于队列满申请失败返回 nil 233 func (q *Queue[E]) Alloc() (p *E) { 234 if q.len == q.cap { 235 return nil 236 } 237 p = &q.raw[q.tail] 238 q.tailGrow() 239 return 240 } 241 242 // Unshift 在队列头部添加元素,添加成功返回 true,由于队列满添加失败返回 false 243 func (q *Queue[E]) Unshift(e E) bool { 244 if q.len == q.cap { 245 return false 246 } 247 q.headGrow() 248 q.raw[q.head] = e 249 return true 250 } 251 252 // UnshiftAlloc 在队列头部申请一个元素的空间,申请成功返回此元素空间的地址,由于队列满申请失败 253 // 返回 nil 254 func (q *Queue[E]) UnshiftAlloc() *E { 255 if q.len == q.cap { 256 return nil 257 } 258 q.headGrow() 259 return &q.raw[q.head] 260 } 261 262 // Pop 移除队列尾部的一个元素,返回被移除的元素以及是否有元素被移除 263 func (q *Queue[E]) Pop() (e E, ok bool) { 264 if q.len == 0 { 265 return 266 } 267 if q.tail--; q.tail < 0 { 268 q.tail = q.cap - 1 269 } 270 e, ok = q.raw[q.tail], true 271 q.len-- 272 return 273 } 274 275 // Shift 移除队列头部的一个元素,返回被移除的元素以及是否有元素被移除 276 func (q *Queue[E]) Shift() (e E, ok bool) { 277 if q.len == 0 { 278 return 279 } 280 e, ok = q.raw[q.head], true 281 if q.head++; q.head == q.cap { 282 q.head = 0 283 } 284 q.len-- 285 return 286 } 287 288 // ShiftTo 将队列头部开始的多个元素移除到指定切片中,返回移除元素的个数 289 func (q *Queue[E]) ShiftTo(dst []E) (n int) { 290 end := len(dst) 291 if end > q.len { 292 end = q.len 293 } 294 if end += q.head; end > q.cap { 295 end -= q.cap 296 n = copy(dst, q.raw[q.head:]) 297 n += copy(dst[n:], q.raw[:end]) 298 } else { 299 n = copy(dst, q.raw[q.head:end]) 300 } 301 q.len -= n 302 q.head = end 303 return 304 } 305 306 // ShiftAll 将所有元素移除到切片中,并返回此切片 307 func (q *Queue[E]) ShiftAll() []E { 308 es := make([]E, q.len) 309 q.ShiftTo(es) 310 return es 311 } 312 313 // Set 设置指定索引位置的元素 314 func (q *Queue[E]) Set(i int, e E) { 315 q.checkIndex(i) 316 q.raw[q.rawIndex(i)] = e 317 } 318 319 // Swap 交换指定索引位置的元素 320 func (q *Queue[E]) Swap(i, j int) { 321 q.checkIndex(i) 322 q.checkIndex(j) 323 i, j = q.rawIndex(i), q.rawIndex(j) 324 q.raw[i], q.raw[j] = q.raw[j], q.raw[i] 325 } 326 327 func (q *Queue[E]) Removes(n int) int { 328 if n > q.len { 329 n = q.len 330 } 331 if q.tail -= n; q.tail < 0 { 332 q.tail += q.cap 333 } 334 q.len -= n 335 return n 336 } 337 338 func (q *Queue[E]) ShiftRemoves(n int) int { 339 if n > q.len { 340 n = q.len 341 } 342 if q.head += n; q.head >= q.cap { 343 q.head -= q.cap 344 } 345 q.len -= n 346 return n 347 } 348 349 // Clear 清空队列 350 func (q *Queue[E]) Clear() { 351 q.head = q.tail 352 q.len = 0 353 } 354 355 // Clear 重置队列。与清空队列类似,但会重置头部指针和尾部指针到队列空间的起始处 356 func (q *Queue[E]) Reset() { 357 q.head, q.tail = 0, 0 358 q.len = 0 359 }