utils/cycle_queue.go (70 lines of code) (raw):

package utils import "sync" type CycleQueue struct { data []interface{} //存储空间 front int //前指针,前指针负责弹出数据移动 rear int //尾指针,后指针负责添加数据移动 cap int //设置切片最大容量 lock sync.Mutex } // NewCycleQueue init Queue func NewCycleQueue(cap int) *CycleQueue { cap++ // 因为有一个元素用不了 return &CycleQueue{ data: make([]interface{}, cap), cap: cap, front: 0, rear: 0, } } func (q *CycleQueue) Freeze() { q.lock.Lock() } func (q *CycleQueue) Unfreeze() { q.lock.Unlock() } // Length 因为是循环队列, 后指针减去前指针 加上最大值, 然后与最大值 取余 func (q *CycleQueue) Length() int { return (q.rear - q.front + q.cap) % q.cap } // Push 入队操作 // 判断队列是否队满,队满则不允许添加数据 func (q *CycleQueue) Push(data interface{}) bool { q.lock.Lock() defer q.lock.Unlock() // check queue is full if (q.rear+1)%q.cap == q.front { //队列已满时,不执行入队操作 return false } q.data[q.rear] = data //将元素放入队列尾部 q.rear = (q.rear + 1) % q.cap //尾部元素指向下一个空间位置,取模运算保证了索引不越界(余数一定小于除数) return true } // Pop 出队操作 需要考虑: 队空没有数据返回了 func (q *CycleQueue) Pop() interface{} { if q.rear == q.front { return nil } data := q.data[q.front] q.data[q.front] = nil q.front = (q.front + 1) % q.cap return data } func (q *CycleQueue) Peek() interface{} { if q.rear == q.front { return nil } return q.data[q.front] } func (q *CycleQueue) Tail() interface{} { if q.rear == q.front { return nil } return q.data[q.rear] } func (q *CycleQueue) IsFull() bool { if (q.rear+1)%q.cap == q.front { return true } return false } func (q *CycleQueue) IsEmpty() bool { if q.front == q.rear { return true } return false }