1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/third_party/libevent/minheap-internal.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,160 @@ 1.4 +/* 1.5 + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson 1.6 + * 1.7 + * Copyright (c) 2006 Maxim Yegorushkin <maxim.yegorushkin@gmail.com> 1.8 + * 1.9 + * Redistribution and use in source and binary forms, with or without 1.10 + * modification, are permitted provided that the following conditions 1.11 + * are met: 1.12 + * 1. Redistributions of source code must retain the above copyright 1.13 + * notice, this list of conditions and the following disclaimer. 1.14 + * 2. Redistributions in binary form must reproduce the above copyright 1.15 + * notice, this list of conditions and the following disclaimer in the 1.16 + * documentation and/or other materials provided with the distribution. 1.17 + * 3. The name of the author may not be used to endorse or promote products 1.18 + * derived from this software without specific prior written permission. 1.19 + * 1.20 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1.21 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1.22 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1.23 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1.24 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 1.25 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.26 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.27 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.28 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 1.29 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.30 + */ 1.31 +#ifndef _MIN_HEAP_H_ 1.32 +#define _MIN_HEAP_H_ 1.33 + 1.34 +#include "event2/event-config.h" 1.35 +#include "event2/event.h" 1.36 +#include "event2/event_struct.h" 1.37 +#include "event2/util.h" 1.38 +#include "util-internal.h" 1.39 +#include "mm-internal.h" 1.40 + 1.41 +typedef struct min_heap 1.42 +{ 1.43 + struct event** p; 1.44 + unsigned n, a; 1.45 +} min_heap_t; 1.46 + 1.47 +static inline void min_heap_ctor(min_heap_t* s); 1.48 +static inline void min_heap_dtor(min_heap_t* s); 1.49 +static inline void min_heap_elem_init(struct event* e); 1.50 +static inline int min_heap_elt_is_top(const struct event *e); 1.51 +static inline int min_heap_elem_greater(struct event *a, struct event *b); 1.52 +static inline int min_heap_empty(min_heap_t* s); 1.53 +static inline unsigned min_heap_size(min_heap_t* s); 1.54 +static inline struct event* min_heap_top(min_heap_t* s); 1.55 +static inline int min_heap_reserve(min_heap_t* s, unsigned n); 1.56 +static inline int min_heap_push(min_heap_t* s, struct event* e); 1.57 +static inline struct event* min_heap_pop(min_heap_t* s); 1.58 +static inline int min_heap_erase(min_heap_t* s, struct event* e); 1.59 +static inline void min_heap_shift_up_(min_heap_t* s, unsigned hole_index, struct event* e); 1.60 +static inline void min_heap_shift_down_(min_heap_t* s, unsigned hole_index, struct event* e); 1.61 + 1.62 +int min_heap_elem_greater(struct event *a, struct event *b) 1.63 +{ 1.64 + return evutil_timercmp(&a->ev_timeout, &b->ev_timeout, >); 1.65 +} 1.66 + 1.67 +void min_heap_ctor(min_heap_t* s) { s->p = 0; s->n = 0; s->a = 0; } 1.68 +void min_heap_dtor(min_heap_t* s) { if (s->p) mm_free(s->p); } 1.69 +void min_heap_elem_init(struct event* e) { e->ev_timeout_pos.min_heap_idx = -1; } 1.70 +int min_heap_empty(min_heap_t* s) { return 0u == s->n; } 1.71 +unsigned min_heap_size(min_heap_t* s) { return s->n; } 1.72 +struct event* min_heap_top(min_heap_t* s) { return s->n ? *s->p : 0; } 1.73 + 1.74 +int min_heap_push(min_heap_t* s, struct event* e) 1.75 +{ 1.76 + if (min_heap_reserve(s, s->n + 1)) 1.77 + return -1; 1.78 + min_heap_shift_up_(s, s->n++, e); 1.79 + return 0; 1.80 +} 1.81 + 1.82 +struct event* min_heap_pop(min_heap_t* s) 1.83 +{ 1.84 + if (s->n) 1.85 + { 1.86 + struct event* e = *s->p; 1.87 + min_heap_shift_down_(s, 0u, s->p[--s->n]); 1.88 + e->ev_timeout_pos.min_heap_idx = -1; 1.89 + return e; 1.90 + } 1.91 + return 0; 1.92 +} 1.93 + 1.94 +int min_heap_elt_is_top(const struct event *e) 1.95 +{ 1.96 + return e->ev_timeout_pos.min_heap_idx == 0; 1.97 +} 1.98 + 1.99 +int min_heap_erase(min_heap_t* s, struct event* e) 1.100 +{ 1.101 + if (-1 != e->ev_timeout_pos.min_heap_idx) 1.102 + { 1.103 + struct event *last = s->p[--s->n]; 1.104 + unsigned parent = (e->ev_timeout_pos.min_heap_idx - 1) / 2; 1.105 + /* we replace e with the last element in the heap. We might need to 1.106 + shift it upward if it is less than its parent, or downward if it is 1.107 + greater than one or both its children. Since the children are known 1.108 + to be less than the parent, it can't need to shift both up and 1.109 + down. */ 1.110 + if (e->ev_timeout_pos.min_heap_idx > 0 && min_heap_elem_greater(s->p[parent], last)) 1.111 + min_heap_shift_up_(s, e->ev_timeout_pos.min_heap_idx, last); 1.112 + else 1.113 + min_heap_shift_down_(s, e->ev_timeout_pos.min_heap_idx, last); 1.114 + e->ev_timeout_pos.min_heap_idx = -1; 1.115 + return 0; 1.116 + } 1.117 + return -1; 1.118 +} 1.119 + 1.120 +int min_heap_reserve(min_heap_t* s, unsigned n) 1.121 +{ 1.122 + if (s->a < n) 1.123 + { 1.124 + struct event** p; 1.125 + unsigned a = s->a ? s->a * 2 : 8; 1.126 + if (a < n) 1.127 + a = n; 1.128 + if (!(p = (struct event**)mm_realloc(s->p, a * sizeof *p))) 1.129 + return -1; 1.130 + s->p = p; 1.131 + s->a = a; 1.132 + } 1.133 + return 0; 1.134 +} 1.135 + 1.136 +void min_heap_shift_up_(min_heap_t* s, unsigned hole_index, struct event* e) 1.137 +{ 1.138 + unsigned parent = (hole_index - 1) / 2; 1.139 + while (hole_index && min_heap_elem_greater(s->p[parent], e)) 1.140 + { 1.141 + (s->p[hole_index] = s->p[parent])->ev_timeout_pos.min_heap_idx = hole_index; 1.142 + hole_index = parent; 1.143 + parent = (hole_index - 1) / 2; 1.144 + } 1.145 + (s->p[hole_index] = e)->ev_timeout_pos.min_heap_idx = hole_index; 1.146 +} 1.147 + 1.148 +void min_heap_shift_down_(min_heap_t* s, unsigned hole_index, struct event* e) 1.149 +{ 1.150 + unsigned min_child = 2 * (hole_index + 1); 1.151 + while (min_child <= s->n) 1.152 + { 1.153 + min_child -= min_child == s->n || min_heap_elem_greater(s->p[min_child], s->p[min_child - 1]); 1.154 + if (!(min_heap_elem_greater(e, s->p[min_child]))) 1.155 + break; 1.156 + (s->p[hole_index] = s->p[min_child])->ev_timeout_pos.min_heap_idx = hole_index; 1.157 + hole_index = min_child; 1.158 + min_child = 2 * (hole_index + 1); 1.159 + } 1.160 + (s->p[hole_index] = e)->ev_timeout_pos.min_heap_idx = hole_index; 1.161 +} 1.162 + 1.163 +#endif /* _MIN_HEAP_H_ */