/*
 * Revision Control Information
 *
 * $Source: /vol/opua/opua2/sis/sis-1.2/common/src/sis/avl/RCS/avl.c,v $
 * $Author: sis $
 * $Revision: 1.3 $
 * $Date: 1994/07/15 23:00:40 $
 *
 */
/* LINTLIBRARY */


#include <stdio.h>
#include <stdlib.h>

#include "avl.h"

ABC_NAMESPACE_IMPL_START




#define HEIGHT(node) (node == NIL(avl_node) ? -1 : (node)->height)
#define BALANCE(node) (HEIGHT((node)->right) - HEIGHT((node)->left))

#define compute_height(node) {                \
    int x=HEIGHT(node->left), y=HEIGHT(node->right);    \
    (node)->height = MAX(x,y) + 1;            \
}

#define COMPARE(key, nodekey, compare)             \
    ((compare == avl_numcmp) ?                 \
    (int) key - (int) nodekey :             \
    (*compare)(key, nodekey))


#define STACK_SIZE    50

static avl_node *new_node ();
static avl_node *find_rightmost ();
static void do_rebalance ();
static rotate_left ();
static rotate_right ();
static int do_check_tree ();

avl_tree *
avl_init_table (compar)
 int (*compar) ();
{
    avl_tree *tree;

    tree = ALLOC (avl_tree, 1);
    tree->root = NIL (avl_node);
    tree->compar = compar;
    tree->num_entries = 0;
    return tree;
}



avl_lookup (tree, key, value_p)
 avl_tree *tree;
 register char *key;
 char **value_p;
{
    register avl_node *node;
    register int (*compare) () = tree->compar, diff;

    node = tree->root;
    while (node != NIL (avl_node))
    {
        diff = COMPARE (key, node->key, compare);
        if (diff == 0)
        {
            /* got a match */
            if (value_p != NIL (char *))
                 *value_p = node->value;
            return 1;
        }
        node = (diff < 0) ? node->left : node->right;
    }
    return 0;
}

avl_first (tree, key_p, value_p)
 avl_tree *tree;
 char **key_p;
 char **value_p;
{
    register avl_node *node;

    if (tree->root == 0)
    {
        return 0;                /* no entries */
    }
    else
    {
        /* walk down the tree; stop at leftmost leaf */
        for (node = tree->root; node->left != 0; node = node->left)
        {
        }
        if (key_p != NIL (char *))
             *key_p = node->key;
        if (value_p != NIL (char *))
             *value_p = node->value;
        return 1;
    }
}


avl_last (tree, key_p, value_p)
 avl_tree *tree;
 char **key_p;
 char **value_p;
{
    register avl_node *node;

    if (tree->root == 0)
    {
        return 0;                /* no entries */
    }
    else
    {
        /* walk down the tree; stop at rightmost leaf */
        for (node = tree->root; node->right != 0; node = node->right)
        {
        }
        if (key_p != NIL (char *))
             *key_p = node->key;
        if (value_p != NIL (char *))
             *value_p = node->value;
        return 1;
    }
}

avl_insert (tree, key, value)
 avl_tree *tree;
 char *key;
 char *value;
{
    register avl_node **node_p, *node;
    register int stack_n = 0;
    register int (*compare) () = tree->compar;
    avl_node **stack_nodep[STACK_SIZE];
    int diff, status;

    node_p = &tree->root;

    /* walk down the tree (saving the path); stop at insertion point */
    status = 0;
    while ((node = *node_p) != NIL (avl_node))
    {
        stack_nodep[stack_n++] = node_p;
        diff = COMPARE (key, node->key, compare);
        if (diff == 0)
            status = 1;
        node_p = (diff < 0) ? &node->left : &node->right;
    }

    /* insert the item and re-balance the tree */
    *node_p = new_node (key, value);
    do_rebalance (stack_nodep, stack_n);
    tree->num_entries++;
    tree->modified = 1;
    return status;
}



avl_find_or_add (tree, key, slot_p)
 avl_tree *tree;
 char *key;
 char ***slot_p;
{
    register avl_node **node_p, *node;
    register int stack_n = 0;
    register int (*compare) () = tree->compar;
    avl_node **stack_nodep[STACK_SIZE];
    int diff;

    node_p = &tree->root;

    /* walk down the tree (saving the path); stop at insertion point */
    while ((node = *node_p) != NIL (avl_node))
    {
        stack_nodep[stack_n++] = node_p;
        diff = COMPARE (key, node->key, compare);
        if (diff == 0)
        {
            if (slot_p != 0)
                *slot_p = &node->value;
            return 1;            /* found */
        }
        node_p = (diff < 0) ? &node->left : &node->right;
    }

    /* insert the item and re-balance the tree */
    *node_p = new_node (key, NIL (char));
    if (slot_p != 0)
        *slot_p = &(*node_p)->value;
    do_rebalance (stack_nodep, stack_n);
    tree->num_entries++;
    tree->modified = 1;
    return 0;                    /* not already in tree */
}

avl_delete (tree, key_p, value_p)
 avl_tree *tree;
 char **key_p;
 char **value_p;
{
    register avl_node **node_p, *node, *rightmost;
    register int stack_n = 0;
    char *key = *key_p;
    int (*compare) () = tree->compar, diff;
    avl_node **stack_nodep[STACK_SIZE];

    node_p = &tree->root;

    /* Walk down the tree saving the path; return if not found */
    while ((node = *node_p) != NIL (avl_node))
    {
        diff = COMPARE (key, node->key, compare);
        if (diff == 0)
            goto delete_item;
        stack_nodep[stack_n++] = node_p;
        node_p = (diff < 0) ? &node->left : &node->right;
    }
    return 0;                    /* not found */

    /* prepare to delete node and replace it with rightmost of left tree */
  delete_item:
    *key_p = node->key;
    if (value_p != 0)
        *value_p = node->value;
    if (node->left == NIL (avl_node))
    {
        *node_p = node->right;
    }
    else
    {
        rightmost = find_rightmost (&node->left);
        rightmost->left = node->left;
        rightmost->right = node->right;
        rightmost->height = -2;    /* mark bogus height for do_rebal */
        *node_p = rightmost;
        stack_nodep[stack_n++] = node_p;
    }
    FREE (node);

    /* work our way back up, re-balancing the tree */
    do_rebalance (stack_nodep, stack_n);
    tree->num_entries--;
    tree->modified = 1;
    return 1;
}

static void
avl_record_gen_forward (node, gen)
 avl_node *node;
 avl_generator *gen;
{
    if (node != NIL (avl_node))
    {
        avl_record_gen_forward (node->left, gen);
        gen->nodelist[gen->count++] = node;
        avl_record_gen_forward (node->right, gen);
    }
}


static void
avl_record_gen_backward (node, gen)
 avl_node *node;
 avl_generator *gen;
{
    if (node != NIL (avl_node))
    {
        avl_record_gen_backward (node->right, gen);
        gen->nodelist[gen->count++] = node;
        avl_record_gen_backward (node->left, gen);
    }
}


avl_generator *
avl_init_gen (tree, dir)
 avl_tree *tree;
 int dir;
{
    avl_generator *gen;

    /* what a hack */
    gen = ALLOC (avl_generator, 1);
    gen->tree = tree;
    gen->nodelist = ALLOC (avl_node *, avl_count (tree));
    gen->count = 0;
    if (dir == AVL_FORWARD)
    {
        avl_record_gen_forward (tree->root, gen);
    }
    else
    {
        avl_record_gen_backward (tree->root, gen);
    }
    gen->count = 0;

    /* catch any attempt to modify the tree while we generate */
    tree->modified = 0;
    return gen;
}


avl_gen (gen, key_p, value_p)
 avl_generator *gen;
 char **key_p;
 char **value_p;
{
    avl_node *node;

    if (gen->count == gen->tree->num_entries)
    {
        return 0;
    }
    else
    {
        node = gen->nodelist[gen->count++];
        if (key_p != NIL (char *))
             *key_p = node->key;
        if (value_p != NIL (char *))
             *value_p = node->value;
        return 1;
    }
}


void
avl_free_gen (gen)
 avl_generator *gen;
{
    FREE (gen->nodelist);
    FREE (gen);
}

static avl_node *
find_rightmost (node_p)
 register avl_node **node_p;
{
    register avl_node *node;
    register int stack_n = 0;
    avl_node **stack_nodep[STACK_SIZE];

    node = *node_p;
    while (node->right != NIL (avl_node))
    {
        stack_nodep[stack_n++] = node_p;
        node_p = &node->right;
        node = *node_p;
    }
    *node_p = node->left;

    do_rebalance (stack_nodep, stack_n);
    return node;
}


static void
do_rebalance (stack_nodep, stack_n)
 register avl_node ***stack_nodep;
 register int stack_n;
{
    register avl_node **node_p, *node;
    register int hl, hr;
    int height;

    /* work our way back up, re-balancing the tree */
    while (--stack_n >= 0)
    {
        node_p = stack_nodep[stack_n];
        node = *node_p;
        hl = HEIGHT (node->left);    /* watch for NIL */
        hr = HEIGHT (node->right);    /* watch for NIL */
        if ((hr - hl) < -1)
        {
            rotate_right (node_p);
        }
        else if ((hr - hl) > 1)
        {
            rotate_left (node_p);
        }
        else
        {
            height = MAX (hl, hr) + 1;
            if (height == node->height)
                break;
            node->height = height;
        }
    }
}

static
rotate_left (node_p)
 register avl_node **node_p;
{
    register avl_node *old_root = *node_p, *new_root, *new_right;

    if (BALANCE (old_root->right) >= 0)
    {
        *node_p = new_root = old_root->right;
        old_root->right = new_root->left;
        new_root->left = old_root;
    }
    else
    {
        new_right = old_root->right;
        *node_p = new_root = new_right->left;
        old_root->right = new_root->left;
        new_right->left = new_root->right;
        new_root->right = new_right;
        new_root->left = old_root;
        compute_height (new_right);
    }
    compute_height (old_root);
    compute_height (new_root);
}


static
rotate_right (node_p)
 avl_node **node_p;
{
    register avl_node *old_root = *node_p, *new_root, *new_left;

    if (BALANCE (old_root->left) <= 0)
    {
        *node_p = new_root = old_root->left;
        old_root->left = new_root->right;
        new_root->right = old_root;
    }
    else
    {
        new_left = old_root->left;
        *node_p = new_root = new_left->right;
        old_root->left = new_root->right;
        new_left->right = new_root->left;
        new_root->left = new_left;
        new_root->right = old_root;
        compute_height (new_left);
    }
    compute_height (old_root);
    compute_height (new_root);
}

static void
avl_walk_forward (node, func)
 avl_node *node;
 void (*func) ();
{
    if (node != NIL (avl_node))
    {
        avl_walk_forward (node->left, func);
        (*func) (node->key, node->value);
        avl_walk_forward (node->right, func);
    }
}


static void
avl_walk_backward (node, func)
 avl_node *node;
 void (*func) ();
{
    if (node != NIL (avl_node))
    {
        avl_walk_backward (node->right, func);
        (*func) (node->key, node->value);
        avl_walk_backward (node->left, func);
    }
}


void
avl_foreach (tree, func, direction)
 avl_tree *tree;
 void (*func) ();
 int direction;
{
    if (direction == AVL_FORWARD)
    {
        avl_walk_forward (tree->root, func);
    }
    else
    {
        avl_walk_backward (tree->root, func);
    }
}


static void
free_entry (node, key_free, value_free)
 avl_node *node;
 void (*key_free) ();
 void (*value_free) ();
{
    if (node != NIL (avl_node))
    {
        free_entry (node->left, key_free, value_free);
        free_entry (node->right, key_free, value_free);
        if (key_free != 0)
            (*key_free) (node->key);
        if (value_free != 0)
            (*value_free) (node->value);
        FREE (node);
    }
}


void
avl_free_table (tree, key_free, value_free)
 avl_tree *tree;
 void (*key_free) ();
 void (*value_free) ();
{
    free_entry (tree->root, key_free, value_free);
    FREE (tree);
}


int
avl_count (tree)
 avl_tree *tree;
{
    return tree->num_entries;
}

static avl_node *
new_node (key, value)
 char *key;
 char *value;
{
    register avl_node *new;

    new = ALLOC (avl_node, 1);
    new->key = key;
    new->value = value;
    new->height = 0;
    new->left = new->right = NIL (avl_node);
    return new;
}


int
avl_numcmp (x, y)
 char *x, *y;
{
    return (int) x - (int) y;
}

int
avl_check_tree (tree)
 avl_tree *tree;
{
    int error = 0;
    (void) do_check_tree (tree->root, tree->compar, &error);
    return error;
}


static int
do_check_tree (node, compar, error)
 avl_node *node;
 int (*compar) ();
 int *error;
{
    int l_height, r_height, comp_height, bal;

    if (node == NIL (avl_node))
    {
        return -1;
    }

    r_height = do_check_tree (node->right, compar, error);
    l_height = do_check_tree (node->left, compar, error);

    comp_height = MAX (l_height, r_height) + 1;
    bal = r_height - l_height;

    if (comp_height != node->height)
    {
        (void) printf ("Bad height for 0x%08x: computed=%d stored=%d\n",
                       node, comp_height, node->height);
        ++*error;
    }

    if (bal > 1 || bal < -1)
    {
        (void) printf ("Out of balance at node 0x%08x, balance = %d\n",
                       node, bal);
        ++*error;
    }

    if (node->left != NIL (avl_node) &&
        (*compar) (node->left->key, node->key) > 0)
    {
        (void) printf ("Bad ordering between 0x%08x and 0x%08x",
                       node, node->left);
        ++*error;
    }

    if (node->right != NIL (avl_node) &&
        (*compar) (node->key, node->right->key) > 0)
    {
        (void) printf ("Bad ordering between 0x%08x and 0x%08x",
                       node, node->right);
        ++*error;
    }

    return comp_height;
}
ABC_NAMESPACE_IMPL_END

