diff options
| author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-21 19:21:46 -0400 |
|---|---|---|
| committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-21 19:21:46 -0400 |
| commit | 33f5fe82661086d27467821aaf418364774e360a (patch) | |
| tree | a58574e9befb985973091e9f326abce52b4c472f | |
| parent | ee525fe7ba4edf4da2d293629ffdff2caa9ad02b (diff) | |
Simplify binheap_delete and add binheap_decrease
| -rw-r--r-- | include/litmus/binheap.h | 73 |
1 files changed, 33 insertions, 40 deletions
diff --git a/include/litmus/binheap.h b/include/litmus/binheap.h index 9fe5dc13d032..fd4c0a318b96 100644 --- a/include/litmus/binheap.h +++ b/include/litmus/binheap.h | |||
| @@ -80,9 +80,9 @@ container_of((ptr), type, member) | |||
| 80 | /** | 80 | /** |
| 81 | * binheap_top_entry - get the struct for the node at the top of the heap. | 81 | * binheap_top_entry - get the struct for the node at the top of the heap. |
| 82 | * Only valid when called upon the heap handle node. | 82 | * Only valid when called upon the heap handle node. |
| 83 | * @ptr: the special heap-handle node. | 83 | * @ptr: the special heap-handle node. |
| 84 | * @type: the type of the struct the head is embedded in. | 84 | * @type: the type of the struct the head is embedded in. |
| 85 | * @member: the name of the binheap_struct within the (type) struct. | 85 | * @member: the name of the binheap_struct within the (type) struct. |
| 86 | */ | 86 | */ |
| 87 | #define binheap_top_entry(ptr, type, member) \ | 87 | #define binheap_top_entry(ptr, type, member) \ |
| 88 | binheap_entry((ptr)->root, type, member) | 88 | binheap_entry((ptr)->root, type, member) |
| @@ -90,7 +90,7 @@ binheap_entry((ptr)->root, type, member) | |||
| 90 | /** | 90 | /** |
| 91 | * binheap_delete_root - remove the root element from the heap. | 91 | * binheap_delete_root - remove the root element from the heap. |
| 92 | * @handle: handle to the heap. | 92 | * @handle: handle to the heap. |
| 93 | * @type: the type of the struct the head is embedded in. | 93 | * @type: the type of the struct the head is embedded in. |
| 94 | * @member: the name of the binheap_struct within the (type) struct. | 94 | * @member: the name of the binheap_struct within the (type) struct. |
| 95 | */ | 95 | */ |
| 96 | #define binheap_delete_root(handle, type, member) \ | 96 | #define binheap_delete_root(handle, type, member) \ |
| @@ -100,22 +100,30 @@ __binheap_delete_root((handle), &((type *)((handle)->root->data))->member) | |||
| 100 | * binheap_delete - remove an arbitrary element from the heap. | 100 | * binheap_delete - remove an arbitrary element from the heap. |
| 101 | * @to_delete: pointer to node to be removed. | 101 | * @to_delete: pointer to node to be removed. |
| 102 | * @handle: handle to the heap. | 102 | * @handle: handle to the heap. |
| 103 | * @type: the type of the struct the head is embedded in. | ||
| 104 | * @member: the name of the binheap_struct within the (type) struct. | ||
| 105 | */ | 103 | */ |
| 106 | #define binheap_delete(to_delete, handle, type, member) \ | 104 | #define binheap_delete(to_delete, handle) \ |
| 107 | __binheap_delete((to_delete), &((((type*)((to_delete)->data))->member)), (handle)) | 105 | __binheap_delete((to_delete), (handle)) |
| 108 | 106 | ||
| 109 | /** | 107 | /** |
| 110 | * binheap_add - insert an element to the heap | 108 | * binheap_add - insert an element to the heap |
| 111 | * new_node: node to add. | 109 | * new_node: node to add. |
| 112 | * @handle: handle to the heap. | 110 | * @handle: handle to the heap. |
| 113 | * @type: the type of the struct the head is embedded in. | 111 | * @type: the type of the struct the head is embedded in. |
| 114 | * @member: the name of the binheap_struct within the (type) struct. | 112 | * @member: the name of the binheap_struct within the (type) struct. |
| 115 | */ | 113 | */ |
| 116 | #define binheap_add(new_node, handle, type, member) \ | 114 | #define binheap_add(new_node, handle, type, member) \ |
| 117 | __binheap_add((new_node), (handle), container_of((new_node), type, member)) | 115 | __binheap_add((new_node), (handle), container_of((new_node), type, member)) |
| 118 | 116 | ||
| 117 | /** | ||
| 118 | * binheap_decrease - re-eval the position of a node (based upon its | ||
| 119 | * original data pointer). | ||
| 120 | * @handle: handle to the heap. | ||
| 121 | * @orig_node: node that was associated with the data pointer | ||
| 122 | * (whose value has changed) when said pointer was | ||
| 123 | * added to the heap. | ||
| 124 | */ | ||
| 125 | #define binheap_decrease(orig_node, handle) \ | ||
| 126 | __binheap_decrease((orig_node), (handle)) | ||
| 119 | 127 | ||
| 120 | #define BINHEAP_NODE_INIT() { NULL, NULL, NULL, NULL , NULL, NULL} | 128 | #define BINHEAP_NODE_INIT() { NULL, NULL, NULL, NULL , NULL, NULL} |
| 121 | 129 | ||
| @@ -494,43 +502,17 @@ static inline void __binheap_delete_root(struct binheap_handle *handle, | |||
| 494 | 502 | ||
| 495 | 503 | ||
| 496 | /** | 504 | /** |
| 497 | * Delete an arbitrary node. We first coalesce, then bubble | 505 | * Delete an arbitrary node. Bubble node to delete up to the root, |
| 498 | * node to delete up to the root, and then delete to root. | 506 | * and then delete to root. |
| 499 | */ | 507 | */ |
| 500 | static inline void __binheap_delete( | 508 | static inline void __binheap_delete( |
| 501 | struct binheap_node *node_to_delete, | 509 | struct binheap_node *node_to_delete, |
| 502 | struct binheap_node *user_of_node, | ||
| 503 | struct binheap_handle *handle) | 510 | struct binheap_handle *handle) |
| 504 | { | 511 | { |
| 505 | struct binheap_node *root, *target; | 512 | struct binheap_node *target = node_to_delete->ref; |
| 506 | void *temp_data; | 513 | void *temp_data = target->data; |
| 507 | |||
| 508 | /* Position the node to delete at the root. */ | ||
| 509 | |||
| 510 | /* coalesce: swap nodes with user of the node to delete. */ | ||
| 511 | if(node_to_delete != user_of_node) { | ||
| 512 | /* we need to take container's memory/node out of the heap, | ||
| 513 | * so swap with the user of the node | ||
| 514 | */ | ||
| 515 | __binheap_swap_safe(handle, user_of_node, node_to_delete); | ||
| 516 | } | ||
| 517 | |||
| 518 | root = handle->root; | ||
| 519 | |||
| 520 | /* Move the _node_ to the root */ | ||
| 521 | if(root != node_to_delete) { | ||
| 522 | __binheap_swap_safe(handle, root, node_to_delete); | ||
| 523 | node_to_delete = root; | ||
| 524 | } | ||
| 525 | |||
| 526 | node_to_delete = handle->root; | ||
| 527 | target = node_to_delete->ref; | ||
| 528 | |||
| 529 | /* Bubble the data pointer back up to its node, which has already been | ||
| 530 | * positioned at the root. */ | ||
| 531 | 514 | ||
| 532 | /* temporarily set data to null to allow node to bubble up to the top. */ | 515 | /* temporarily set data to null to allow node to bubble up to the top. */ |
| 533 | temp_data = target->data; | ||
| 534 | target->data = NULL; | 516 | target->data = NULL; |
| 535 | 517 | ||
| 536 | __binheap_bubble_up(handle, target); | 518 | __binheap_bubble_up(handle, target); |
| @@ -539,5 +521,16 @@ static inline void __binheap_delete( | |||
| 539 | node_to_delete->data = temp_data; /* restore node data pointer */ | 521 | node_to_delete->data = temp_data; /* restore node data pointer */ |
| 540 | } | 522 | } |
| 541 | 523 | ||
| 524 | /** | ||
| 525 | * Bubble up a node whose pointer has decreased in value. | ||
| 526 | */ | ||
| 527 | static inline void __binheap_decrease( | ||
| 528 | struct binheap_node *orig_node, | ||
| 529 | struct binheap_handle *handle) | ||
| 530 | { | ||
| 531 | struct binheap_node *target = orig_node->ref; | ||
| 532 | __binheap_bubble_up(handle, target); | ||
| 533 | } | ||
| 534 | |||
| 542 | #endif | 535 | #endif |
| 543 | 536 | ||
