美文网首页
自定义队列和堆

自定义队列和堆

作者: 吃猫的鱼0 | 来源:发表于2018-02-27 16:27 被阅读0次

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

队列

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]
}

相关文章

  • 自定义队列和堆

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

  • NSOperation

    1.1、NSOperationQueue为我们提供两种队列,主队列和自定义队列,主队列运行在主线程上,自定义队列运...

  • NSOperationQueue&NSOperation

    NSOperationQueue有两种不同类型的队列:主队列和自定义队列。主队列运行在主线程之上,而自定义队列在后...

  • 动画 | 什么是二叉堆?

    二叉堆的解释 (动态选择优先级最高的任务执行) 堆,又称为优先队列。虽然名为优先队列,但堆并不是队列。堆和队列是两...

  • 堆和优先队列

    堆又称为优先队列,其通常包括至少两种操作:入队操作和出队操作。 普通队列与优先队列 普通队列:先进先出,后进后出优...

  • 堆、栈和队列

    栈(stack)又叫堆栈是一种容器,可存入数据元素、访问元素、删除元素,它的特点在于只能允许在容器的一端进行加入数...

  • 一步一步学习数据结构和算法 (三) 堆和堆排序

    堆和堆排序 堆排序 堆和优先队列 普通队列: 先进先出; 后进后出. 优先队列: 出队顺序和入队顺序无关, 和优先...

  • 5 堆和优先队列

    定义 优先队列:priority queue 取出元素的顺序是依据元素的优先权大小,而不是元素进入队列的先后顺序两...

  • iOS堆、栈和队列

    堆 堆是一种经过排序的树形数据结构,每个节点都有一个值,通常我们所说的堆的数据结构是指二叉树。所以堆在数据结构中通...

  • 【二】优先队列和堆

    堆 ----待补充--- java中的优先队列 PriorityQueue为java中的优先队列((a,b)->b...

网友评论

      本文标题:自定义队列和堆

      本文链接:https://www.haomeiwen.com/subject/kxjmxftx.html