package nsqd

type inFlightPqueue []*Message

func newInFlightPqueue(capacity int) inFlightPqueue {
    return make(inFlightPqueue, 0, capacity)
}

func (pq inFlightPqueue) Swap(i, j int) {
    pq[i], pq[j] = pq[j], pq[i]
    pq[i].index = i
    pq[j].index = j
}

func (pq *inFlightPqueue) Push(x *Message) {
    n := len(*pq)
    c := cap(*pq)
    if n+1 > c {
        npq := make(inFlightPqueue, n, c*2)
        copy(npq, *pq)
        *pq = npq
    }
    *pq = (*pq)[0 : n+1]
    x.index = n
    (*pq)[n] = x
    pq.up(n)
}

func (pq *inFlightPqueue) Pop() *Message {
    n := len(*pq)
    c := cap(*pq)
    pq.Swap(0, n-1)
    pq.down(0, n-1)
    if n < (c/2) && c > 25 {
        npq := make(inFlightPqueue, n, c/2)
        copy(npq, *pq)
        *pq = npq
    }
    x := (*pq)[n-1]
    x.index = -1
    *pq = (*pq)[0 : n-1]
    return x
}

func (pq *inFlightPqueue) Remove(i int) *Message {
    n := len(*pq)
    if n-1 != i {
        pq.Swap(i, n-1)
        pq.down(i, n-1)
        pq.up(i)
    }
    x := (*pq)[n-1]
    x.index = -1
    *pq = (*pq)[0 : n-1]
    return x
}

func (pq *inFlightPqueue) PeekAndShift(max int64) (*Message, int64) {
    if len(*pq) == 0 {
        return nil, 0
    }

    x := (*pq)[0]
    if x.pri > max {
        return nil, x.pri - max
    }
    pq.Pop()

    return x, 0
}

func (pq *inFlightPqueue) up(j int) {
    for {
        i := (j - 1) / 2 // parent
        if i == j || (*pq)[j].pri >= (*pq)[i].pri {
            break
        }
        pq.Swap(i, j)
        j = i
    }
}

func (pq *inFlightPqueue) down(i, n int) {
    for {
        j1 := 2*i + 1
        if j1 >= n || j1 < 0 { // j1 < 0 after int overflow
            break
        }
        j := j1 // left child
        if j2 := j1 + 1; j2 < n && (*pq)[j1].pri >= (*pq)[j2].pri {
            j = j2 // = 2*i + 2  // right child
        }
        if (*pq)[j].pri >= (*pq)[i].pri {
            break
        }
        pq.Swap(i, j)
        i = j
    }
}

in_flight_pqueue.go的更多相关文章

  1. nsq源码阅读笔记之nsqd(四)——Channel

    与Channel相关的代码主要位于nsqd/channel.go, nsqd/nsqd.go中. Channel与Topic的关系 Channel是消费者订阅特定Topic的一种抽象.对于发往Topi ...

随机推荐

  1. rails应用ajax之三:进一步完善ajax动画特效果

    本猫已经对界面放低标准很久了,但是复习了ajax之后突然发现:哇!原来世界可以这么美,这么生动鲜活的!所以本篇主要讨论下如何用ajax在rails中做一些简单的动画效果. 其实最新版的的rails中使 ...

  2. C#中使用双缓冲来避免绘制图像过程中闪烁

    自己所做项目中,在显示医学图像的界面中,当鼠标拖动图像时,不断刷新从后台获取新的图像,而整个过程就很诡异,一直闪个不停. 找到的一个可行方法是:在用户控件的构造函数中加入以下代码: SetStyle( ...

  3. JQuery系统梳理

    JQuery在前端网页开发中可以说是非常常用了,它所拥有的强大功能足以让我们完成各式各样的效果. 一.JQuery基础语法 1. 使用JQuery必须先导入jquery.x.x.x.js文件: 2. ...

  4. easyui 在编辑状态下,动态修改其他列值。

    首先是自定义了一个方法uodateColumn更新列值 /** *自定义的修改列值方法 */ $.extend($.fn.datagrid.methods, { updateColumn: funct ...

  5. volatile的适用场景

    volatile保证线程间的数据是可见的(共享的),但不保证数据同步 volatile相当于synchronized的弱实现,也就是说volatile实现了类似synchronized的语义,却又没有 ...

  6. 转:<mvc:annotation-driven/>的注解意义

    <mvc:annotation-driven /> 是一种简写形式,完全可以手动配置替代这种简写形式,简写形式可以让初学都快速应用默认配置方案.<mvc:annotation-dri ...

  7. python结巴(jieba)分词

    python结巴(jieba)分词 一.特点 1.支持三种分词模式: (1)精确模式:试图将句子最精确的切开,适合文本分析. (2)全模式:把句子中所有可以成词的词语都扫描出来,速度非常快,但是不能解 ...

  8. Mac 下实现 pyenv/virtualenv 与 Anaconda 的兼容

    http://blog.csdn.net/vencent7/article/details/76849849 自己一直用的 pyenv 和 pyenv-virtualenv 管理不同的 python ...

  9. HttpDNS的坑以及一个针对安卓不太完善的测试方案

    背景:单位因为域名劫持(具体表象是某个地区的用户ping不通域名或者因为DNS解析的ip跨网段导致访问速度很慢)需要运维经常去定位,于是提出了httpDNS方案. 想法是美好的,现实是残酷的.没引入这 ...

  10. Spring Boot【快速入门】

    Spring Boot 概述 Build Anything with Spring Boot:Spring Boot is the starting point for building all Sp ...