aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/binheap.c
diff options
context:
space:
mode:
Diffstat (limited to 'litmus/binheap.c')
-rw-r--r--litmus/binheap.c126
1 files changed, 63 insertions, 63 deletions
diff --git a/litmus/binheap.c b/litmus/binheap.c
index 22feea614e50..8d42403ad52c 100644
--- a/litmus/binheap.c
+++ b/litmus/binheap.c
@@ -9,11 +9,11 @@ int binheap_is_in_this_heap(struct binheap_node *node,
9 if(!binheap_is_in_heap(node)) { 9 if(!binheap_is_in_heap(node)) {
10 return 0; 10 return 0;
11 } 11 }
12 12
13 while(node->parent != NULL) { 13 while(node->parent != NULL) {
14 node = node->parent; 14 node = node->parent;
15 } 15 }
16 16
17 return (node == heap->root); 17 return (node == heap->root);
18} 18}
19 19
@@ -23,7 +23,7 @@ static void __update_ref(struct binheap_node *parent,
23{ 23{
24 *(parent->ref_ptr) = child; 24 *(parent->ref_ptr) = child;
25 *(child->ref_ptr) = parent; 25 *(child->ref_ptr) = parent;
26 26
27 swap(parent->ref_ptr, child->ref_ptr); 27 swap(parent->ref_ptr, child->ref_ptr);
28} 28}
29 29
@@ -35,7 +35,7 @@ static void __binheap_swap(struct binheap_node *parent,
35// dump_node_data(parent, child); 35// dump_node_data(parent, child);
36// BUG(); 36// BUG();
37// } 37// }
38 38
39 swap(parent->data, child->data); 39 swap(parent->data, child->data);
40 __update_ref(parent, child); 40 __update_ref(parent, child);
41} 41}
@@ -50,14 +50,14 @@ static void __binheap_swap_safe(struct binheap_handle *handle,
50{ 50{
51 swap(a->data, b->data); 51 swap(a->data, b->data);
52 __update_ref(a, b); 52 __update_ref(a, b);
53 53
54 if((a->parent != NULL) && (a->parent == b->parent)) { 54 if((a->parent != NULL) && (a->parent == b->parent)) {
55 /* special case: shared parent */ 55 /* special case: shared parent */
56 swap(a->parent->left, a->parent->right); 56 swap(a->parent->left, a->parent->right);
57 } 57 }
58 else { 58 else {
59 /* Update pointers to swap parents. */ 59 /* Update pointers to swap parents. */
60 60
61 if(a->parent) { 61 if(a->parent) {
62 if(a == a->parent->left) { 62 if(a == a->parent->left) {
63 a->parent->left = b; 63 a->parent->left = b;
@@ -66,7 +66,7 @@ static void __binheap_swap_safe(struct binheap_handle *handle,
66 a->parent->right = b; 66 a->parent->right = b;
67 } 67 }
68 } 68 }
69 69
70 if(b->parent) { 70 if(b->parent) {
71 if(b == b->parent->left) { 71 if(b == b->parent->left) {
72 b->parent->left = a; 72 b->parent->left = a;
@@ -75,48 +75,48 @@ static void __binheap_swap_safe(struct binheap_handle *handle,
75 b->parent->right = a; 75 b->parent->right = a;
76 } 76 }
77 } 77 }
78 78
79 swap(a->parent, b->parent); 79 swap(a->parent, b->parent);
80 } 80 }
81 81
82 /* swap children */ 82 /* swap children */
83 83
84 if(a->left) { 84 if(a->left) {
85 a->left->parent = b; 85 a->left->parent = b;
86 86
87 if(a->right) { 87 if(a->right) {
88 a->right->parent = b; 88 a->right->parent = b;
89 } 89 }
90 } 90 }
91 91
92 if(b->left) { 92 if(b->left) {
93 b->left->parent = a; 93 b->left->parent = a;
94 94
95 if(b->right) { 95 if(b->right) {
96 b->right->parent = a; 96 b->right->parent = a;
97 } 97 }
98 } 98 }
99 99
100 swap(a->left, b->left); 100 swap(a->left, b->left);
101 swap(a->right, b->right); 101 swap(a->right, b->right);
102 102
103 103
104 /* update next/last/root pointers */ 104 /* update next/last/root pointers */
105 105
106 if(a == handle->next) { 106 if(a == handle->next) {
107 handle->next = b; 107 handle->next = b;
108 } 108 }
109 else if(b == handle->next) { 109 else if(b == handle->next) {
110 handle->next = a; 110 handle->next = a;
111 } 111 }
112 112
113 if(a == handle->last) { 113 if(a == handle->last) {
114 handle->last = b; 114 handle->last = b;
115 } 115 }
116 else if(b == handle->last) { 116 else if(b == handle->last) {
117 handle->last = a; 117 handle->last = a;
118 } 118 }
119 119
120 if(a == handle->root) { 120 if(a == handle->root) {
121 handle->root = b; 121 handle->root = b;
122 } 122 }
@@ -133,29 +133,29 @@ static void __binheap_swap_safe(struct binheap_handle *handle,
133static void __binheap_update_last(struct binheap_handle *handle) 133static void __binheap_update_last(struct binheap_handle *handle)
134{ 134{
135 struct binheap_node *temp = handle->last; 135 struct binheap_node *temp = handle->last;
136 136
137 /* find a "bend" in the tree. */ 137 /* find a "bend" in the tree. */
138 while(temp->parent && (temp == temp->parent->left)) { 138 while(temp->parent && (temp == temp->parent->left)) {
139 temp = temp->parent; 139 temp = temp->parent;
140 } 140 }
141 141
142 /* step over to sibling if we're not at root */ 142 /* step over to sibling if we're not at root */
143 if(temp->parent != NULL) { 143 if(temp->parent != NULL) {
144 temp = temp->parent->left; 144 temp = temp->parent->left;
145 } 145 }
146 146
147 /* now travel right as far as possible. */ 147 /* now travel right as far as possible. */
148 while(temp->right != NULL) { 148 while(temp->right != NULL) {
149 temp = temp->right; 149 temp = temp->right;
150 } 150 }
151 151
152 /* take one step to the left if we're not at the bottom-most level. */ 152 /* take one step to the left if we're not at the bottom-most level. */
153 if(temp->left != NULL) { 153 if(temp->left != NULL) {
154 temp = temp->left; 154 temp = temp->left;
155 } 155 }
156 156
157 //BUG_ON(!(temp->left == NULL && temp->right == NULL)); 157 //BUG_ON(!(temp->left == NULL && temp->right == NULL));
158 158
159 handle->last = temp; 159 handle->last = temp;
160} 160}
161 161
@@ -166,22 +166,22 @@ static void __binheap_update_last(struct binheap_handle *handle)
166static void __binheap_update_next(struct binheap_handle *handle) 166static void __binheap_update_next(struct binheap_handle *handle)
167{ 167{
168 struct binheap_node *temp = handle->next; 168 struct binheap_node *temp = handle->next;
169 169
170 /* find a "bend" in the tree. */ 170 /* find a "bend" in the tree. */
171 while(temp->parent && (temp == temp->parent->right)) { 171 while(temp->parent && (temp == temp->parent->right)) {
172 temp = temp->parent; 172 temp = temp->parent;
173 } 173 }
174 174
175 /* step over to sibling if we're not at root */ 175 /* step over to sibling if we're not at root */
176 if(temp->parent != NULL) { 176 if(temp->parent != NULL) {
177 temp = temp->parent->right; 177 temp = temp->parent->right;
178 } 178 }
179 179
180 /* now travel left as far as possible. */ 180 /* now travel left as far as possible. */
181 while(temp->left != NULL) { 181 while(temp->left != NULL) {
182 temp = temp->left; 182 temp = temp->left;
183 } 183 }
184 184
185 handle->next = temp; 185 handle->next = temp;
186} 186}
187 187
@@ -198,13 +198,13 @@ static void __binheap_bubble_up(
198// dump_node_data2(handle, node); 198// dump_node_data2(handle, node);
199// BUG(); 199// BUG();
200// } 200// }
201 201
202 while((node->parent != NULL) && 202 while((node->parent != NULL) &&
203 ((node->data == BINHEAP_POISON) /* let BINHEAP_POISON data bubble to the top */ || 203 ((node->data == BINHEAP_POISON) /* let BINHEAP_POISON data bubble to the top */ ||
204 handle->compare(node, node->parent))) { 204 handle->compare(node, node->parent))) {
205 __binheap_swap(node->parent, node); 205 __binheap_swap(node->parent, node);
206 node = node->parent; 206 node = node->parent;
207 207
208// if(!binheap_is_in_heap(node)) 208// if(!binheap_is_in_heap(node))
209// { 209// {
210// dump_node_data2(handle, node); 210// dump_node_data2(handle, node);
@@ -218,7 +218,7 @@ static void __binheap_bubble_up(
218static void __binheap_bubble_down(struct binheap_handle *handle) 218static void __binheap_bubble_down(struct binheap_handle *handle)
219{ 219{
220 struct binheap_node *node = handle->root; 220 struct binheap_node *node = handle->root;
221 221
222 while(node->left != NULL) { 222 while(node->left != NULL) {
223 if(node->right && handle->compare(node->right, node->left)) { 223 if(node->right && handle->compare(node->right, node->left)) {
224 if(handle->compare(node->right, node)) { 224 if(handle->compare(node->right, node)) {
@@ -252,11 +252,11 @@ void __binheap_add(struct binheap_node *new_node,
252// dump_node_data2(handle, new_node); 252// dump_node_data2(handle, new_node);
253// BUG(); 253// BUG();
254// } 254// }
255 255
256 new_node->data = data; 256 new_node->data = data;
257 new_node->ref = new_node; 257 new_node->ref = new_node;
258 new_node->ref_ptr = &(new_node->ref); 258 new_node->ref_ptr = &(new_node->ref);
259 259
260 if(!binheap_empty(handle)) { 260 if(!binheap_empty(handle)) {
261 /* insert left side first */ 261 /* insert left side first */
262 if(handle->next->left == NULL) { 262 if(handle->next->left == NULL) {
@@ -264,9 +264,9 @@ void __binheap_add(struct binheap_node *new_node,
264 new_node->parent = handle->next; 264 new_node->parent = handle->next;
265 new_node->left = NULL; 265 new_node->left = NULL;
266 new_node->right = NULL; 266 new_node->right = NULL;
267 267
268 handle->last = new_node; 268 handle->last = new_node;
269 269
270 __binheap_bubble_up(handle, new_node); 270 __binheap_bubble_up(handle, new_node);
271 } 271 }
272 else { 272 else {
@@ -275,20 +275,20 @@ void __binheap_add(struct binheap_node *new_node,
275 new_node->parent = handle->next; 275 new_node->parent = handle->next;
276 new_node->left = NULL; 276 new_node->left = NULL;
277 new_node->right = NULL; 277 new_node->right = NULL;
278 278
279 handle->last = new_node; 279 handle->last = new_node;
280 280
281 __binheap_update_next(handle); 281 __binheap_update_next(handle);
282 __binheap_bubble_up(handle, new_node); 282 __binheap_bubble_up(handle, new_node);
283 } 283 }
284 } 284 }
285 else { 285 else {
286 /* first node in heap */ 286 /* first node in heap */
287 287
288 new_node->parent = NULL; 288 new_node->parent = NULL;
289 new_node->left = NULL; 289 new_node->left = NULL;
290 new_node->right = NULL; 290 new_node->right = NULL;
291 291
292 handle->root = new_node; 292 handle->root = new_node;
293 handle->next = new_node; 293 handle->next = new_node;
294 handle->last = new_node; 294 handle->last = new_node;
@@ -308,27 +308,27 @@ void __binheap_delete_root(struct binheap_handle *handle,
308 struct binheap_node *container) 308 struct binheap_node *container)
309{ 309{
310 struct binheap_node *root = handle->root; 310 struct binheap_node *root = handle->root;
311 311
312// if(!binheap_is_in_heap(container)) 312// if(!binheap_is_in_heap(container))
313// { 313// {
314// dump_node_data2(handle, container); 314// dump_node_data2(handle, container);
315// BUG(); 315// BUG();
316// } 316// }
317 317
318 if(root != container) { 318 if(root != container) {
319 /* coalesce */ 319 /* coalesce */
320 __binheap_swap_safe(handle, root, container); 320 __binheap_swap_safe(handle, root, container);
321 root = container; 321 root = container;
322 } 322 }
323 323
324 if(handle->last != root) { 324 if(handle->last != root) {
325 /* swap 'last' node up to root and bubble it down. */ 325 /* swap 'last' node up to root and bubble it down. */
326 326
327 struct binheap_node *to_move = handle->last; 327 struct binheap_node *to_move = handle->last;
328 328
329 if(to_move->parent != root) { 329 if(to_move->parent != root) {
330 handle->next = to_move->parent; 330 handle->next = to_move->parent;
331 331
332 if(handle->next->right == to_move) { 332 if(handle->next->right == to_move) {
333 /* disconnect from parent */ 333 /* disconnect from parent */
334 to_move->parent->right = NULL; 334 to_move->parent->right = NULL;
@@ -337,16 +337,16 @@ void __binheap_delete_root(struct binheap_handle *handle,
337 else { 337 else {
338 /* find new 'last' before we disconnect */ 338 /* find new 'last' before we disconnect */
339 __binheap_update_last(handle); 339 __binheap_update_last(handle);
340 340
341 /* disconnect from parent */ 341 /* disconnect from parent */
342 to_move->parent->left = NULL; 342 to_move->parent->left = NULL;
343 } 343 }
344 } 344 }
345 else { 345 else {
346 /* 'last' is direct child of root */ 346 /* 'last' is direct child of root */
347 347
348 handle->next = to_move; 348 handle->next = to_move;
349 349
350 if(to_move == to_move->parent->right) { 350 if(to_move == to_move->parent->right) {
351 to_move->parent->right = NULL; 351 to_move->parent->right = NULL;
352 handle->last = to_move->parent->left; 352 handle->last = to_move->parent->left;
@@ -357,7 +357,7 @@ void __binheap_delete_root(struct binheap_handle *handle,
357 } 357 }
358 } 358 }
359 to_move->parent = NULL; 359 to_move->parent = NULL;
360 360
361 /* reconnect as root. We can't just swap data ptrs since root node 361 /* reconnect as root. We can't just swap data ptrs since root node
362 * may be freed after this function returns. 362 * may be freed after this function returns.
363 */ 363 */
@@ -369,9 +369,9 @@ void __binheap_delete_root(struct binheap_handle *handle,
369 if(to_move->right != NULL) { 369 if(to_move->right != NULL) {
370 to_move->right->parent = to_move; 370 to_move->right->parent = to_move;
371 } 371 }
372 372
373 handle->root = to_move; 373 handle->root = to_move;
374 374
375 /* bubble down */ 375 /* bubble down */
376 __binheap_bubble_down(handle); 376 __binheap_bubble_down(handle);
377 } 377 }
@@ -381,7 +381,7 @@ void __binheap_delete_root(struct binheap_handle *handle,
381 handle->next = NULL; 381 handle->next = NULL;
382 handle->last = NULL; 382 handle->last = NULL;
383 } 383 }
384 384
385 /* mark as removed */ 385 /* mark as removed */
386 container->parent = BINHEAP_POISON; 386 container->parent = BINHEAP_POISON;
387} 387}
@@ -396,25 +396,25 @@ void __binheap_delete(struct binheap_node *node_to_delete,
396{ 396{
397 struct binheap_node *target = node_to_delete->ref; 397 struct binheap_node *target = node_to_delete->ref;
398 void *temp_data = target->data; 398 void *temp_data = target->data;
399 399
400// if(!binheap_is_in_heap(node_to_delete)) 400// if(!binheap_is_in_heap(node_to_delete))
401// { 401// {
402// dump_node_data2(handle, node_to_delete); 402// dump_node_data2(handle, node_to_delete);
403// BUG(); 403// BUG();
404// } 404// }
405// 405//
406// if(!binheap_is_in_heap(target)) 406// if(!binheap_is_in_heap(target))
407// { 407// {
408// dump_node_data2(handle, target); 408// dump_node_data2(handle, target);
409// BUG(); 409// BUG();
410// } 410// }
411 411
412 /* temporarily set data to null to allow node to bubble up to the top. */ 412 /* temporarily set data to null to allow node to bubble up to the top. */
413 target->data = BINHEAP_POISON; 413 target->data = BINHEAP_POISON;
414 414
415 __binheap_bubble_up(handle, target); 415 __binheap_bubble_up(handle, target);
416 __binheap_delete_root(handle, node_to_delete); 416 __binheap_delete_root(handle, node_to_delete);
417 417
418 node_to_delete->data = temp_data; /* restore node data pointer */ 418 node_to_delete->data = temp_data; /* restore node data pointer */
419 //node_to_delete->parent = BINHEAP_POISON; /* poison the node */ 419 //node_to_delete->parent = BINHEAP_POISON; /* poison the node */
420} 420}
@@ -426,18 +426,18 @@ void __binheap_decrease(struct binheap_node *orig_node,
426 struct binheap_handle *handle) 426 struct binheap_handle *handle)
427{ 427{
428 struct binheap_node *target = orig_node->ref; 428 struct binheap_node *target = orig_node->ref;
429 429
430// if(!binheap_is_in_heap(orig_node)) 430// if(!binheap_is_in_heap(orig_node))
431// { 431// {
432// dump_node_data2(handle, orig_node); 432// dump_node_data2(handle, orig_node);
433// BUG(); 433// BUG();
434// } 434// }
435// 435//
436// if(!binheap_is_in_heap(target)) 436// if(!binheap_is_in_heap(target))
437// { 437// {
438// dump_node_data2(handle, target); 438// dump_node_data2(handle, target);
439// BUG(); 439// BUG();
440// } 440// }
441// 441//
442 __binheap_bubble_up(handle, target); 442 __binheap_bubble_up(handle, target);
443} 443}