Add heap_replace() functionality

This commit is contained in:
Justin R. Cutler 2016-04-09 11:39:19 -04:00
parent ecf9cc606c
commit aca3db2b06
3 changed files with 42 additions and 2 deletions

View File

@ -84,6 +84,27 @@ int heap_push(heap_t *heap, heap_node_t *node)
}
void heap_replace(heap_node_t *old, heap_node_t *node)
{
heap_t *heap = old->heap;
size_t pos = old->index;
heap_node_t **storage = heap->allocation.memory;
/* disassociate old node from heap */
old->heap = NULL;
old->index = 0;
/* place new node in heap */
node->heap = heap;
node->index = pos;
storage[pos] = node;
/* restore heap invariant */
sift_up(heap, pos, heap->count);
sift_down(heap, 0, pos);
}
void heap_remove(heap_node_t *node)
{
heap_t *heap = node->heap;

View File

@ -30,7 +30,12 @@
#include <threadless/heap.h>
const int data[] = { 4 /* duplicate */, 1, 9, 2, 8, 4, 0, 5, 3, 6, 7, 99 };
const int data[] = {
4 /* duplicate (remove) */,
6 /* duplicate (replace with 1) */,
9, 2, 8, 4, 0, 5, 3, 6, 7,
99 /* remove */,
};
const size_t data_count = sizeof(data) / sizeof(data[0]);
@ -58,7 +63,7 @@ static int run(allocator_t *allocator)
heap_node_t *node;
allocation_init(&alloc, allocator);
error = allocation_realloc_array(&alloc, data_count, sizeof(*values));
error = allocation_realloc_array(&alloc, data_count + 1, sizeof(*values));
if (error) {
return error;
}
@ -74,9 +79,14 @@ static int run(allocator_t *allocator)
/* remove from middle */
heap_remove(&(values[0].node));
/* remove from end */
heap_remove(&(values[data_count - 1].node));
/* replace */
values[data_count].value = 1;
heap_replace(&(values[1].node), &(values[data_count].node));
/* pull values out of heap (minimum first) */
while (NULL != (node = heap_pop(&heap))) {
value_t *value = container_of(node, value_t, node);

View File

@ -84,6 +84,15 @@ static inline heap_node_t *heap_peek(const heap_t *heap)
*/
int heap_push(heap_t *heap, heap_node_t *node);
/** Replace an existing @p old node in a heap with a new @p node
* @param[in,out] old old node
* @param[in,out] node new node
* @pre @p old must be in a heap
* @post @p old is no longer in a heap
* @post @p node is in the heap that previously contained @p old
*/
void heap_replace(heap_node_t *old, heap_node_t *node);
/** Remove an arbitrary @p node from its heap
* @param[in,out] node node
* @pre @p node must be in a heap