aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2009-10-05 13:20:29 -0400
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2009-10-05 13:20:29 -0400
commitf8ed8c406d70b9a040807a01de5296d8832cafd7 (patch)
tree6fa8fa64a669fa64955c5b2e570e023b33a31e50
parentd278c1c93b03f6617d7137a79561639ad1845f71 (diff)
binomial heap: support decrease() operation
Used to adjust position of heap node after the key of the node was decreased (= made more important). Cannot be used if key was increased (= made less important).
-rw-r--r--include/litmus/heap.h5
-rw-r--r--litmus/heap.c33
2 files changed, 34 insertions, 4 deletions
diff --git a/include/litmus/heap.h b/include/litmus/heap.h
index 19230f550f..da959b0bec 100644
--- a/include/litmus/heap.h
+++ b/include/litmus/heap.h
@@ -1,6 +1,6 @@
1/* heaps.h -- Binomial Heaps 1/* heaps.h -- Binomial Heaps
2 * 2 *
3 * (c) 2008 Bjoern Brandenburg 3 * (c) 2008, 2009 Bjoern Brandenburg
4 */ 4 */
5 5
6#ifndef HEAP_H 6#ifndef HEAP_H
@@ -57,6 +57,9 @@ struct heap_node* heap_peek(heap_prio_t higher_prio,
57struct heap_node* heap_take(heap_prio_t higher_prio, 57struct heap_node* heap_take(heap_prio_t higher_prio,
58 struct heap* heap); 58 struct heap* heap);
59 59
60void heap_uncache_min(heap_prio_t higher_prio, struct heap* heap);
61int heap_decrease(heap_prio_t higher_prio, struct heap_node* node);
62
60void heap_delete(heap_prio_t higher_prio, 63void heap_delete(heap_prio_t higher_prio,
61 struct heap* heap, 64 struct heap* heap,
62 struct heap_node* node); 65 struct heap_node* node);
diff --git a/litmus/heap.c b/litmus/heap.c
index 4d0d7b96ae..112d14da46 100644
--- a/litmus/heap.c
+++ b/litmus/heap.c
@@ -175,7 +175,7 @@ void heap_insert(heap_prio_t higher_prio, struct heap* heap,
175 __heap_union(higher_prio, heap, node); 175 __heap_union(higher_prio, heap, node);
176} 176}
177 177
178static void __uncache_min(heap_prio_t higher_prio, struct heap* heap) 178void heap_uncache_min(heap_prio_t higher_prio, struct heap* heap)
179{ 179{
180 struct heap_node* min; 180 struct heap_node* min;
181 if (heap->min) { 181 if (heap->min) {
@@ -190,8 +190,8 @@ void heap_union(heap_prio_t higher_prio,
190 struct heap* target, struct heap* addition) 190 struct heap* target, struct heap* addition)
191{ 191{
192 /* first insert any cached minima, if necessary */ 192 /* first insert any cached minima, if necessary */
193 __uncache_min(higher_prio, target); 193 heap_uncache_min(higher_prio, target);
194 __uncache_min(higher_prio, addition); 194 heap_uncache_min(higher_prio, addition);
195 __heap_union(higher_prio, target, addition->head); 195 __heap_union(higher_prio, target, addition->head);
196 /* this is a destructive merge */ 196 /* this is a destructive merge */
197 addition->head = NULL; 197 addition->head = NULL;
@@ -218,6 +218,33 @@ struct heap_node* heap_take(heap_prio_t higher_prio,
218 return node; 218 return node;
219} 219}
220 220
221int heap_decrease(heap_prio_t higher_prio, struct heap_node* node)
222{
223 struct heap_node *parent;
224 struct heap_node** tmp_ref;
225 void* tmp;
226
227 /* bubble up */
228 parent = node->parent;
229 while (parent && higher_prio(node, parent)) {
230 /* swap parent and node */
231 tmp = parent->value;
232 parent->value = node->value;
233 node->value = tmp;
234 /* swap references */
235 *(parent->ref) = node;
236 *(node->ref) = parent;
237 tmp_ref = parent->ref;
238 parent->ref = node->ref;
239 node->ref = tmp_ref;
240 /* step up */
241 node = parent;
242 parent = node->parent;
243 }
244
245 return parent != NULL;
246}
247
221void heap_delete(heap_prio_t higher_prio, struct heap* heap, 248void heap_delete(heap_prio_t higher_prio, struct heap* heap,
222 struct heap_node* node) 249 struct heap_node* node)
223{ 250{