typedef struct min_heap
{
struct event** p;
unsigned n, a;
} min_heap_t; static inline void min_heap_ctor_(min_heap_t* s);
static inline void min_heap_dtor_(min_heap_t* s);
static inline void min_heap_elem_init_(struct event* e);
static inline int min_heap_elt_is_top_(const struct event *e);
static inline int min_heap_empty_(min_heap_t* s);
static inline unsigned min_heap_size_(min_heap_t* s);
static inline struct event* min_heap_top_(min_heap_t* s);
static inline int min_heap_reserve_(min_heap_t* s, unsigned n);
static inline int min_heap_push_(min_heap_t* s, struct event* e);
static inline struct event* min_heap_pop_(min_heap_t* s);
static inline int min_heap_adjust_(min_heap_t *s, struct event* e);
static inline int min_heap_erase_(min_heap_t* s, struct event* e);
static inline void min_heap_shift_up_(min_heap_t* s, unsigned hole_index, struct event* e);
static inline void min_heap_shift_up_unconditional_(min_heap_t* s, unsigned hole_index, struct event* e);
static inline void min_heap_shift_down_(min_heap_t* s, unsigned hole_index, struct event* e); #define min_heap_elem_greater(a, b) \
(evutil_timercmp(&(a)->ev_timeout, &(b)->ev_timeout, >)) void min_heap_ctor_(min_heap_t* s) { s->p = ; s->n = ; s->a = ; }
void min_heap_dtor_(min_heap_t* s) { if (s->p) mm_free(s->p); }
void min_heap_elem_init_(struct event* e) { e->ev_timeout_pos.min_heap_idx = -; }
int min_heap_empty_(min_heap_t* s) { return 0u == s->n; }
unsigned min_heap_size_(min_heap_t* s) { return s->n; }
struct event* min_heap_top_(min_heap_t* s) { return s->n ? *s->p : ; } int min_heap_push_(min_heap_t* s, struct event* e)
{
if (min_heap_reserve_(s, s->n + ))
return -;
min_heap_shift_up_(s, s->n++, e);
return ;
} struct event* min_heap_pop_(min_heap_t* s)
{
if (s->n)
{
struct event* e = *s->p;
min_heap_shift_down_(s, 0u, s->p[--s->n]);
e->ev_timeout_pos.min_heap_idx = -;
return e;
}
return ;
} int min_heap_elt_is_top_(const struct event *e)
{
return e->ev_timeout_pos.min_heap_idx == ;
} int min_heap_erase_(min_heap_t* s, struct event* e)
{
if (- != e->ev_timeout_pos.min_heap_idx)
{
struct event *last = s->p[--s->n];
unsigned parent = (e->ev_timeout_pos.min_heap_idx - ) / ;
/* we replace e with the last element in the heap. We might need to
shift it upward if it is less than its parent, or downward if it is
greater than one or both its children. Since the children are known
to be less than the parent, it can't need to shift both up and
down. */
if (e->ev_timeout_pos.min_heap_idx > && min_heap_elem_greater(s->p[parent], last))
min_heap_shift_up_unconditional_(s, e->ev_timeout_pos.min_heap_idx, last);
else
min_heap_shift_down_(s, e->ev_timeout_pos.min_heap_idx, last);
e->ev_timeout_pos.min_heap_idx = -;
return ;
}
return -;
} int min_heap_adjust_(min_heap_t *s, struct event *e)
{
if (- == e->ev_timeout_pos.min_heap_idx) {
return min_heap_push_(s, e);
} else {
unsigned parent = (e->ev_timeout_pos.min_heap_idx - ) / ;
/* The position of e has changed; we shift it up or down
* as needed. We can't need to do both. */
if (e->ev_timeout_pos.min_heap_idx > && min_heap_elem_greater(s->p[parent], e))
min_heap_shift_up_unconditional_(s, e->ev_timeout_pos.min_heap_idx, e);
else
min_heap_shift_down_(s, e->ev_timeout_pos.min_heap_idx, e);
return ;
}
return -;
} int min_heap_reserve_(min_heap_t* s, unsigned n)
{
if (s->a < n)
{
struct event** p;
unsigned a = s->a ? s->a * : ;
if (a < n)
a = n;
if (!(p = (struct event**)mm_realloc(s->p, a * sizeof *p)))
return -;
s->p = p;
s->a = a;
}
return ;
}
//主要算法思想是填补空洞,最好找到合适的位置再安插
void min_heap_shift_up_unconditional_(min_heap_t* s, unsigned hole_index, struct event* e)
{
unsigned parent = (hole_index - ) / ;
do
{
//如果父节点>value[hole_index],父节点下沉
(s->p[hole_index] = s->p[parent])->ev_timeout_pos.min_heap_idx = hole_index;
//hole_index替换为parent
hole_index = parent;
parent = (hole_index - ) / ;
} while (hole_index && min_heap_elem_greater(s->p[parent], e));
(s->p[hole_index] = e)->ev_timeout_pos.min_heap_idx = hole_index;
} void min_heap_shift_up_(min_heap_t* s, unsigned hole_index, struct event* e)
{
unsigned parent = (hole_index - ) / ;
while (hole_index && min_heap_elem_greater(s->p[parent], e))
{
(s->p[hole_index] = s->p[parent])->ev_timeout_pos.min_heap_idx = hole_index;
hole_index = parent;
parent = (hole_index - ) / ;
}
(s->p[hole_index] = e)->ev_timeout_pos.min_heap_idx = hole_index;
} void min_heap_shift_down_(min_heap_t* s, unsigned hole_index, struct event* e)
{
unsigned min_child = * (hole_index + );
while (min_child <= s->n)
{
min_child -= min_child == s->n || min_heap_elem_greater(s->p[min_child], s->p[min_child - ]);
if (!(min_heap_elem_greater(e, s->p[min_child])))
break;
(s->p[hole_index] = s->p[min_child])->ev_timeout_pos.min_heap_idx = hole_index;
hole_index = min_child;
min_child = * (hole_index + );
}
(s->p[hole_index] = e)->ev_timeout_pos.min_heap_idx = hole_index;
}

暂时记录下,明天继续看,figthing!

实现的很清晰,不得不佩服作者清晰的思维呀。菜鸟学习ing!

libevent中min_heap分析的更多相关文章

  1. libevent中数据缓冲区buffer分析

    很多时候为了应对数据IO的"慢"或者其他原因都需要使用数据缓冲区.对于数据缓冲,我们不陌生,但是对于如何实现这个缓冲区,相信很多时候大家都没有考虑过.今天就通过分析libevent ...

  2. 【转】libevent源码分析

    libevent源码分析 转自:http://www.cnblogs.com/hustcat/archive/2010/08/31/1814022.html 这两天没事,看了一下Memcached和l ...

  3. libevent 网络IO分析

    libevent 网络IO分析 Table of Contents 1. 简介 2. 简单使用与入门 2.1. 定时器-timeout 超时回调 2.2. 信号事件 2.3. 读取 socket 3. ...

  4. libevent源码分析

    这两天没事,看了一下Memcached和libevent的源码,做个小总结. 1.入门 1.1.概述Libevent是一个用于开发可扩展性网络服务器的基于事件驱动(event-driven)模型的网络 ...

  5. libevent源码分析二--timeout事件响应

    libevent不仅支持io事件,同时还支持timeout事件与signal事件,这篇文件将分析libevent是如何组织timeout事件以及如何响应timeout事件. 1.  min_heap ...

  6. libevent 源码分析

    1,前言 Libevent是一个轻量级的开源高性能网络库,使用者众多,研究者更甚,相关文章也不少.写这一系列文章的用意在于,一则分享心得:二则对libevent代码和设计思想做系统的.更深层次的分析, ...

  7. libevent源码分析:bufferevent

    struct bufferevent定义在文件bufferevent_struct.h中. /** Shared implementation of a bufferevent. This type ...

  8. Libevent源码分析(一):最小堆

    Libevent中的timeout事件是使用最小堆来管理维护的.代码位于<minheap-internal.h>. 看函数命名和代码风格应该是一个C++程序员,函数名都挺好懂的,只是下面这 ...

  9. Libevent源码分析 (1) hello-world

    Libevent源码分析 (1) hello-world ⑨月份接触了久闻大名的libevent,当时想读读源码,可是由于事情比较多一直没有时间,现在手头的东西基本告一段落了,我准备读读libeven ...

随机推荐

  1. 微信小程序 this.data与this.setData

    一.摘要 小程序中我们会经常使用到this.data与this.setData.其中this.data是用来获取页面data对象的,而this.setData是用来更新界面的.那么他们之间的区别与联系 ...

  2. Spark Strcutured Streaming中使用Dataset的groupBy agg 与 join 示例(java api)

    Dataset的groupBy agg示例 Dataset<Row> resultDs = dsParsed .groupBy("enodeb_id", "e ...

  3. IncrediBuild 2.40 过期时间

    IncrediBuild 2.40的License有2个文件CoordLicense.dat和AgentLicense.dat,分别位于Coordinator和Agent安装目录下,这两个文件都是RS ...

  4. LXC 容器集chroot使用说明

    1.1 LXC是什么? 1.1.1 关于LXC LXC,其名称来自Linux软件容器(Linux Containers)的缩写,一种操作系统层虚拟化(Operating system–level vi ...

  5. CAD中批量打印

    同事在网上找各种软件来实现CAD图的批量打印,总是问题多多.于是,我想到一个更方便的解决方法,即只要我将一个打印出来,然后就可以用批量处理来实现. 1.在CAD中输入plot命令(或快捷键Ctrl+P ...

  6. 微信小程序 - 浮层引导(示例)

    更新日期: 2019/3/15:首次发布,具体请下载:demo.

  7. 忘记webogic管理控制台密码

    cd /user_projects/domains/base_domain/security cp DefaultAuthenticatorInit.ldift DefaultAuthenticato ...

  8. JAVA WEB 解决编码问题的filter

    最近使用Springmvc,GET传输参数的时候,经常出错误,下面介绍添加一个Filter的方法,可以解决这个问题.既支持POST方式也支持GET方式. 首先写一个Filter package com ...

  9. dynamicpdf文件打印

    function printForm(PD_ID, sREP_ID) { var data = { id: '#SID#', t: '' + new Date(), PrintAction: 'Pri ...

  10. flume-elasticsearch-sink indexName