go 基于切片的队列实现

一、基于slice,简单实现

queue    []*wantConn

//入队
queue = append(queue, w)

//出队
v := queue[0]
queue[0] = nil
queue = queue[1:]
  • 但是这会存在问题,随着频繁的入队与出队操作,切片queue的底层数组,会有大量空间无法复用而造成浪费。除非该切片执行了扩容操作。扩容底层会新创建一个数组。

二、高阶处理方法

func (q *wantConnQueue) pushBack(w *wantConn) {
    q.tail = append(q.tail, w)   //尾部队列,入
}

func (q *wantConnQueue) popFront() *wantConn {
    if q.headPos >= len(q.head) {   //若读取位置超出头部出队列长度
        if len(q.tail) == 0 {
            return nil
        }
        // Pick up tail as new head, clear tail.
        q.head, q.headPos, q.tail = q.tail, 0, q.head[:0]
    }
    w := q.head[q.headPos]  
    q.head[q.headPos] = nil   //头部队列,出,并将该位置赋为nil
    q.headPos++   //记录当前队列移动到的位置
    return w
}

使用了两个切片head和tail;head切片用于出队操作,tail切片用于入队操作;
出队时,通过headPos读取位置,判断head切片是否消耗完,headPos > len(head) 即head每个位置为nil,则交换head与tail。
通过这种方式,Golang实现了底层数组空间的复用。

原文地址:https://www.cnblogs.com/fanzou/p/13555663.html