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  }