pull up my changes from the mainline, to v9_3

This commit is contained in:
Michael Graff 2006-04-17 18:27:20 +00:00
parent 251d3142a6
commit 186afeb58b
4 changed files with 173 additions and 47 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2004 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
@ -15,15 +15,15 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: heap.c,v 1.28.12.3 2004/03/08 09:04:48 marka Exp $ */
/* $Id: heap.c,v 1.28.12.4 2006/04/17 18:27:20 explorer Exp $ */
/*
/*! \file
* Heap implementation of priority queues adapted from the following:
*
* _Introduction to Algorithms_, Cormen, Leiserson, and Rivest,
* \li "Introduction to Algorithms," Cormen, Leiserson, and Rivest,
* MIT Press / McGraw Hill, 1990, ISBN 0-262-03141-8, chapter 7.
*
* _Algorithms_, Second Edition, Sedgewick, Addison-Wesley, 1988,
* \li "Algorithms," Second Edition, Sedgewick, Addison-Wesley, 1988,
* ISBN 0-201-06673-4, chapter 11.
*/
@ -35,20 +35,23 @@
#include <isc/string.h> /* Required for memcpy. */
#include <isc/util.h>
/*
/*@{*/
/*%
* 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)
/*@}*/
#define SIZE_INCREMENT 1024
#define HEAP_MAGIC ISC_MAGIC('H', 'E', 'A', 'P')
#define VALID_HEAP(h) ISC_MAGIC_VALID(h, HEAP_MAGIC)
/*
/*%
* When the heap is in a consistent state, the following invariant
* holds true: for every element i > 1, heap_parent(i) has a priority
* higher than or equal to that of i.
@ -57,6 +60,7 @@
! heap->compare(heap->array[(i)], \
heap->array[heap_parent(i)]))
/*% ISC heap structure. */
struct isc_heap {
unsigned int magic;
isc_mem_t * mctx;
@ -141,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)
@ -196,48 +200,48 @@ isc_heap_insert(isc_heap_t *heap, void *elt) {
}
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
@ -247,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);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2004 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
@ -15,36 +15,155 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: heap.h,v 1.16.206.1 2004/03/06 08:14:41 marka Exp $ */
/* $Id: heap.h,v 1.16.206.2 2006/04/17 18:27:20 explorer Exp $ */
#ifndef ISC_HEAP_H
#define ISC_HEAP_H 1
/*! \file */
#include <isc/lang.h>
#include <isc/types.h>
ISC_LANG_BEGINDECLS
/*
/*%
* The comparision function returns ISC_TRUE if the first argument has
* higher priority than the second argument, and ISC_FALSE otherwise.
*/
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

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2004 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
@ -15,12 +15,15 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: print.c,v 1.22.2.3.2.3 2004/03/06 08:14:33 marka Exp $ */
/* $Id: print.c,v 1.22.2.3.2.4 2006/04/17 18:27:20 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. */
@ -41,7 +44,7 @@ isc_print_sprintf(char *str, const char *format, ...) {
return (strlen(str));
}
/*
/*!
* Return length of string that would have been written if not truncated.
*/
@ -57,7 +60,7 @@ isc_print_snprintf(char *str, size_t size, const char *format, ...) {
}
/*
/*!
* Return length of string that would have been written if not truncated.
*/

View file

@ -1902,7 +1902,7 @@
./lib/isc/event.c C 1998,1999,2000,2001,2004
./lib/isc/fsaccess.c C 2000,2001,2004
./lib/isc/hash.c C 2003,2004,2006
./lib/isc/heap.c C 1997,1998,1999,2000,2001,2004
./lib/isc/heap.c C 1997,1998,1999,2000,2001,2004,2005,2006
./lib/isc/hex.c C 2000,2001,2002,2003,2004
./lib/isc/hmacmd5.c C 2000,2001,2004,2006
./lib/isc/include/.cvsignore X 1999,2000,2001
@ -1925,7 +1925,7 @@
./lib/isc/include/isc/formatcheck.h C 2000,2001,2004
./lib/isc/include/isc/fsaccess.h C 2000,2001,2004
./lib/isc/include/isc/hash.h C 2003,2004
./lib/isc/include/isc/heap.h C 1997,1998,1999,2000,2001,2004
./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
./lib/isc/include/isc/hmacmd5.h C 2000,2001,2004
./lib/isc/include/isc/interfaceiter.h C 1999,2000,2001,2004
@ -2002,7 +2002,7 @@
./lib/isc/nothreads/thread.c C 2000,2001,2004
./lib/isc/ondestroy.c C 2000,2001,2004
./lib/isc/parseint.c C 2001,2002,2003,2004
./lib/isc/print.c C 1999,2000,2001,2003,2004
./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