forked from MysteryOfPanda/leactor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
lea_heap.c
123 lines (112 loc) · 3.13 KB
/
lea_heap.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include "lea_heap.h"
#include "event_lea.h"
/*
*/
/*
static inline int min_heap_push_(min_heap_t *, event_t *);
static inline int min_heap_reserve_(min_heap_t *, unsigned);
static inline void min_heap_shift_up_(min_heap_t *, unsigned, event_t *);
static inline void min_heap_shift_down_(min_heap_t *, unsigned, event_t *);
*/
#define min_heap_elem_greater(a, b) \
(lt_time_a_sub_b((a)->endtime, (b)->endtime))
void
min_heap_constructor_(min_heap_t* s)
{
s->p = 0;
s->n = 0;
s->a = 0;
}
void
min_heap_elem_init_(event_t *ev)
{
ev->min_heap_idx = -1;
return;
}
int
min_heap_push_(min_heap_t* s, event_t *e)
{
if (min_heap_reserve_(s, s->n + 1))
return -1;
min_heap_shift_up_(s, s->n++, e);
return 0;
}
event_t *
min_heap_pop_(min_heap_t *s)
{
if (s->n) {
event_t *e = *s->p;
min_heap_shift_down_(s, 0u, s->p[--s->n]);
e->min_heap_idx = -1;
return e;
} else {
return 0;
}
}
void
min_heap_shift_up_(min_heap_t *s, unsigned hole_index, event_t *e)
{
unsigned parent = (hole_index - 1) / 2;
while (hole_index && min_heap_elem_greater(s->p[parent], e)) {//min time on time
s->p[hole_index] = s->p[parent];
s->p[hole_index]->min_heap_idx = hole_index;//TODO ev_timeout_pos???
hole_index = parent;
parent = (hole_index - 1) / 2;
}
s->p[hole_index] = e;
s->p[hole_index]->min_heap_idx = hole_index;
}
void
min_heap_shift_up_unconditional_(min_heap_t* s, unsigned hole_index, event_t *e)
{
unsigned parent = (hole_index - 1) / 2;
do {
s->p[hole_index] = s->p[parent];
s->p[hole_index]->min_heap_idx = hole_index;
hole_index = parent;
parent = (hole_index - 1) / 2;
} while (hole_index && min_heap_elem_greater(s->p[parent], e));
s->p[hole_index] = e;
s->p[hole_index]->min_heap_idx = hole_index;
}
void
min_heap_shift_down_(min_heap_t * s, unsigned hole_index, event_t *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];
s->p[hole_index]->min_heap_idx = hole_index;
hole_index = min_child;
min_child = 2 * (hole_index + 1);
}
s->p[hole_index] = e;
s->p[hole_index]->min_heap_idx = hole_index;
}
int min_heap_reserve_(min_heap_t *s, unsigned n)
{
if (s->a < n) {
event_t **p;
unsigned a = s->a? s->a*2 : 8;
if (a < n) { a = n; }
if ( !(p = realloc(s->p, a* sizeof *p)) ) { return -1; }
s->p = p;
s->a = a;
}
return 0;
}
int min_heap_erase_(min_heap_t *s, event_t *e)
{
// if (e->min_heap_idx != -1) {
event_t *last = s->p[--s->n];
unsigned parent = (e->min_heap_idx - 1 ) / 2;
if (e->min_heap_idx > 0 && min_heap_elem_greater(s->p[parent], last) ) {
min_heap_shift_up_unconditional_(s, e->min_heap_idx, last);
} else {
min_heap_shift_down_(s, e->min_heap_idx, last);
}
e->min_heap_idx = -1;
return 0;
}