ipc/chromium/src/third_party/libevent/minheap-internal.h

changeset 0
6474c204b198
     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_ */

mercurial