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. 【图片版】学习CSS网格布局

    简言 CSS网格布局(Grid)是一套二维的页面布局系统,它的出现将完全颠覆页面布局的传统方式.传统的CSS页面布局 一直不够理想.包括table布局.浮动.定位及内联块等方式,从本质上都是Hack的 ...

  2. JVM学习--(五)垃圾回收器

    上一篇我们介绍了常见的垃圾回收算法,不同的算法各有各的优缺点,在JVM中并不是单纯的使用某一种算法进行垃圾回收,而是将不同的垃圾回收算法包装在不同的垃圾回收器当中,用户可以根据自身的需求,使用不同的垃 ...

  3. onload="fixImage(this, 200, 200)"

    function fixImage(img, w, h) { var newImg = new Image(); //获得图片的原始尺寸 newImg.src = img.src; var lh; / ...

  4. oracle 数据库 date + 1 转载

    http://blog.csdn.net/yjp198713/article/details/18131871 oracle 求两个时间点直接的分钟.小时数 1.获得时间差毫秒数: select ce ...

  5. mysql史上最全的学习资料

    Ⅰ.mysql 1.mysql小基础 (1)数据类型 类型 备注 tinyint/smallint/mediumint/int/bigint 1B/2B/3B/4B/8B float/double 单 ...

  6. Python字符串全解

    1.字符串大小写转换 def strChange(): str = "niuXinLong@163.com" print("原字符串:" + str) prin ...

  7. Android框架之Volley与Glide

    PS:在看到这个题目的同时,你们估计会想,Volley与Glide怎么拿来一块说呢,他们虽然不是一个框架,但有着相同功能,那就是图片处理方面.首先我们先来看一下什么volley,又什么是glide. ...

  8. AUTOSAR - 标准文档下载

    官网 https://www.autosar.org/ 文档分类 按功能分 按类型分 CLASSIC PLATFORM The AUTOSAR Classic Platform architectur ...

  9. Scrapy爬虫框架补充内容三(代理及其基本原理介绍)

    前言:(本文参考维基百科及百度百科所写) 当我们使用爬虫抓取数据时,有时会产生错误比如:突然跳出来了403 Forbidden 或者网页上出现以下提示:您的ip访问频率太高 或者时不时跳出一个验证码需 ...

  10. Web开发环境搭建 Eclipse-Java EE 篇

    Web开发环境搭建 Eclipse-Java EE 篇 [原创内容,转载注名出处] 1. 下载和安装 1.1 下载JDK 在Java官方网站下载最新版本的 Java SE:  http://www.o ...