libevent中min_heap分析

时间:2022-06-18 20:36:52
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源码分析&lpar;一&rpar;:最小堆

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

  9. Libevent源码分析 &lpar;1&rpar; hello-world

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

随机推荐

  1. WebView返回时设置Title

    private TextView mWebTitle; private com.tencent.smtt.sdk.WebView mX5Web; ......... if (mX5Web.canGoB ...

  2. spring关于urlpattern

    视图解析器(ViewResolver)注册*调度器定制处理器jsp页面搭建springmvc.xml配置效果图第一个案例提升----视图解析器关于urlpattern说法最好配成*.do 不能配成/ ...

  3. linux-软连接

    ln -s /opt/lampp/bin/mysql(绝对路径) /usr/local/bin(软连接目录或者文件) 如果不愿意配置环境变脸可以直接创建env查出的路径下建连接

  4. Android使用Webview加载网页

    安卓使用Webview来加载和显示网页内容,首先在layout文件中定义Webview <?xml version="1.0" encoding="utf-8&qu ...

  5. 解决GitHub未配置SSH key提示错误信息

    git push -u origin master Permission denied (publickey). fatal: Could not read from remote repositor ...

  6. swift闭包中解决循环引用的问题

    swift中可以通过三种方法解决循环引用的问题 利用类似oc方法解决循环引用weak var weakSelf = self weak var weakSelf = self loadData = { ...

  7. 使用Socket对序列化数据进行传输&lpar;基于C&num;&rpar;

    客户端代码 [Serializable] // 表示该类可以被序列化 class Person{ public string name; public void HI() { Debug.Log(na ...

  8. ios中input获取焦点时的问题

    1.获取焦点时,input会变大 解决办法是:font-size设置为32px以上 还有就是要在header里面加这一行代码:<meta name="viewport" co ...

  9. 将数据库从Oracle迁移到SQL Server

    参考链接:http://www.360doc.com/content/15/0310/14/9260775_454038517.shtml

  10. wordpress学习(五)----插件

    wordpress加载顺序:首先加载插件,再加载主题中的functions.php,初始化一些数据之类的,最后加载模板了!!! update_option("hc_copyright_tex ...