From 80a63e1574114b7e4e42d023f3a92cd9c7f252fe Mon Sep 17 00:00:00 2001 From: Michael Graff Date: Mon, 10 Apr 2006 16:28:04 +0000 Subject: [PATCH] Documentation changes; no functional changes. Some variables were renamed from 'i' to 'index' in heap.h so documentation can be nicer. --- lib/isc/heap.c | 47 ++++++------- lib/isc/include/isc/heap.h | 137 ++++++++++++++++++++++++++++++++++--- 2 files changed, 149 insertions(+), 35 deletions(-) diff --git a/lib/isc/heap.c b/lib/isc/heap.c index 49832040ae..7ea5e12889 100644 --- a/lib/isc/heap.c +++ b/lib/isc/heap.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: heap.c,v 1.32 2005/04/29 00:23:24 marka Exp $ */ +/* $Id: heap.c,v 1.33 2006/04/10 16:28:04 explorer Exp $ */ /*! \file * Heap implementation of priority queues adapted from the following: @@ -39,7 +39,8 @@ /*% * Note: to make heap_parent and heap_left easy to compute, the first * element of the heap array is not used; i.e. heap subscripts are 1-based, - * not 0-based. + * not 0-based. The parent is index/2, and the left-child is index*2. + * The right child is index*2+1. */ #define heap_parent(i) ((i) >> 1) #define heap_left(i) ((i) << 1) @@ -71,7 +72,6 @@ struct isc_heap { isc_heapindex_t index; }; -/*% Create a heap. */ isc_result_t isc_heap_create(isc_mem_t *mctx, isc_heapcompare_t compare, isc_heapindex_t index, unsigned int size_increment, @@ -102,7 +102,6 @@ isc_heap_create(isc_mem_t *mctx, isc_heapcompare_t compare, return (ISC_R_SUCCESS); } -/*% Destroy a heap. */ void isc_heap_destroy(isc_heap_t **heapp) { isc_heap_t *heap; @@ -146,8 +145,8 @@ static void float_up(isc_heap_t *heap, unsigned int i, void *elt) { unsigned int p; - for (p = heap_parent(i); - i > 1 && heap->compare(elt, heap->array[p]); + for (p = heap_parent(i) ; + i > 1 && heap->compare(elt, heap->array[p]) ; i = p, p = heap_parent(i)) { heap->array[i] = heap->array[p]; if (heap->index != NULL) @@ -185,7 +184,6 @@ sink_down(isc_heap_t *heap, unsigned int i, void *elt) { INSIST(HEAPCONDITION(i)); } -/*% Insert a heap. */ isc_result_t isc_heap_insert(isc_heap_t *heap, void *elt) { unsigned int i; @@ -201,50 +199,49 @@ isc_heap_insert(isc_heap_t *heap, void *elt) { return (ISC_R_SUCCESS); } -/*% Delete a heap. */ void -isc_heap_delete(isc_heap_t *heap, unsigned int i) { +isc_heap_delete(isc_heap_t *heap, unsigned int index) { void *elt; isc_boolean_t less; REQUIRE(VALID_HEAP(heap)); - REQUIRE(i >= 1 && i <= heap->last); + REQUIRE(index >= 1 && index <= heap->last); - if (i == heap->last) { + if (index == heap->last) { heap->last--; } else { elt = heap->array[heap->last--]; - less = heap->compare(elt, heap->array[i]); - heap->array[i] = elt; + less = heap->compare(elt, heap->array[index]); + heap->array[index] = elt; if (less) - float_up(heap, i, heap->array[i]); + float_up(heap, index, heap->array[index]); else - sink_down(heap, i, heap->array[i]); + sink_down(heap, index, heap->array[index]); } } void -isc_heap_increased(isc_heap_t *heap, unsigned int i) { +isc_heap_increased(isc_heap_t *heap, unsigned int index) { REQUIRE(VALID_HEAP(heap)); - REQUIRE(i >= 1 && i <= heap->last); + REQUIRE(index >= 1 && index <= heap->last); - float_up(heap, i, heap->array[i]); + float_up(heap, index, heap->array[index]); } void -isc_heap_decreased(isc_heap_t *heap, unsigned int i) { +isc_heap_decreased(isc_heap_t *heap, unsigned int index) { REQUIRE(VALID_HEAP(heap)); - REQUIRE(i >= 1 && i <= heap->last); + REQUIRE(index >= 1 && index <= heap->last); - sink_down(heap, i, heap->array[i]); + sink_down(heap, index, heap->array[index]); } void * -isc_heap_element(isc_heap_t *heap, unsigned int i) { +isc_heap_element(isc_heap_t *heap, unsigned int index) { REQUIRE(VALID_HEAP(heap)); - REQUIRE(i >= 1 && i <= heap->last); + REQUIRE(index >= 1 && index <= heap->last); - return (heap->array[i]); + return (heap->array[index]); } void @@ -254,6 +251,6 @@ isc_heap_foreach(isc_heap_t *heap, isc_heapaction_t action, void *uap) { REQUIRE(VALID_HEAP(heap)); REQUIRE(action != NULL); - for (i = 1; i <= heap->last; i++) + for (i = 1 ; i <= heap->last ; i++) (action)(heap->array[i], uap); } diff --git a/lib/isc/include/isc/heap.h b/lib/isc/include/isc/heap.h index 2e97b625b6..ff11370b32 100644 --- a/lib/isc/include/isc/heap.h +++ b/lib/isc/include/isc/heap.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: heap.h,v 1.19 2005/04/29 00:23:37 marka Exp $ */ +/* $Id: heap.h,v 1.20 2006/04/10 16:28:04 explorer Exp $ */ #ifndef ISC_HEAP_H #define ISC_HEAP_H 1 @@ -33,20 +33,137 @@ ISC_LANG_BEGINDECLS */ typedef isc_boolean_t (*isc_heapcompare_t)(void *, void *); +/*% + * The index function allows the client of the heap to receive a callback + * when an item's index number changes. This allows it to maintain + * sync with its external state, but still delete itself, since deletions + * from the heap require the index be provided. + */ typedef void (*isc_heapindex_t)(void *, unsigned int); + +/*% + * The heapaction function is used when iterating over the heap. + * + * NOTE: The heap structure CANNOT BE MODIFIED during the call to + * isc_heap_foreach(). + */ typedef void (*isc_heapaction_t)(void *, void *); typedef struct isc_heap isc_heap_t; -isc_result_t isc_heap_create(isc_mem_t *, isc_heapcompare_t, - isc_heapindex_t, unsigned int, isc_heap_t **); -void isc_heap_destroy(isc_heap_t **); -isc_result_t isc_heap_insert(isc_heap_t *, void *); -void isc_heap_delete(isc_heap_t *, unsigned int); -void isc_heap_increased(isc_heap_t *, unsigned int); -void isc_heap_decreased(isc_heap_t *, unsigned int); -void * isc_heap_element(isc_heap_t *, unsigned int); -void isc_heap_foreach(isc_heap_t *, isc_heapaction_t, void *); +isc_result_t +isc_heap_create(isc_mem_t *mctx, isc_heapcompare_t compare, + isc_heapindex_t index, unsigned int size_increment, + isc_heap_t **heapp); +/*!< + * \brief Create a new heap. The heap is implemented using a space-efficient + * storage method. When the heap elements are deleted space is not freed + * but will be reused when new elements are inserted. + * + * Requires: + *\li "mctx" is valid. + *\li "compare" is a function which takes two void * arguments and + * returns ISC_TRUE if the first argument has a higher priority than + * the second, and ISC_FALSE otherwise. + *\li "index" is a function which takes a void *, and an unsigned int + * argument. This function will be called whenever an element's + * index value changes, so it may continue to delete itself from the + * heap. This option may be NULL if this functionality is unneeded. + *\li "size_increment" is a hint about how large the heap should grow + * when resizing is needed. If this is 0, a default size will be + * used, which is currently 1024, allowing space for an additional 1024 + * heap elements to be inserted before adding more space. + *\li "heapp" is not NULL, and "*heap" is NULL. + * + * Returns: + *\li ISC_R_SUCCESS - success + *\li ISC_R_NOMEMORY - insufficient memory + */ + +void +isc_heap_destroy(isc_heap_t **heapp); +/*!< + * \brief Destroys a heap. + * + * Requires: + *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t. + */ + +isc_result_t +isc_heap_insert(isc_heap_t *heap, void *elt); +/*!< + * \brief Inserts a new element into a heap. + * + * Requires: + *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t. + */ + +void +isc_heap_delete(isc_heap_t *heap, unsigned int index); +/*!< + * \brief Deletes an element from a heap, by element index. + * + * Requires: + *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t. + *\li "index" is a valid element index, as provided by the "index" callback + * provided during heap creation. + */ + +void +isc_heap_increased(isc_heap_t *heap, unsigned int index); +/*!< + * \brief Indicates to the heap that an element's priority has increased. + * This function MUST be called whenever an element has increased in priority. + * + * Requires: + *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t. + *\li "index" is a valid element index, as provided by the "index" callback + * provided during heap creation. + */ + +void +isc_heap_decreased(isc_heap_t *heap, unsigned int index); +/*!< + * \brief Indicates to the heap that an element's priority has decreased. + * This function MUST be called whenever an element has decreased in priority. + * + * Requires: + *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t. + *\li "index" is a valid element index, as provided by the "index" callback + * provided during heap creation. + */ + +void * +isc_heap_element(isc_heap_t *heap, unsigned int index); +/*!< + * \brief Returns the element for a specific element index. + * + * Requires: + *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t. + *\li "index" is a valid element index, as provided by the "index" callback + * provided during heap creation. + * + * Returns: + *\li A pointer to the element for the element index. + */ + +void +isc_heap_foreach(isc_heap_t *heap, isc_heapaction_t action, void *uap); +/*!< + * \brief Iterate over the heap, calling an action for each element. The + * order of iteration is not sorted. + * + * Requires: + *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t. + *\li "action" is not NULL, and is a function which takes two arguments. + * The first is a void *, representing the element, and the second is + * "uap" as provided to isc_heap_foreach. + *\li "uap" is a caller-provided argument, and may be NULL. + * + * Note: + *\li The heap structure CANNOT be modified during this iteration. The only + * safe function to call while iterating the heap is isc_heap_element(). + */ ISC_LANG_ENDDECLS