summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2008-10-29 23:24:23 -0400
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2008-10-29 23:24:23 -0400
commit65ca5c2129f50228ce63f2df5ebe79f963e9b4be (patch)
treea983539ffd7b8433f9167775798fed03ff60e54c /include
parentb1c9e03d3c0a7eaf584b62454b941e06e2c2f5fa (diff)
factor out common code
Diffstat (limited to 'include')
-rw-r--r--include/eheap.h12
-rw-r--r--include/heap.h379
-rw-r--r--include/load.h6
3 files changed, 397 insertions, 0 deletions
diff --git a/include/eheap.h b/include/eheap.h
new file mode 100644
index 0000000..323fa30
--- /dev/null
+++ b/include/eheap.h
@@ -0,0 +1,12 @@
1#ifndef EHEAP_H
2#define EHEAP_H
3
4#include <limits.h>
5#include "heap.h"
6
7int earlier_event(struct heap_node* _a, struct heap_node* _b);
8
9struct heap* heapify_events(struct st_event_record *ev, unsigned int count);
10
11
12#endif
diff --git a/include/heap.h b/include/heap.h
new file mode 100644
index 0000000..e46b0eb
--- /dev/null
+++ b/include/heap.h
@@ -0,0 +1,379 @@
1/* heap.h -- Binomial Heaps
2 *
3 * Copyright (c) 2008, Bjoern B. Brandenburg <bbb [at] cs.unc.edu>
4 *
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * * Neither the name of the University of North Carolina nor the
15 * names of its contributors may be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY COPYRIGHT OWNER AND CONTRIBUTERS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTERS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#ifndef HEAP_H
32#define HEAP_H
33
34#define NOT_IN_HEAP UINT_MAX
35
36struct heap_node {
37 struct heap_node* parent;
38 struct heap_node* next;
39 struct heap_node* child;
40
41 unsigned int degree;
42 void* value;
43 struct heap_node** ref;
44};
45
46struct heap {
47 struct heap_node* head;
48 /* We cache the minimum of the heap.
49 * This speeds up repeated peek operations.
50 */
51 struct heap_node* min;
52};
53
54/* item comparison function:
55 * return 1 if a has higher prio than b, 0 otherwise
56 */
57typedef int (*heap_prio_t)(struct heap_node* a, struct heap_node* b);
58
59static inline void heap_init(struct heap* heap)
60{
61 heap->head = NULL;
62 heap->min = NULL;
63}
64
65static inline void heap_node_init_ref(struct heap_node** _h, void* value)
66{
67 struct heap_node* h = *_h;
68 h->parent = NULL;
69 h->next = NULL;
70 h->child = NULL;
71 h->degree = NOT_IN_HEAP;
72 h->value = value;
73 h->ref = _h;
74}
75
76static inline void heap_node_init(struct heap_node* h, void* value)
77{
78 h->parent = NULL;
79 h->next = NULL;
80 h->child = NULL;
81 h->degree = NOT_IN_HEAP;
82 h->value = value;
83 h->ref = NULL;
84}
85
86static inline void* heap_node_value(struct heap_node* h)
87{
88 return h->value;
89}
90
91static inline int heap_node_in_heap(struct heap_node* h)
92{
93 return h->degree != NOT_IN_HEAP;
94}
95
96static inline int heap_empty(struct heap* heap)
97{
98 return heap->head == NULL && heap->min == NULL;
99}
100
101/* make child a subtree of root */
102static inline void __heap_link(struct heap_node* root,
103 struct heap_node* child)
104{
105 child->parent = root;
106 child->next = root->child;
107 root->child = child;
108 root->degree++;
109}
110
111/* merge root lists */
112static inline struct heap_node* __heap_merge(struct heap_node* a,
113 struct heap_node* b)
114{
115 struct heap_node* head = NULL;
116 struct heap_node** pos = &head;
117
118 while (a && b) {
119 if (a->degree < b->degree) {
120 *pos = a;
121 a = a->next;
122 } else {
123 *pos = b;
124 b = b->next;
125 }
126 pos = &(*pos)->next;
127 }
128 if (a)
129 *pos = a;
130 else
131 *pos = b;
132 return head;
133}
134
135/* reverse a linked list of nodes. also clears parent pointer */
136static inline struct heap_node* __heap_reverse(struct heap_node* h)
137{
138 struct heap_node* tail = NULL;
139 struct heap_node* next;
140
141 if (!h)
142 return h;
143
144 h->parent = NULL;
145 while (h->next) {
146 next = h->next;
147 h->next = tail;
148 tail = h;
149 h = next;
150 h->parent = NULL;
151 }
152 h->next = tail;
153 return h;
154}
155
156static inline void __heap_min(heap_prio_t higher_prio, struct heap* heap,
157 struct heap_node** prev, struct heap_node** node)
158{
159 struct heap_node *_prev, *cur;
160 *prev = NULL;
161
162 if (!heap->head) {
163 *node = NULL;
164 return;
165 }
166
167 *node = heap->head;
168 _prev = heap->head;
169 cur = heap->head->next;
170 while (cur) {
171 if (higher_prio(cur, *node)) {
172 *node = cur;
173 *prev = _prev;
174 }
175 _prev = cur;
176 cur = cur->next;
177 }
178}
179
180static inline void __heap_union(heap_prio_t higher_prio, struct heap* heap,
181 struct heap_node* h2)
182{
183 struct heap_node* h1;
184 struct heap_node *prev, *x, *next;
185 if (!h2)
186 return;
187 h1 = heap->head;
188 if (!h1) {
189 heap->head = h2;
190 return;
191 }
192 h1 = __heap_merge(h1, h2);
193 prev = NULL;
194 x = h1;
195 next = x->next;
196 while (next) {
197 if (x->degree != next->degree ||
198 (next->next && next->next->degree == x->degree)) {
199 /* nothing to do, advance */
200 prev = x;
201 x = next;
202 } else if (higher_prio(x, next)) {
203 /* x becomes the root of next */
204 x->next = next->next;
205 __heap_link(x, next);
206 } else {
207 /* next becomes the root of x */
208 if (prev)
209 prev->next = next;
210 else
211 h1 = next;
212 __heap_link(next, x);
213 x = next;
214 }
215 next = x->next;
216 }
217 heap->head = h1;
218}
219
220static inline struct heap_node* __heap_extract_min(heap_prio_t higher_prio,
221 struct heap* heap)
222{
223 struct heap_node *prev, *node;
224 __heap_min(higher_prio, heap, &prev, &node);
225 if (!node)
226 return NULL;
227 if (prev)
228 prev->next = node->next;
229 else
230 heap->head = node->next;
231 __heap_union(higher_prio, heap, __heap_reverse(node->child));
232 return node;
233}
234
235/* insert (and reinitialize) a node into the heap */
236static inline void heap_insert(heap_prio_t higher_prio, struct heap* heap,
237 struct heap_node* node)
238{
239 struct heap_node *min;
240 node->child = NULL;
241 node->parent = NULL;
242 node->next = NULL;
243 node->degree = 0;
244 if (heap->min && higher_prio(node, heap->min)) {
245 /* swap min cache */
246 min = heap->min;
247 min->child = NULL;
248 min->parent = NULL;
249 min->next = NULL;
250 min->degree = 0;
251 __heap_union(higher_prio, heap, min);
252 heap->min = node;
253 } else
254 __heap_union(higher_prio, heap, node);
255}
256
257static inline void __uncache_min(heap_prio_t higher_prio, struct heap* heap)
258{
259 struct heap_node* min;
260 if (heap->min) {
261 min = heap->min;
262 heap->min = NULL;
263 heap_insert(higher_prio, heap, min);
264 }
265}
266
267/* merge addition into target */
268static inline void heap_union(heap_prio_t higher_prio,
269 struct heap* target, struct heap* addition)
270{
271 /* first insert any cached minima, if necessary */
272 __uncache_min(higher_prio, target);
273 __uncache_min(higher_prio, addition);
274 __heap_union(higher_prio, target, addition->head);
275 /* this is a destructive merge */
276 addition->head = NULL;
277}
278
279static inline struct heap_node* heap_peek(heap_prio_t higher_prio,
280 struct heap* heap)
281{
282 if (!heap->min)
283 heap->min = __heap_extract_min(higher_prio, heap);
284 return heap->min;
285}
286
287static inline struct heap_node* heap_take(heap_prio_t higher_prio,
288 struct heap* heap)
289{
290 struct heap_node *node;
291 if (!heap->min)
292 heap->min = __heap_extract_min(higher_prio, heap);
293 node = heap->min;
294 heap->min = NULL;
295 if (node)
296 node->degree = NOT_IN_HEAP;
297 return node;
298}
299
300static inline void heap_decrease(heap_prio_t higher_prio, struct heap* heap,
301 struct heap_node* node)
302{
303 struct heap_node *parent;
304 struct heap_node** tmp_ref;
305 void* tmp;
306
307 /* node's priority was decreased, we need to update its position */
308 if (!node->ref)
309 return;
310 if (heap->min != node) {
311 /* bubble up */
312 parent = node->parent;
313 while (parent && higher_prio(node, parent)) {
314 /* swap parent and node */
315 tmp = parent->value;
316 parent->value = node->value;
317 node->value = tmp;
318 /* swap references */
319 if (parent->ref)
320 *(parent->ref) = node;
321 *(node->ref) = parent;
322 tmp_ref = parent->ref;
323 parent->ref = node->ref;
324 node->ref = tmp_ref;
325 /* step up */
326 node = parent;
327 parent = node->parent;
328 }
329 }
330}
331
332static inline void heap_delete(heap_prio_t higher_prio, struct heap* heap,
333 struct heap_node* node)
334{
335 struct heap_node *parent, *prev, *pos;
336 struct heap_node** tmp_ref;
337 void* tmp;
338
339 if (!node->ref) /* can only delete if we have a reference */
340 return;
341 if (heap->min != node) {
342 /* bubble up */
343 parent = node->parent;
344 while (parent) {
345 /* swap parent and node */
346 tmp = parent->value;
347 parent->value = node->value;
348 node->value = tmp;
349 /* swap references */
350 if (parent->ref)
351 *(parent->ref) = node;
352 *(node->ref) = parent;
353 tmp_ref = parent->ref;
354 parent->ref = node->ref;
355 node->ref = tmp_ref;
356 /* step up */
357 node = parent;
358 parent = node->parent;
359 }
360 /* now delete:
361 * first find prev */
362 prev = NULL;
363 pos = heap->head;
364 while (pos != node) {
365 prev = pos;
366 pos = pos->next;
367 }
368 /* we have prev, now remove node */
369 if (prev)
370 prev->next = node->next;
371 else
372 heap->head = node->next;
373 __heap_union(higher_prio, heap, __heap_reverse(node->child));
374 } else
375 heap->min = NULL;
376 node->degree = NOT_IN_HEAP;
377}
378
379#endif /* HEAP_H */
diff --git a/include/load.h b/include/load.h
new file mode 100644
index 0000000..a7a242d
--- /dev/null
+++ b/include/load.h
@@ -0,0 +1,6 @@
1#ifndef LOAD_H
2#define LOAD_H
3
4int map_trace(const char *name, void **start, void **end, size_t *size);
5
6#endif