2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 23:25:38 +00:00

Documentation changes; no functional changes. Some variables were renamed from 'i' to 'index' in heap.h so documentation can be nicer.

This commit is contained in:
Michael Graff
2006-04-10 16:28:04 +00:00
parent 069a2ad007
commit 80a63e1574
2 changed files with 149 additions and 35 deletions

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 /*! \file
* Heap implementation of priority queues adapted from the following: * 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 * 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, * 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_parent(i) ((i) >> 1)
#define heap_left(i) ((i) << 1) #define heap_left(i) ((i) << 1)
@@ -71,7 +72,6 @@ struct isc_heap {
isc_heapindex_t index; isc_heapindex_t index;
}; };
/*% Create a heap. */
isc_result_t isc_result_t
isc_heap_create(isc_mem_t *mctx, isc_heapcompare_t compare, isc_heap_create(isc_mem_t *mctx, isc_heapcompare_t compare,
isc_heapindex_t index, unsigned int size_increment, 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); return (ISC_R_SUCCESS);
} }
/*% Destroy a heap. */
void void
isc_heap_destroy(isc_heap_t **heapp) { isc_heap_destroy(isc_heap_t **heapp) {
isc_heap_t *heap; isc_heap_t *heap;
@@ -146,8 +145,8 @@ static void
float_up(isc_heap_t *heap, unsigned int i, void *elt) { float_up(isc_heap_t *heap, unsigned int i, void *elt) {
unsigned int p; unsigned int p;
for (p = heap_parent(i); for (p = heap_parent(i) ;
i > 1 && heap->compare(elt, heap->array[p]); i > 1 && heap->compare(elt, heap->array[p]) ;
i = p, p = heap_parent(i)) { i = p, p = heap_parent(i)) {
heap->array[i] = heap->array[p]; heap->array[i] = heap->array[p];
if (heap->index != NULL) if (heap->index != NULL)
@@ -185,7 +184,6 @@ sink_down(isc_heap_t *heap, unsigned int i, void *elt) {
INSIST(HEAPCONDITION(i)); INSIST(HEAPCONDITION(i));
} }
/*% Insert a heap. */
isc_result_t isc_result_t
isc_heap_insert(isc_heap_t *heap, void *elt) { isc_heap_insert(isc_heap_t *heap, void *elt) {
unsigned int i; unsigned int i;
@@ -201,50 +199,49 @@ isc_heap_insert(isc_heap_t *heap, void *elt) {
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
} }
/*% Delete a heap. */
void void
isc_heap_delete(isc_heap_t *heap, unsigned int i) { isc_heap_delete(isc_heap_t *heap, unsigned int index) {
void *elt; void *elt;
isc_boolean_t less; isc_boolean_t less;
REQUIRE(VALID_HEAP(heap)); 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--; heap->last--;
} else { } else {
elt = heap->array[heap->last--]; elt = heap->array[heap->last--];
less = heap->compare(elt, heap->array[i]); less = heap->compare(elt, heap->array[index]);
heap->array[i] = elt; heap->array[index] = elt;
if (less) if (less)
float_up(heap, i, heap->array[i]); float_up(heap, index, heap->array[index]);
else else
sink_down(heap, i, heap->array[i]); sink_down(heap, index, heap->array[index]);
} }
} }
void 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(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 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(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 * 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(VALID_HEAP(heap));
REQUIRE(i >= 1 && i <= heap->last); REQUIRE(index >= 1 && index <= heap->last);
return (heap->array[i]); return (heap->array[index]);
} }
void void
@@ -254,6 +251,6 @@ isc_heap_foreach(isc_heap_t *heap, isc_heapaction_t action, void *uap) {
REQUIRE(VALID_HEAP(heap)); REQUIRE(VALID_HEAP(heap));
REQUIRE(action != NULL); REQUIRE(action != NULL);
for (i = 1; i <= heap->last; i++) for (i = 1 ; i <= heap->last ; i++)
(action)(heap->array[i], uap); (action)(heap->array[i], uap);
} }

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 #ifndef ISC_HEAP_H
#define ISC_HEAP_H 1 #define ISC_HEAP_H 1
@@ -33,20 +33,137 @@ ISC_LANG_BEGINDECLS
*/ */
typedef isc_boolean_t (*isc_heapcompare_t)(void *, void *); 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); 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 void (*isc_heapaction_t)(void *, void *);
typedef struct isc_heap isc_heap_t; typedef struct isc_heap isc_heap_t;
isc_result_t isc_heap_create(isc_mem_t *, isc_heapcompare_t, isc_result_t
isc_heapindex_t, unsigned int, isc_heap_t **); isc_heap_create(isc_mem_t *mctx, isc_heapcompare_t compare,
void isc_heap_destroy(isc_heap_t **); isc_heapindex_t index, unsigned int size_increment,
isc_result_t isc_heap_insert(isc_heap_t *, void *); isc_heap_t **heapp);
void isc_heap_delete(isc_heap_t *, unsigned int); /*!<
void isc_heap_increased(isc_heap_t *, unsigned int); * \brief Create a new heap. The heap is implemented using a space-efficient
void isc_heap_decreased(isc_heap_t *, unsigned int); * storage method. When the heap elements are deleted space is not freed
void * isc_heap_element(isc_heap_t *, unsigned int); * but will be reused when new elements are inserted.
void isc_heap_foreach(isc_heap_t *, isc_heapaction_t, void *); *
* 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 ISC_LANG_ENDDECLS