/*
- * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1997-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: heap.c,v 1.30.18.2 2005/04/29 00:16:46 marka Exp $ */
+/* $Id: heap.c,v 1.30.18.3 2006/04/17 18:27:33 explorer Exp $ */
/*! \file
* Heap implementation of priority queues adapted from the following:
/*%
* 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)
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,
return (ISC_R_SUCCESS);
}
-/*% Destroy a heap. */
void
isc_heap_destroy(isc_heap_t **heapp) {
isc_heap_t *heap;
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)
INSIST(HEAPCONDITION(i));
}
-/*% Insert a heap. */
isc_result_t
isc_heap_insert(isc_heap_t *heap, void *elt) {
unsigned int i;
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
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);
}
/*
- * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1997-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: heap.h,v 1.17.18.2 2005/04/29 00:16:55 marka Exp $ */
+/* $Id: heap.h,v 1.17.18.3 2006/04/17 18:27:33 explorer Exp $ */
#ifndef ISC_HEAP_H
#define ISC_HEAP_H 1
*/
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
/*
- * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: print.c,v 1.27.18.2 2005/04/29 00:16:48 marka Exp $ */
+/* $Id: print.c,v 1.27.18.3 2006/04/17 18:27:33 explorer Exp $ */
/*! \file */
#include <config.h>
#include <ctype.h>
-#include <stdio.h> /* for sprintf */
+#include <stdio.h> /* for sprintf() */
+#include <string.h> /* for strlen() */
#define ISC__PRINT_SOURCE /* Used to get the isc_print_* prototypes. */
./lib/isc/event.c C 1998,1999,2000,2001,2004,2005
./lib/isc/fsaccess.c C 2000,2001,2004,2005
./lib/isc/hash.c C 2003,2004,2005,2006
-./lib/isc/heap.c C 1997,1998,1999,2000,2001,2004,2005
+./lib/isc/heap.c C 1997,1998,1999,2000,2001,2004,2005,2006
./lib/isc/hex.c C 2000,2001,2002,2003,2004,2005
./lib/isc/hmacmd5.c C 2000,2001,2004,2005,2006
./lib/isc/hmacsha.c C 2005,2006
./lib/isc/include/isc/formatcheck.h C 2000,2001,2004,2005
./lib/isc/include/isc/fsaccess.h C 2000,2001,2004,2005
./lib/isc/include/isc/hash.h C 2003,2004,2005
-./lib/isc/include/isc/heap.h C 1997,1998,1999,2000,2001,2004,2005
+./lib/isc/include/isc/heap.h C 1997,1998,1999,2000,2001,2004,2005,2006
./lib/isc/include/isc/hex.h C 2000,2001,2004,2005
./lib/isc/include/isc/hmacmd5.h C 2000,2001,2004,2005,2006
./lib/isc/include/isc/hmacsha.h C 2005,2006
./lib/isc/ondestroy.c C 2000,2001,2004,2005
./lib/isc/parseint.c C 2001,2002,2003,2004,2005
./lib/isc/powerpc/include/isc/atomic.h C 2005
-./lib/isc/print.c C 1999,2000,2001,2003,2004,2005
+./lib/isc/print.c C 1999,2000,2001,2003,2004,2005,2006
./lib/isc/pthreads/.cvsignore X 1999,2000,2001
./lib/isc/pthreads/Makefile.in MAKE 1998,1999,2000,2001,2004
./lib/isc/pthreads/condition.c C 1998,1999,2000,2001,2004,2005