Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ambrop72/badvpn.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorambrop7 <ambrop7@1a93d707-3861-5ebc-ad3b-9740d49b5140>2012-09-01 04:33:17 +0400
committerambrop7 <ambrop7@1a93d707-3861-5ebc-ad3b-9740d49b5140>2012-09-01 04:33:17 +0400
commit1a842753018752e26cfabc18db7af839375fb363 (patch)
tree98e9461e806f4c884a125438f351fcdd229a8dbc /structure
parent965936585fb196eee6d8299829faaa5082fec6a2 (diff)
structure: remove BHeap
Diffstat (limited to 'structure')
-rw-r--r--structure/BHeap.h457
1 files changed, 0 insertions, 457 deletions
diff --git a/structure/BHeap.h b/structure/BHeap.h
deleted file mode 100644
index 6eb3e25..0000000
--- a/structure/BHeap.h
+++ /dev/null
@@ -1,457 +0,0 @@
-/**
- * @file BHeap.h
- * @author Ambroz Bizjak <ambrop7@gmail.com>
- *
- * @section LICENSE
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the author nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @section DESCRIPTION
- *
- * Binary heap.
- */
-
-#ifndef BADVPN_STRUCTURE_BHEAP_H
-#define BADVPN_STRUCTURE_BHEAP_H
-
-//#define BHEAP_DEBUG
-
-#include <stdint.h>
-#include <stddef.h>
-
-#include <misc/debug.h>
-
-/**
- * Handler function called by heap algorithms to compare two values.
- * For any two values, the comparator must always return the same result.
- * The <= relation defined by the comparator must be a total order.
- * Values are obtained like that:
- * - The value of a node in the heap, or a node that is being inserted is:
- * (uint8_t *)node + offset.
- * - The value being looked up is the same as given to the lookup function.
- *
- * @param user as in {@link BHeap_Init}
- * @param val1 first value
- * @param val2 second value
- * @return -1 if val1 < val2, 0 if val1 = val2, 1 if val1 > val2
- */
-typedef int (*BHeap_comparator) (void *user, void *val1, void *val2);
-
-struct BHeapNode;
-
-/**
- * Binary heap.
- */
-typedef struct {
- int offset;
- BHeap_comparator comparator;
- void *user;
- struct BHeapNode *root;
- struct BHeapNode *last;
- #ifndef NDEBUG
- int in_handler;
- #endif
-} BHeap;
-
-/**
- * Binary heap node.
- */
-typedef struct BHeapNode {
- struct BHeapNode *parent;
- struct BHeapNode *link[2];
-} BHeapNode;
-
-/**
- * Initializes the heap.
- *
- * @param o heap to initialize
- * @param offset offset of a value from its node
- * @param comparator value comparator handler function
- * @param user value to pass to comparator
- */
-static void BHeap_Init (BHeap *h, int offset, BHeap_comparator comparator, void *user);
-
-/**
- * Inserts a node into the heap.
- * Must not be called from comparator.
- *
- * @param o the heap
- * @param node uninitialized node to insert. Must have a valid value (its value
- * may be passed to the comparator during insertion).
- */
-static void BHeap_Insert (BHeap *h, BHeapNode *node);
-
-/**
- * Removes a node from the heap.
- * Must not be called from comparator.
- *
- * @param o the heap
- * @param node node to remove
- */
-static void BHeap_Remove (BHeap *h, BHeapNode *node);
-
-/**
- * Returns one of the smallest nodes in the heap.
- * Must not be called from comparator.
- *
- * @param o the heap
- * @return one of the smallest nodes in the heap, or NULL if there
- * are no nodes
- */
-static BHeapNode * BHeap_GetFirst (BHeap *h);
-
-static void * _BHeap_node_value (BHeap *o, BHeapNode *n)
-{
- return ((uint8_t *)n + o->offset);
-}
-
-static int _BHeap_compare_values (BHeap *o, void *v1, void *v2)
-{
- #ifndef NDEBUG
- o->in_handler = 1;
- #endif
-
- int res = o->comparator(o->user, v1, v2);
-
- #ifndef NDEBUG
- o->in_handler = 0;
- #endif
-
- ASSERT(res == -1 || res == 0 || res == 1)
-
- return res;
-}
-
-static int _BHeap_compare_nodes (BHeap *o, BHeapNode *n1, BHeapNode *n2)
-{
- return _BHeap_compare_values(o, _BHeap_node_value(o, n1), _BHeap_node_value(o, n2));
-}
-
-#ifdef BHEAP_DEBUG
-#define BHEAP_ASSERT(_h) _BHeap_assert(_h);
-#else
-#define BHEAP_ASSERT(_h)
-#endif
-
-#ifdef BHEAP_DEBUG
-
-struct _BHeap_assert_data {
- int state;
- int level;
- BHeapNode *prev_leaf;
-};
-
-#define BHEAP_ASSERT_STATE_NODEPTH 1
-#define BHEAP_ASSERT_STATE_LOWEST 2
-#define BHEAP_ASSERT_STATE_LOWESTEND 3
-
-static void _BHeap_assert_recurser (BHeap *h, BHeapNode *n, struct _BHeap_assert_data *ad, int level)
-{
- if (!n->link[0] && !n->link[1]) {
- if (ad->state == BHEAP_ASSERT_STATE_NODEPTH) {
- // leftmost none, remember depth
- ad->state = BHEAP_ASSERT_STATE_LOWEST;
- ad->level = level;
- }
- } else {
- // drop down
- if (n->link[0]) {
- ASSERT(_BHeap_compare_nodes(h, n, n->link[0]) <= 0)
- ASSERT(n->link[0]->parent == n)
- _BHeap_assert_recurser(h, n->link[0], ad, level + 1);
- }
- if (n->link[1]) {
- ASSERT(_BHeap_compare_nodes(h, n, n->link[1]) <= 0)
- ASSERT(n->link[1]->parent == n)
- _BHeap_assert_recurser(h, n->link[1], ad, level + 1);
- }
- }
-
- ASSERT(ad->state == BHEAP_ASSERT_STATE_LOWEST || ad->state == BHEAP_ASSERT_STATE_LOWESTEND)
-
- if (level < ad->level - 1) {
- ASSERT(n->link[0] && n->link[1])
- }
- else if (level == ad->level - 1) {
- switch (ad->state) {
- case BHEAP_ASSERT_STATE_LOWEST:
- if (!n->link[0]) {
- ad->state = BHEAP_ASSERT_STATE_LOWESTEND;
- ASSERT(!n->link[1])
- ASSERT(ad->prev_leaf == h->last)
- } else {
- if (!n->link[1]) {
- ad->state = BHEAP_ASSERT_STATE_LOWESTEND;
- ASSERT(ad->prev_leaf == h->last)
- }
- }
- break;
- case BHEAP_ASSERT_STATE_LOWESTEND:
- ASSERT(!n->link[0] && !n->link[1])
- break;
- }
- }
- else if (level == ad->level) {
- ASSERT(ad->state == BHEAP_ASSERT_STATE_LOWEST)
- ASSERT(!n->link[0] && !n->link[1])
- ad->prev_leaf = n;
- }
- else {
- ASSERT(0)
- }
-}
-
-static void _BHeap_assert (BHeap *h)
-{
- struct _BHeap_assert_data ad;
- ad.state = BHEAP_ASSERT_STATE_NODEPTH;
- ad.prev_leaf = NULL;
-
- if (h->root) {
- ASSERT(h->last)
- ASSERT(!h->root->parent)
- _BHeap_assert_recurser(h, h->root, &ad, 0);
- if (ad.state == BHEAP_ASSERT_STATE_LOWEST) {
- ASSERT(ad.prev_leaf == h->last)
- }
- } else {
- ASSERT(!h->last)
- }
-}
-
-#endif
-
-static void _BHeap_move_one_up (BHeap *h, BHeapNode *n)
-{
- ASSERT(n->parent)
-
- BHeapNode *p = n->parent;
-
- if (p->parent) {
- p->parent->link[p == p->parent->link[1]] = n;
- } else {
- h->root = n;
- }
- n->parent = p->parent;
-
- int nside = (n == p->link[1]);
- BHeapNode *c = p->link[!nside];
-
- p->link[0] = n->link[0];
- if (p->link[0]) {
- p->link[0]->parent = p;
- }
-
- p->link[1] = n->link[1];
- if (p->link[1]) {
- p->link[1]->parent = p;
- }
-
- n->link[nside] = p;
- p->parent = n;
-
- n->link[!nside] = c;
- if (c) {
- c->parent = n;
- }
-
- if (n == h->last) {
- h->last = p;
- }
-}
-
-static void _BHeap_replace_node (BHeap *h, BHeapNode *d, BHeapNode *s)
-{
- if (d->parent) {
- d->parent->link[d == d->parent->link[1]] = s;
- } else {
- h->root = s;
- }
- s->parent = d->parent;
-
- s->link[0] = d->link[0];
- if (s->link[0]) {
- s->link[0]->parent = s;
- }
-
- s->link[1] = d->link[1];
- if (s->link[1]) {
- s->link[1]->parent = s;
- }
-}
-
-void BHeap_Init (BHeap *h, int offset, BHeap_comparator comparator, void *user)
-{
- h->offset = offset;
- h->comparator = comparator;
- h->user = user;
- h->root = NULL;
- h->last = NULL;
-
- #ifndef NDEBUG
- h->in_handler = 0;
- #endif
-
- BHEAP_ASSERT(h)
-}
-
-void BHeap_Insert (BHeap *h, BHeapNode *node)
-{
- ASSERT(!h->in_handler)
-
- if (!h->root) {
- // insert to root
- h->root = node;
- h->last = node;
- node->parent = NULL;
- node->link[0] = NULL;
- node->link[1] = NULL;
-
- BHEAP_ASSERT(h)
- return;
- }
-
- // find the node to insert to
-
- // start with current last node and walk up left as much as possible.
- // That is, keep replacing the current node with the parent as long as it
- // exists and the current node is its right child.
- BHeapNode *cur = h->last;
- while (cur->parent && cur == cur->parent->link[1]) {
- cur = cur->parent;
- }
-
- if (cur->parent) {
- if (cur->parent->link[1]) {
- // have parent and parent has right child. Attach the new node
- // to the leftmost node of the parent's right subtree.
- cur = cur->parent->link[1];
- while (cur->link[0]) {
- cur = cur->link[0];
- }
- } else {
- // have parent, but parent has no right child. This can
- // only happen when the last node is a right child. So
- // attach the new node to its parent.
- cur = cur->parent;
- }
- } else {
- // have no parent, attach the new node to a new level. We're at the
- // root, so drop down left to obtain the node where we'll attach
- // the new node.
- while (cur->link[0]) {
- cur = cur->link[0];
- }
- }
-
- ASSERT((!cur->link[0] && !cur->link[1]) || (cur->link[0] && !cur->link[1]))
-
- // attach new node
- // the new node becomes the new last node
- h->last = node;
- cur->link[!!cur->link[0]] = node;
- node->parent = cur;
- node->link[0] = NULL;
- node->link[1] = NULL;
-
- // restore heap property
- while (node->parent && _BHeap_compare_nodes(h, node->parent, node) > 0) {
- _BHeap_move_one_up(h, node);
- }
-
- BHEAP_ASSERT(h)
-}
-
-void BHeap_Remove (BHeap *h, BHeapNode *node)
-{
- ASSERT(!h->in_handler)
-
- if (!node->parent && !node->link[0] && !node->link[1]) {
- h->root = NULL;
- h->last = NULL;
-
- BHEAP_ASSERT(h)
- return;
- }
-
- // locate the node before the last node
- BHeapNode *cur = h->last;
- while (cur->parent && cur == cur->parent->link[0]) {
- cur = cur->parent;
- }
- if (cur->parent) {
- ASSERT(cur->parent->link[0])
- cur = cur->parent->link[0];
- while (cur->link[1]) {
- cur = cur->link[1];
- }
- } else {
- while (cur->link[1]) {
- cur = cur->link[1];
- }
- }
-
- // disconnect last
- ASSERT(h->last->parent)
- h->last->parent->link[h->last == h->last->parent->link[1]] = NULL;
-
- if (node == h->last) {
- // deleting last; set new last
- h->last = cur;
- } else {
- // not deleting last; move last to node's place
- BHeapNode *srcnode = h->last;
- _BHeap_replace_node(h, node, srcnode);
- // set new last unless node=cur; in this case it stays the same
- if (node != cur) {
- h->last = cur;
- }
-
- // restore heap property
- if (srcnode->parent && _BHeap_compare_nodes(h, srcnode, srcnode->parent) < 0) {
- do {
- _BHeap_move_one_up(h, srcnode);
- } while (srcnode->parent && _BHeap_compare_nodes(h, srcnode, srcnode->parent) < 0);
- } else {
- while (srcnode->link[0] || srcnode->link[1]) {
- int side = (srcnode->link[1] && (_BHeap_compare_nodes(h, srcnode->link[0], srcnode->link[1]) >= 0));
- if (_BHeap_compare_nodes(h, srcnode, srcnode->link[side]) > 0) {
- _BHeap_move_one_up(h, srcnode->link[side]);
- } else {
- break;
- }
- }
- }
- }
-
- BHEAP_ASSERT(h)
-}
-
-BHeapNode * BHeap_GetFirst (BHeap *h)
-{
- ASSERT(!h->in_handler)
-
- return h->root;
-}
-
-#endif