自定义队列和堆

自己写了一个对队列和堆的处理,下面记录一下。

队列

package queue

package queue

import "sync"

type queue []interface{}

type Queue struct {
    queue queue
    mutex sync.Mutex
}


func (q Queue) Len() int           { return len(q.queue) }

func (q *Queue) Push(x interface{}) {
    q.mutex.Lock()
    defer q.mutex.Unlock()
    q.queue = append(q.queue, x)
}

func (q *Queue) Pull() interface{} {
    q.mutex.Lock()
    defer q.mutex.Unlock()
    old := q.queue
    n := len(old)
    if n==0 {
        return nil
    }
    x := old[0]
    q.queue = old[1:]
    return x
}

别人写的一个优秀的队列

package queue
import (
    "runtime"
    "sync/atomic"
)

type esCache struct {
    value interface{}
    mark  bool
}

// lock free queue
type EsQueue struct {
    capaciity uint32
    capMod    uint32
    putPos    uint32
    getPos    uint32
    cache     []esCache
}

func NewQueue(capaciity uint32) *EsQueue {
    q := new(EsQueue)
    q.capaciity = minQuantity(capaciity)
    q.capMod = q.capaciity - 1
    q.cache = make([]esCache, q.capaciity)
    return q
}

func (q *EsQueue) Capaciity() uint32 {
    return q.capaciity
}

func (q *EsQueue) Quantity() uint32 {
    var putPos, getPos uint32
    var quantity uint32
    getPos = q.getPos
    putPos = q.putPos

    if putPos >= getPos {
        quantity = putPos - getPos
    } else {
        quantity = q.capMod + putPos - getPos
    }

    return quantity
}

// put queue functions
func (q *EsQueue) Put(val interface{}) (ok bool, quantity uint32) {
    var putPos, putPosNew, getPos, posCnt uint32
    var cache *esCache
    capMod := q.capMod
    for {
        getPos = q.getPos
        putPos = q.putPos

        if putPos >= getPos {
            posCnt = putPos - getPos
        } else {
            posCnt = capMod + putPos - getPos
        }

        if posCnt >= capMod {
            runtime.Gosched()
            return false, posCnt
        }

        putPosNew = putPos + 1
        if atomic.CompareAndSwapUint32(&q.putPos, putPos, putPosNew) {
            break
        } else {
            runtime.Gosched()
        }
    }

    cache = &q.cache[putPosNew&capMod]

    for {
        if !cache.mark {
            cache.value = val
            cache.mark = true
            return true, posCnt + 1
        } else {
            runtime.Gosched()
        }
    }
}

// get queue functions
func (q *EsQueue) Get() (val interface{}, ok bool, quantity uint32) {
    var putPos, getPos, getPosNew, posCnt uint32
    var cache *esCache
    capMod := q.capMod
    for {
        putPos = q.putPos
        getPos = q.getPos

        if putPos >= getPos {
            posCnt = putPos - getPos
        } else {
            posCnt = capMod + putPos - getPos
        }

        if posCnt < 1 {
            runtime.Gosched()
            return nil, false, posCnt
        }

        getPosNew = getPos + 1
        if atomic.CompareAndSwapUint32(&q.getPos, getPos, getPosNew) {
            break
        } else {
            runtime.Gosched()
        }
    }

    cache = &q.cache[getPosNew&capMod]

    for {
        if cache.mark {
            val = cache.value
            cache.mark = false
            return val, true, posCnt - 1
        } else {
            runtime.Gosched()
        }
    }
}

// round 到最近的2的倍数
func minQuantity(v uint32) uint32 {
    v--
    v |= v >> 1
    v |= v >> 2
    v |= v >> 4
    v |= v >> 8
    v |= v >> 16
    v++
    return v
}

package heap

import "sync"

type heap []interface{}
type Heap struct {
    heap heap
    mutex sync.Mutex
}

func (h Heap) Len() int           { return len(h.heap) }

func (h *Heap) Insert(x interface{}) {
    h.mutex.Lock()
    defer h.mutex.Unlock()
    h.heap= append(h.heap, x)
}

func (h *Heap) Get() interface{} {
    h.mutex.Lock()
    defer h.mutex.Unlock()
    old := h.heap
    n := len(old)
    x := old[n-1]
    h.heap = old[0 : n-1]
    return x
}
func (h *Heap) Delete()  {
    h.mutex.Lock()
    defer h.mutex.Unlock()
    old := h.heap
    n := len(old)
    h.heap = old[0 : n-1]
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 179,276评论 25 708
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,678评论 19 139
  • 这个中秋,过得,不像中秋了。也许这很正常,我们都会走着走着,就散了。就像这个中秋,哪怕在同一所学校,在这个特殊的...
    小溪流在唱歌阅读 235评论 0 0
  • 写在前面 阿德勒心理学的精华。《被讨厌的勇气》、《幸福的勇气》两本书的精华内容读书笔记。共15条建议,分上下篇整理...
    素0908阅读 229评论 0 0
  • 望着窗外那明亮的灯光,想着独自在外打拼的你,久久不能入睡。 今年6月,于你于我,都太过特殊——你,高考;我,中考。...
    阿喵同鞋阅读 239评论 0 0

友情链接更多精彩内容