github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/znet/limiter/queue.go (about)

     1  package limiter
     2  
     3  import (
     4  	"errors"
     5  	"sync"
     6  	"time"
     7  )
     8  
     9  type circleQueue struct {
    10  	slice   []int64
    11  	maxSize int
    12  	head    int
    13  	tail    int
    14  	sync.RWMutex
    15  }
    16  
    17  // newCircleQueue Initialize ring queue
    18  func newCircleQueue(size int) *circleQueue {
    19  	var c circleQueue
    20  	c.maxSize = size + 1
    21  	c.slice = make([]int64, c.maxSize)
    22  	return &c
    23  }
    24  
    25  func (c *circleQueue) push(val int64) (err error) {
    26  	if c.isFull() {
    27  		return errors.New("queue is full")
    28  	}
    29  	c.slice[c.tail] = val
    30  	c.tail = (c.tail + 1) % c.maxSize
    31  	return
    32  }
    33  
    34  func (c *circleQueue) pop() (val int64, err error) {
    35  	if c.isEmpty() {
    36  		return 0, errors.New("queue is empty")
    37  	}
    38  	c.Lock()
    39  	defer c.Unlock()
    40  	val = c.slice[c.head]
    41  	c.head = (c.head + 1) % c.maxSize
    42  	return
    43  }
    44  
    45  func (c *circleQueue) isFull() bool {
    46  	return (c.tail+1)%c.maxSize == c.head
    47  }
    48  
    49  func (c *circleQueue) isEmpty() bool {
    50  	return c.tail == c.head
    51  }
    52  
    53  func (c *circleQueue) usedSize() int {
    54  	c.RLock()
    55  	defer c.RUnlock()
    56  	return (c.tail + c.maxSize - c.head) % c.maxSize
    57  }
    58  
    59  func (c *circleQueue) unUsedSize() int {
    60  	return c.maxSize - 1 - c.usedSize()
    61  }
    62  
    63  func (c *circleQueue) size() int {
    64  	return c.maxSize - 1
    65  }
    66  
    67  func (c *circleQueue) deleteExpired() {
    68  	now := time.Now().UnixNano()
    69  	size := c.usedSize()
    70  	if size == 0 {
    71  		return
    72  	}
    73  	for i := 0; i < size; i++ {
    74  		if now > c.slice[c.head] {
    75  			_, _ = c.pop()
    76  		} else {
    77  			return
    78  		}
    79  	}
    80  }