heap.c revision af669cb4fd7ecfb67ed145b176e5e764b249573b
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff/*
499b34cea04a46823d003d4c0520c8b03e8513cbBrian Wellington * Copyright (C) 2004-2007, 2010-2014 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Copyright (C) 1997-2001 Internet Software Consortium.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff *
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Permission to use, copy, modify, and/or distribute this software for any
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * purpose with or without fee is hereby granted, provided that the above
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * copyright notice and this permission notice appear in all copies.
15a44745412679c30a6d022733925af70a38b715David Lawrence *
15a44745412679c30a6d022733925af70a38b715David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
15a44745412679c30a6d022733925af70a38b715David Lawrence * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15a44745412679c30a6d022733925af70a38b715David Lawrence * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
15a44745412679c30a6d022733925af70a38b715David Lawrence * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15a44745412679c30a6d022733925af70a38b715David Lawrence * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15a44745412679c30a6d022733925af70a38b715David Lawrence * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15a44745412679c30a6d022733925af70a38b715David Lawrence * PERFORMANCE OF THIS SOFTWARE.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews/* $Id$ */
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff/*! \file
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Heap implementation of priority queues adapted from the following:
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff *
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * \li "Introduction to Algorithms," Cormen, Leiserson, and Rivest,
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * MIT Press / McGraw Hill, 1990, ISBN 0-262-03141-8, chapter 7.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff *
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * \li "Algorithms," Second Edition, Sedgewick, Addison-Wesley, 1988,
6028d1ce0380d0ba7f6c6ecd1ad20b31ddd1becbDavid Lawrence * ISBN 0-201-06673-4, chapter 11.
364a82f7c25b62967678027043425201a5e5171aBob Halley */
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <config.h>
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence#include <isc/heap.h>
7d823f705d9d3a8cb4d43fcf11249515e2845364Andreas Gustafsson#include <isc/magic.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <isc/mem.h>
294ae26fb3e1376b4c34c6b8d15737e39cc2cb48Andreas Gustafsson#include <isc/string.h> /* Required for memmove. */
dc570b92f6cc60def4207733c7a194fbb69a4399Michael Sawyer#include <isc/util.h>
294ae26fb3e1376b4c34c6b8d15737e39cc2cb48Andreas Gustafsson
f9df80f4348ef68043903efa08299480324f4823Michael Graff/*@{*/
f9df80f4348ef68043903efa08299480324f4823Michael Graff/*%
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence * Note: to make heap_parent and heap_left easy to compute, the first
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * element of the heap array is not used; i.e. heap subscripts are 1-based,
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence * not 0-based. The parent is index/2, and the left-child is index*2.
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington * The right child is index*2+1.
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#define heap_parent(i) ((i) >> 1)
75ec9bc9c7b4f2485647414330122e7b8e188097Andreas Gustafsson#define heap_left(i) ((i) << 1)
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley/*@}*/
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff#define SIZE_INCREMENT 1024
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley#define HEAP_MAGIC ISC_MAGIC('H', 'E', 'A', 'P')
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley#define VALID_HEAP(h) ISC_MAGIC_VALID(h, HEAP_MAGIC)
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
f9df80f4348ef68043903efa08299480324f4823Michael Graff/*%
f9df80f4348ef68043903efa08299480324f4823Michael Graff * When the heap is in a consistent state, the following invariant
f9df80f4348ef68043903efa08299480324f4823Michael Graff * holds true: for every element i > 1, heap_parent(i) has a priority
f9df80f4348ef68043903efa08299480324f4823Michael Graff * higher than or equal to that of i.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington#define HEAPCONDITION(i) ((i) == 1 || \
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington ! heap->compare(heap->array[(i)], \
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington heap->array[heap_parent(i)]))
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer/*% ISC heap structure. */
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyerstruct isc_heap {
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned int magic;
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_mem_t * mctx;
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned int size;
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned int size_increment;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff unsigned int last;
f9df80f4348ef68043903efa08299480324f4823Michael Graff void **array;
e223094b2248afa2697c531f75e6f84855638becMichael Graff isc_heapcompare_t compare;
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff isc_heapindex_t index;
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff};
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graffisc_result_t
f9df80f4348ef68043903efa08299480324f4823Michael Graffisc_heap_create(isc_mem_t *mctx, isc_heapcompare_t compare,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_heapindex_t idx, unsigned int size_increment,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_heap_t **heapp)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer{
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_heap_t *heap;
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(heapp != NULL && *heapp == NULL);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(compare != NULL);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer heap = isc_mem_get(mctx, sizeof(*heap));
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (heap == NULL)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer return (ISC_R_NOMEMORY);
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer heap->magic = HEAP_MAGIC;
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer heap->size = 0;
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer heap->mctx = NULL;
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer isc_mem_attach(mctx, &heap->mctx);
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer if (size_increment == 0)
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer heap->size_increment = SIZE_INCREMENT;
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer else
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence heap->size_increment = size_increment;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer heap->last = 0;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer heap->array = NULL;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer heap->compare = compare;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer heap->index = idx;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer *heapp = heap;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer return (ISC_R_SUCCESS);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer}
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyervoid
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerisc_heap_destroy(isc_heap_t **heapp) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_heap_t *heap;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(heapp != NULL);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer heap = *heapp;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(VALID_HEAP(heap));
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence if (heap->array != NULL)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_mem_put(heap->mctx, heap->array,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer heap->size * sizeof(void *));
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer heap->magic = 0;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_mem_putanddetach(&heap->mctx, heap, sizeof(*heap));
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer *heapp = NULL;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer}
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerstatic isc_boolean_t
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerresize(isc_heap_t *heap) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer void **new_array;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer unsigned int new_size;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(VALID_HEAP(heap));
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer new_size = heap->size + heap->size_increment;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer new_array = isc_mem_get(heap->mctx, new_size * sizeof(void *));
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (new_array == NULL)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer return (ISC_FALSE);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (heap->array != NULL) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff memmove(new_array, heap->array, heap->size * sizeof(void *));
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_mem_put(heap->mctx, heap->array,
f9df80f4348ef68043903efa08299480324f4823Michael Graff heap->size * sizeof(void *));
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff heap->size = new_size;
f9df80f4348ef68043903efa08299480324f4823Michael Graff heap->array = new_array;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff return (ISC_TRUE);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic void
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Grafffloat_up(isc_heap_t *heap, unsigned int i, void *elt) {
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff unsigned int p;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff for (p = heap_parent(i) ;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff i > 1 && heap->compare(elt, heap->array[p]) ;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff i = p, p = heap_parent(i)) {
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff heap->array[i] = heap->array[p];
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (heap->index != NULL)
f9df80f4348ef68043903efa08299480324f4823Michael Graff (heap->index)(heap->array[i], i);
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff heap->array[i] = elt;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff if (heap->index != NULL)
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff (heap->index)(heap->array[i], i);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff INSIST(HEAPCONDITION(i));
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff}
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic void
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffsink_down(isc_heap_t *heap, unsigned int i, void *elt) {
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff unsigned int j, size, half_size;
f9df80f4348ef68043903efa08299480324f4823Michael Graff size = heap->last;
f9df80f4348ef68043903efa08299480324f4823Michael Graff half_size = size / 2;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff while (i <= half_size) {
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff /* Find the smallest of the (at most) two children. */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff j = heap_left(i);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff if (j < size && heap->compare(heap->array[j+1],
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff heap->array[j]))
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff j++;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff if (heap->compare(elt, heap->array[j]))
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff break;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff heap->array[i] = heap->array[j];
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff if (heap->index != NULL)
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff (heap->index)(heap->array[i], i);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff i = j;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff }
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff heap->array[i] = elt;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff if (heap->index != NULL)
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff (heap->index)(heap->array[i], i);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff INSIST(HEAPCONDITION(i));
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff}
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffisc_result_t
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffisc_heap_insert(isc_heap_t *heap, void *elt) {
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff unsigned int new_last;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff REQUIRE(VALID_HEAP(heap));
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
8c55a67a6d185de7036e39da30561a5c1637d22bAndreas Gustafsson new_last = heap->last + 1;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff RUNTIME_CHECK(new_last > 0); /* overflow check */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff if (new_last >= heap->size && !resize(heap))
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff return (ISC_R_NOMEMORY);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff heap->last = new_last;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff float_up(heap, new_last, elt);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff return (ISC_R_SUCCESS);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff}
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffvoid
f9df80f4348ef68043903efa08299480324f4823Michael Graffisc_heap_delete(isc_heap_t *heap, unsigned int idx) {
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence void *elt;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isc_boolean_t less;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(VALID_HEAP(heap));
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff REQUIRE(idx >= 1 && idx <= heap->last);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff if (idx == heap->last) {
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff heap->array[heap->last] = NULL;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence heap->last--;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff } else {
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff elt = heap->array[heap->last];
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff heap->array[heap->last] = NULL;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff heap->last--;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff less = heap->compare(elt, heap->array[idx]);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff heap->array[idx] = elt;
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (less)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff float_up(heap, idx, heap->array[idx]);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff else
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff sink_down(heap, idx, heap->array[idx]);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencevoid
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffisc_heap_increased(isc_heap_t *heap, unsigned int idx) {
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff REQUIRE(VALID_HEAP(heap));
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff REQUIRE(idx >= 1 && idx <= heap->last);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence float_up(heap, idx, heap->array[idx]);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffvoid
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffisc_heap_decreased(isc_heap_t *heap, unsigned int idx) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff REQUIRE(VALID_HEAP(heap));
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff REQUIRE(idx >= 1 && idx <= heap->last);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff sink_down(heap, idx, heap->array[idx]);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence}
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffvoid *
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffisc_heap_element(isc_heap_t *heap, unsigned int idx) {
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff REQUIRE(VALID_HEAP(heap));
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff REQUIRE(idx >= 1);
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (idx <= heap->last)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (heap->array[idx]);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (NULL);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence}
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffvoid
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffisc_heap_foreach(isc_heap_t *heap, isc_heapaction_t action, void *uap) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff unsigned int i;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff REQUIRE(VALID_HEAP(heap));
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff REQUIRE(action != NULL);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff for (i = 1 ; i <= heap->last ; i++)
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff (action)(heap->array[i], uap);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff