zoukankan      html  css  js  c++  java
  • libevent中min_heap分析

    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 = 0; s->n = 0; s->a = 0; }
    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 = -1; }
    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 : 0; }
    
    int min_heap_push_(min_heap_t* s, struct event* e)
    {
        if (min_heap_reserve_(s, s->n + 1))
            return -1;
        min_heap_shift_up_(s, s->n++, e);
        return 0;
    }
    
    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 = -1;
            return e;
        }
        return 0;
    }
    
    int min_heap_elt_is_top_(const struct event *e)
    {
        return e->ev_timeout_pos.min_heap_idx == 0;
    }
    
    int min_heap_erase_(min_heap_t* s, struct event* e)
    {
        if (-1 != e->ev_timeout_pos.min_heap_idx)
        {
            struct event *last = s->p[--s->n];
            unsigned parent = (e->ev_timeout_pos.min_heap_idx - 1) / 2;
            /* 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 > 0 && 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 = -1;
            return 0;
        }
        return -1;
    }
    
    int min_heap_adjust_(min_heap_t *s, struct event *e)
    {
        if (-1 == e->ev_timeout_pos.min_heap_idx) {
            return min_heap_push_(s, e);
        } else {
            unsigned parent = (e->ev_timeout_pos.min_heap_idx - 1) / 2;
            /* 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 > 0 && 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 0;
        }
        return -1;
    }
    
    int min_heap_reserve_(min_heap_t* s, unsigned n)
    {
        if (s->a < n)
        {
            struct event** p;
            unsigned a = s->a ? s->a * 2 : 8;
            if (a < n)
                a = n;
            if (!(p = (struct event**)mm_realloc(s->p, a * sizeof *p)))
                return -1;
            s->p = p;
            s->a = a;
        }
        return 0;
    }
    //主要算法思想是填补空洞,最好找到合适的位置再安插
    void min_heap_shift_up_unconditional_(min_heap_t* s, unsigned hole_index, struct event* e)
    {
        unsigned parent = (hole_index - 1) / 2;
        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 - 1) / 2; } 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 - 1) / 2; 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 - 1) / 2; } (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 = 2 * (hole_index + 1); while (min_child <= s->n) { min_child -= min_child == s->n || min_heap_elem_greater(s->p[min_child], s->p[min_child - 1]); 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 = 2 * (hole_index + 1); } (s->p[hole_index] = e)->ev_timeout_pos.min_heap_idx = hole_index; }

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

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

  • 相关阅读:
    我对什么是真正的对象,以及软件中的对象在分析阶段、设计阶段、实现阶段的一些看法
    通过分析蜘蛛侠论坛中的版块管理功能来介绍该如何使用我开发出来的ROM框架
    蜘蛛侠论坛核心框架分析1 如何设计与实现当前访问用户
    关于DDD领域驱动设计的理论知识收集汇总
    分享一个简易的ORM框架源代码以及基于该框架开发的一个简易论坛源代码
    微软的一个开源项目Oxite学习后的感受
    AgileEAS.NET平台开发实例药店系统UI层分析
    AgileEAS.NET平台开发实例药店系统BLL层分析
    AgileEAS.NET平台开发实例药店系统DAL层解析
    AgileEAS.NET平台开发实例药店系统系统架构设计
  • 原文地址:https://www.cnblogs.com/xiangshancuizhu/p/3254228.html
Copyright © 2011-2022 走看看