/*
 * Dictionary Abstract Data Type
 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
 *
 * Free Software License:
 *
 * All rights are reserved by the author, with the following exceptions:
 * Permission is granted to freely reproduce and distribute this software,
 * possibly in exchange for a fee, provided that this copyright notice appears
 * intact. Permission is also granted to adapt this software to produce
 * derivative works, as long as the modified versions carry this copyright
 * notice and additional notices stating that the work has been modified.
 * This source code may be translated into executable form and incorporated
 * into proprietary software; there is no requirement for such software to
 * contain a copyright notice related to this source.
 *
 * $Id: dict.c,v 1.2 2004/09/10 20:48:21 hasso Exp $
 * $Name:  $
 */

#include <stdlib.h>
#include <stddef.h>
#include <assert.h>
#define DICT_IMPLEMENTATION
#include "dict.h"

#ifdef KAZLIB_RCSID
static const char rcsid[] =
  "$Id: dict.c,v 1.2 2004/09/10 20:48:21 hasso Exp $";
#endif

/*
 * These macros provide short convenient names for structure members,
 * which are embellished with dict_ prefixes so that they are
 * properly confined to the documented namespace. It's legal for a 
 * program which uses dict to define, for instance, a macro called ``parent''.
 * Such a macro would interfere with the dnode_t struct definition.
 * In general, highly portable and reusable C modules which expose their
 * structures need to confine structure member names to well-defined spaces.
 * The resulting identifiers aren't necessarily convenient to use, nor
 * readable, in the implementation, however!
 */

#define left dict_left
#define right dict_right
#define parent dict_parent
#define color dict_color
#define key dict_key
#define data dict_data

#define nilnode dict_nilnode
#define nodecount dict_nodecount
#define maxcount dict_maxcount
#define compare dict_compare
#define allocnode dict_allocnode
#define freenode dict_freenode
#define context dict_context
#define dupes dict_dupes

#define dictptr dict_dictptr

#define dict_root(D) ((D)->nilnode.left)
#define dict_nil(D) (&(D)->nilnode)
#define DICT_DEPTH_MAX 64

static dnode_t *dnode_alloc (void *context);
static void dnode_free (dnode_t * node, void *context);

/*
 * Perform a ``left rotation'' adjustment on the tree.  The given node P and
 * its right child C are rearranged so that the P instead becomes the left
 * child of C.   The left subtree of C is inherited as the new right subtree
 * for P.  The ordering of the keys within the tree is thus preserved.
 */

static void
rotate_left (dnode_t * upper)
{
  dnode_t *lower, *lowleft, *upparent;

  lower = upper->right;
  upper->right = lowleft = lower->left;
  lowleft->parent = upper;

  lower->parent = upparent = upper->parent;

  /* don't need to check for root node here because root->parent is
     the sentinel nil node, and root->parent->left points back to root */

  if (upper == upparent->left)
    {
      upparent->left = lower;
    }
  else
    {
      assert (upper == upparent->right);
      upparent->right = lower;
    }

  lower->left = upper;
  upper->parent = lower;
}

/*
 * This operation is the ``mirror'' image of rotate_left. It is
 * the same procedure, but with left and right interchanged.
 */

static void
rotate_right (dnode_t * upper)
{
  dnode_t *lower, *lowright, *upparent;

  lower = upper->left;
  upper->left = lowright = lower->right;
  lowright->parent = upper;

  lower->parent = upparent = upper->parent;

  if (upper == upparent->right)
    {
      upparent->right = lower;
    }
  else
    {
      assert (upper == upparent->left);
      upparent->left = lower;
    }

  lower->right = upper;
  upper->parent = lower;
}

/*
 * Do a postorder traversal of the tree rooted at the specified
 * node and free everything under it.  Used by dict_free().
 */

static void
free_nodes (dict_t * dict, dnode_t * node, dnode_t * nil)
{
  if (node == nil)
    return;
  free_nodes (dict, node->left, nil);
  free_nodes (dict, node->right, nil);
  dict->freenode (node, dict->context);
}

/*
 * This procedure performs a verification that the given subtree is a binary
 * search tree. It performs an inorder traversal of the tree using the
 * dict_next() successor function, verifying that the key of each node is
 * strictly lower than that of its successor, if duplicates are not allowed,
 * or lower or equal if duplicates are allowed.  This function is used for
 * debugging purposes. 
 */

static int
verify_bintree (dict_t * dict)
{
  dnode_t *first, *next;

  first = dict_first (dict);

  if (dict->dupes)
    {
      while (first && (next = dict_next (dict, first)))
	{
	  if (dict->compare (first->key, next->key) > 0)
	    return 0;
	  first = next;
	}
    }
  else
    {
      while (first && (next = dict_next (dict, first)))
	{
	  if (dict->compare (first->key, next->key) >= 0)
	    return 0;
	  first = next;
	}
    }
  return 1;
}


/*
 * This function recursively verifies that the given binary subtree satisfies
 * three of the red black properties. It checks that every red node has only
 * black children. It makes sure that each node is either red or black. And it
 * checks that every path has the same count of black nodes from root to leaf.
 * It returns the blackheight of the given subtree; this allows blackheights to
 * be computed recursively and compared for left and right siblings for
 * mismatches. It does not check for every nil node being black, because there
 * is only one sentinel nil node. The return value of this function is the
 * black height of the subtree rooted at the node ``root'', or zero if the
 * subtree is not red-black.
 */

static unsigned int
verify_redblack (dnode_t * nil, dnode_t * root)
{
  unsigned height_left, height_right;

  if (root != nil)
    {
      height_left = verify_redblack (nil, root->left);
      height_right = verify_redblack (nil, root->right);
      if (height_left == 0 || height_right == 0)
	return 0;
      if (height_left != height_right)
	return 0;
      if (root->color == dnode_red)
	{
	  if (root->left->color != dnode_black)
	    return 0;
	  if (root->right->color != dnode_black)
	    return 0;
	  return height_left;
	}
      if (root->color != dnode_black)
	return 0;
      return height_left + 1;
    }
  return 1;
}

/*
 * Compute the actual count of nodes by traversing the tree and
 * return it. This could be compared against the stored count to
 * detect a mismatch.
 */

static dictcount_t
verify_node_count (dnode_t * nil, dnode_t * root)
{
  if (root == nil)
    return 0;
  else
    return 1 + verify_node_count (nil, root->left)
      + verify_node_count (nil, root->right);
}

/*
 * Verify that the tree contains the given node. This is done by
 * traversing all of the nodes and comparing their pointers to the
 * given pointer. Returns 1 if the node is found, otherwise
 * returns zero. It is intended for debugging purposes.
 */

static int
verify_dict_has_node (dnode_t * nil, dnode_t * root, dnode_t * node)
{
  if (root != nil)
    {
      return root == node
	|| verify_dict_has_node (nil, root->left, node)
	|| verify_dict_has_node (nil, root->right, node);
    }
  return 0;
}

/*
 * Dynamically allocate and initialize a dictionary object.
 */

dict_t *
dict_create (dictcount_t maxcount, dict_comp_t comp)
{
  dict_t *new = malloc (sizeof *new);

  if (new)
    {
      new->compare = comp;
      new->allocnode = dnode_alloc;
      new->freenode = dnode_free;
      new->context = NULL;
      new->nodecount = 0;
      new->maxcount = maxcount;
      new->nilnode.left = &new->nilnode;
      new->nilnode.right = &new->nilnode;
      new->nilnode.parent = &new->nilnode;
      new->nilnode.color = dnode_black;
      new->dupes = 0;
    }
  return new;
}

/*
 * Select a different set of node allocator routines.
 */

void
dict_set_allocator (dict_t * dict, dnode_alloc_t al,
		    dnode_free_t fr, void *context)
{
  assert (dict_count (dict) == 0);
  assert ((al == NULL && fr == NULL) || (al != NULL && fr != NULL));

  dict->allocnode = al ? al : dnode_alloc;
  dict->freenode = fr ? fr : dnode_free;
  dict->context = context;
}

/*
 * Free a dynamically allocated dictionary object. Removing the nodes
 * from the tree before deleting it is required.
 */

void
dict_destroy (dict_t * dict)
{
  assert (dict_isempty (dict));
  free (dict);
}

/*
 * Free all the nodes in the dictionary by using the dictionary's
 * installed free routine. The dictionary is emptied.
 */

void
dict_free_nodes (dict_t * dict)
{
  dnode_t *nil = dict_nil (dict), *root = dict_root (dict);
  free_nodes (dict, root, nil);
  dict->nodecount = 0;
  dict->nilnode.left = &dict->nilnode;
  dict->nilnode.right = &dict->nilnode;
}

/*
 * Obsolescent function, equivalent to dict_free_nodes
 */

void
dict_free (dict_t * dict)
{
#ifdef KAZLIB_OBSOLESCENT_DEBUG
  assert ("call to obsolescent function dict_free()" && 0);
#endif
  dict_free_nodes (dict);
}

/*
 * Initialize a user-supplied dictionary object.
 */

dict_t *
dict_init (dict_t * dict, dictcount_t maxcount, dict_comp_t comp)
{
  dict->compare = comp;
  dict->allocnode = dnode_alloc;
  dict->freenode = dnode_free;
  dict->context = NULL;
  dict->nodecount = 0;
  dict->maxcount = maxcount;
  dict->nilnode.left = &dict->nilnode;
  dict->nilnode.right = &dict->nilnode;
  dict->nilnode.parent = &dict->nilnode;
  dict->nilnode.color = dnode_black;
  dict->dupes = 0;
  return dict;
}

/* 
 * Initialize a dictionary in the likeness of another dictionary
 */

void
dict_init_like (dict_t * dict, const dict_t * template)
{
  dict->compare = template->compare;
  dict->allocnode = template->allocnode;
  dict->freenode = template->freenode;
  dict->context = template->context;
  dict->nodecount = 0;
  dict->maxcount = template->maxcount;
  dict->nilnode.left = &dict->nilnode;
  dict->nilnode.right = &dict->nilnode;
  dict->nilnode.parent = &dict->nilnode;
  dict->nilnode.color = dnode_black;
  dict->dupes = template->dupes;

  assert (dict_similar (dict, template));
}

/*
 * Remove all nodes from the dictionary (without freeing them in any way).
 */

static void
dict_clear (dict_t * dict)
{
  dict->nodecount = 0;
  dict->nilnode.left = &dict->nilnode;
  dict->nilnode.right = &dict->nilnode;
  dict->nilnode.parent = &dict->nilnode;
  assert (dict->nilnode.color == dnode_black);
}

/*
 * Verify the integrity of the dictionary structure.  This is provided for
 * debugging purposes, and should be placed in assert statements.   Just because
 * this function succeeds doesn't mean that the tree is not corrupt. Certain
 * corruptions in the tree may simply cause undefined behavior.
 */

int
dict_verify (dict_t * dict)
{
  dnode_t *nil = dict_nil (dict), *root = dict_root (dict);

  /* check that the sentinel node and root node are black */
  if (root->color != dnode_black)
    return 0;
  if (nil->color != dnode_black)
    return 0;
  if (nil->right != nil)
    return 0;
  /* nil->left is the root node; check that its parent pointer is nil */
  if (nil->left->parent != nil)
    return 0;
  /* perform a weak test that the tree is a binary search tree */
  if (!verify_bintree (dict))
    return 0;
  /* verify that the tree is a red-black tree */
  if (!verify_redblack (nil, root))
    return 0;
  if (verify_node_count (nil, root) != dict_count (dict))
    return 0;
  return 1;
}

/*
 * Determine whether two dictionaries are similar: have the same comparison and
 * allocator functions, and same status as to whether duplicates are allowed.
 */

int
dict_similar (const dict_t * left, const dict_t * right)
{
  if (left->compare != right->compare)
    return 0;

  if (left->allocnode != right->allocnode)
    return 0;

  if (left->freenode != right->freenode)
    return 0;

  if (left->context != right->context)
    return 0;

  if (left->dupes != right->dupes)
    return 0;

  return 1;
}

/*
 * Locate a node in the dictionary having the given key.
 * If the node is not found, a null a pointer is returned (rather than 
 * a pointer that dictionary's nil sentinel node), otherwise a pointer to the
 * located node is returned.
 */

dnode_t *
dict_lookup (dict_t * dict, const void *key)
{
  dnode_t *root = dict_root (dict);
  dnode_t *nil = dict_nil (dict);
  dnode_t *saved;
  int result;

  /* simple binary search adapted for trees that contain duplicate keys */

  while (root != nil)
    {
      result = dict->compare (key, root->key);
      if (result < 0)
	root = root->left;
      else if (result > 0)
	root = root->right;
      else
	{
	  if (!dict->dupes)
	    {			/* no duplicates, return match          */
	      return root;
	    }
	  else
	    {			/* could be dupes, find leftmost one    */
	      do
		{
		  saved = root;
		  root = root->left;
		  while (root != nil && dict->compare (key, root->key))
		    root = root->right;
		}
	      while (root != nil);
	      return saved;
	    }
	}
    }

  return NULL;
}

/*
 * Look for the node corresponding to the lowest key that is equal to or
 * greater than the given key.  If there is no such node, return null.
 */

dnode_t *
dict_lower_bound (dict_t * dict, const void *key)
{
  dnode_t *root = dict_root (dict);
  dnode_t *nil = dict_nil (dict);
  dnode_t *tentative = 0;

  while (root != nil)
    {
      int result = dict->compare (key, root->key);

      if (result > 0)
	{
	  root = root->right;
	}
      else if (result < 0)
	{
	  tentative = root;
	  root = root->left;
	}
      else
	{
	  if (!dict->dupes)
	    {
	      return root;
	    }
	  else
	    {
	      tentative = root;
	      root = root->left;
	    }
	}
    }

  return tentative;
}

/*
 * Look for the node corresponding to the greatest key that is equal to or
 * lower than the given key.  If there is no such node, return null.
 */

dnode_t *
dict_upper_bound (dict_t * dict, const void *key)
{
  dnode_t *root = dict_root (dict);
  dnode_t *nil = dict_nil (dict);
  dnode_t *tentative = 0;

  while (root != nil)
    {
      int result = dict->compare (key, root->key);

      if (result < 0)
	{
	  root = root->left;
	}
      else if (result > 0)
	{
	  tentative = root;
	  root = root->right;
	}
      else
	{
	  if (!dict->dupes)
	    {
	      return root;
	    }
	  else
	    {
	      tentative = root;
	      root = root->right;
	    }
	}
    }

  return tentative;
}

/*
 * Insert a node into the dictionary. The node should have been
 * initialized with a data field. All other fields are ignored.
 * The behavior is undefined if the user attempts to insert into
 * a dictionary that is already full (for which the dict_isfull()
 * function returns true).
 */

void
dict_insert (dict_t * dict, dnode_t * node, const void *key)
{
  dnode_t *where = dict_root (dict), *nil = dict_nil (dict);
  dnode_t *parent = nil, *uncle, *grandpa;
  int result = -1;

  node->key = key;

  assert (!dict_isfull (dict));
  assert (!dict_contains (dict, node));
  assert (!dnode_is_in_a_dict (node));

  /* basic binary tree insert */

  while (where != nil)
    {
      parent = where;
      result = dict->compare (key, where->key);
      /* trap attempts at duplicate key insertion unless it's explicitly allowed */
      assert (dict->dupes || result != 0);
      if (result < 0)
	where = where->left;
      else
	where = where->right;
    }

  assert (where == nil);

  if (result < 0)
    parent->left = node;
  else
    parent->right = node;

  node->parent = parent;
  node->left = nil;
  node->right = nil;

  dict->nodecount++;

  /* red black adjustments */

  node->color = dnode_red;

  while (parent->color == dnode_red)
    {
      grandpa = parent->parent;
      if (parent == grandpa->left)
	{
	  uncle = grandpa->right;
	  if (uncle->color == dnode_red)
	    {			/* red parent, red uncle */
	      parent->color = dnode_black;
	      uncle->color = dnode_black;
	      grandpa->color = dnode_red;
	      node = grandpa;
	      parent = grandpa->parent;
	    }
	  else
	    {			/* red parent, black uncle */
	      if (node == parent->right)
		{
		  rotate_left (parent);
		  parent = node;
		  assert (grandpa == parent->parent);
		  /* rotation between parent and child preserves grandpa */
		}
	      parent->color = dnode_black;
	      grandpa->color = dnode_red;
	      rotate_right (grandpa);
	      break;
	    }
	}
      else
	{			/* symmetric cases: parent == parent->parent->right */
	  uncle = grandpa->left;
	  if (uncle->color == dnode_red)
	    {
	      parent->color = dnode_black;
	      uncle->color = dnode_black;
	      grandpa->color = dnode_red;
	      node = grandpa;
	      parent = grandpa->parent;
	    }
	  else
	    {
	      if (node == parent->left)
		{
		  rotate_right (parent);
		  parent = node;
		  assert (grandpa == parent->parent);
		}
	      parent->color = dnode_black;
	      grandpa->color = dnode_red;
	      rotate_left (grandpa);
	      break;
	    }
	}
    }

  dict_root (dict)->color = dnode_black;

  assert (dict_verify (dict));
}

/*
 * Delete the given node from the dictionary. If the given node does not belong
 * to the given dictionary, undefined behavior results.  A pointer to the
 * deleted node is returned.
 */

dnode_t *
dict_delete (dict_t * dict, dnode_t * delete)
{
  dnode_t *nil = dict_nil (dict), *child, *delparent = delete->parent;

  /* basic deletion */

  assert (!dict_isempty (dict));
  assert (dict_contains (dict, delete));

  /*
   * If the node being deleted has two children, then we replace it with its
   * successor (i.e. the leftmost node in the right subtree.) By doing this,
   * we avoid the traditional algorithm under which the successor's key and
   * value *only* move to the deleted node and the successor is spliced out
   * from the tree. We cannot use this approach because the user may hold
   * pointers to the successor, or nodes may be inextricably tied to some
   * other structures by way of embedding, etc. So we must splice out the
   * node we are given, not some other node, and must not move contents from
   * one node to another behind the user's back.
   */

  if (delete->left != nil && delete->right != nil)
    {
      dnode_t *next = dict_next (dict, delete);
      dnode_t *nextparent = next->parent;
      dnode_color_t nextcolor = next->color;

      assert (next != nil);
      assert (next->parent != nil);
      assert (next->left == nil);

      /*
       * First, splice out the successor from the tree completely, by
       * moving up its right child into its place.
       */

      child = next->right;
      child->parent = nextparent;

      if (nextparent->left == next)
	{
	  nextparent->left = child;
	}
      else
	{
	  assert (nextparent->right == next);
	  nextparent->right = child;
	}

      /*
       * Now that the successor has been extricated from the tree, install it
       * in place of the node that we want deleted.
       */

      next->parent = delparent;
      next->left = delete->left;
      next->right = delete->right;
      next->left->parent = next;
      next->right->parent = next;
      next->color = delete->color;
      delete->color = nextcolor;

      if (delparent->left == delete)
	{
	  delparent->left = next;
	}
      else
	{
	  assert (delparent->right == delete);
	  delparent->right = next;
	}

    }
  else
    {
      assert (delete != nil);
      assert (delete->left == nil || delete->right == nil);

      child = (delete->left != nil) ? delete->left : delete->right;

      child->parent = delparent = delete->parent;

      if (delete == delparent->left)
	{
	  delparent->left = child;
	}
      else
	{
	  assert (delete == delparent->right);
	  delparent->right = child;
	}
    }

  delete->parent = NULL;
  delete->right = NULL;
  delete->left = NULL;

  dict->nodecount--;

  assert (verify_bintree (dict));

  /* red-black adjustments */

  if (delete->color == dnode_black)
    {
      dnode_t *parent, *sister;

      dict_root (dict)->color = dnode_red;

      while (child->color == dnode_black)
	{
	  parent = child->parent;
	  if (child == parent->left)
	    {
	      sister = parent->right;
	      assert (sister != nil);
	      if (sister->color == dnode_red)
		{
		  sister->color = dnode_black;
		  parent->color = dnode_red;
		  rotate_left (parent);
		  sister = parent->right;
		  assert (sister != nil);
		}
	      if (sister->left->color == dnode_black
		  && sister->right->color == dnode_black)
		{
		  sister->color = dnode_red;
		  child = parent;
		}
	      else
		{
		  if (sister->right->color == dnode_black)
		    {
		      assert (sister->left->color == dnode_red);
		      sister->left->color = dnode_black;
		      sister->color = dnode_red;
		      rotate_right (sister);
		      sister = parent->right;
		      assert (sister != nil);
		    }
		  sister->color = parent->color;
		  sister->right->color = dnode_black;
		  parent->color = dnode_black;
		  rotate_left (parent);
		  break;
		}
	    }
	  else
	    {			/* symmetric case: child == child->parent->right */
	      assert (child == parent->right);
	      sister = parent->left;
	      assert (sister != nil);
	      if (sister->color == dnode_red)
		{
		  sister->color = dnode_black;
		  parent->color = dnode_red;
		  rotate_right (parent);
		  sister = parent->left;
		  assert (sister != nil);
		}
	      if (sister->right->color == dnode_black
		  && sister->left->color == dnode_black)
		{
		  sister->color = dnode_red;
		  child = parent;
		}
	      else
		{
		  if (sister->left->color == dnode_black)
		    {
		      assert (sister->right->color == dnode_red);
		      sister->right->color = dnode_black;
		      sister->color = dnode_red;
		      rotate_left (sister);
		      sister = parent->left;
		      assert (sister != nil);
		    }
		  sister->color = parent->color;
		  sister->left->color = dnode_black;
		  parent->color = dnode_black;
		  rotate_right (parent);
		  break;
		}
	    }
	}

      child->color = dnode_black;
      dict_root (dict)->color = dnode_black;
    }

  assert (dict_verify (dict));

  return delete;
}

/*
 * Allocate a node using the dictionary's allocator routine, give it
 * the data item.
 */

int
dict_alloc_insert (dict_t * dict, const void *key, void *data)
{
  dnode_t *node = dict->allocnode (dict->context);

  if (node)
    {
      dnode_init (node, data);
      dict_insert (dict, node, key);
      return 1;
    }
  return 0;
}

void
dict_delete_free (dict_t * dict, dnode_t * node)
{
  dict_delete (dict, node);
  dict->freenode (node, dict->context);
}

/*
 * Return the node with the lowest (leftmost) key. If the dictionary is empty
 * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
 */

dnode_t *
dict_first (dict_t * dict)
{
  dnode_t *nil = dict_nil (dict), *root = dict_root (dict), *left;

  if (root != nil)
    while ((left = root->left) != nil)
      root = left;

  return (root == nil) ? NULL : root;
}

/*
 * Return the node with the highest (rightmost) key. If the dictionary is empty
 * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
 */

dnode_t *
dict_last (dict_t * dict)
{
  dnode_t *nil = dict_nil (dict), *root = dict_root (dict), *right;

  if (root != nil)
    while ((right = root->right) != nil)
      root = right;

  return (root == nil) ? NULL : root;
}

/*
 * Return the given node's successor node---the node which has the
 * next key in the the left to right ordering. If the node has
 * no successor, a null pointer is returned rather than a pointer to
 * the nil node.
 */

dnode_t *
dict_next (dict_t * dict, dnode_t * curr)
{
  dnode_t *nil = dict_nil (dict), *parent, *left;

  if (curr->right != nil)
    {
      curr = curr->right;
      while ((left = curr->left) != nil)
	curr = left;
      return curr;
    }

  parent = curr->parent;

  while (parent != nil && curr == parent->right)
    {
      curr = parent;
      parent = curr->parent;
    }

  return (parent == nil) ? NULL : parent;
}

/*
 * Return the given node's predecessor, in the key order.
 * The nil sentinel node is returned if there is no predecessor.
 */

dnode_t *
dict_prev (dict_t * dict, dnode_t * curr)
{
  dnode_t *nil = dict_nil (dict), *parent, *right;

  if (curr->left != nil)
    {
      curr = curr->left;
      while ((right = curr->right) != nil)
	curr = right;
      return curr;
    }

  parent = curr->parent;

  while (parent != nil && curr == parent->left)
    {
      curr = parent;
      parent = curr->parent;
    }

  return (parent == nil) ? NULL : parent;
}

void
dict_allow_dupes (dict_t * dict)
{
  dict->dupes = 1;
}

#undef dict_count
#undef dict_isempty
#undef dict_isfull
#undef dnode_get
#undef dnode_put
#undef dnode_getkey

dictcount_t
dict_count (dict_t * dict)
{
  return dict->nodecount;
}

int
dict_isempty (dict_t * dict)
{
  return dict->nodecount == 0;
}

int
dict_isfull (dict_t * dict)
{
  return dict->nodecount == dict->maxcount;
}

int
dict_contains (dict_t * dict, dnode_t * node)
{
  return verify_dict_has_node (dict_nil (dict), dict_root (dict), node);
}

static dnode_t *
dnode_alloc (void *context)
{
  return malloc (sizeof *dnode_alloc (NULL));
}

static void
dnode_free (dnode_t * node, void *context)
{
  free (node);
}

dnode_t *
dnode_create (void *data)
{
  dnode_t *new = malloc (sizeof *new);
  if (new)
    {
      new->data = data;
      new->parent = NULL;
      new->left = NULL;
      new->right = NULL;
    }
  return new;
}

dnode_t *
dnode_init (dnode_t * dnode, void *data)
{
  dnode->data = data;
  dnode->parent = NULL;
  dnode->left = NULL;
  dnode->right = NULL;
  return dnode;
}

void
dnode_destroy (dnode_t * dnode)
{
  assert (!dnode_is_in_a_dict (dnode));
  free (dnode);
}

void *
dnode_get (dnode_t * dnode)
{
  return dnode->data;
}

const void *
dnode_getkey (dnode_t * dnode)
{
  return dnode->key;
}

void
dnode_put (dnode_t * dnode, void *data)
{
  dnode->data = data;
}

int
dnode_is_in_a_dict (dnode_t * dnode)
{
  return (dnode->parent && dnode->left && dnode->right);
}

void
dict_process (dict_t * dict, void *context, dnode_process_t function)
{
  dnode_t *node = dict_first (dict), *next;

  while (node != NULL)
    {
      /* check for callback function deleting */
      /* the next node from under us          */
      assert (dict_contains (dict, node));
      next = dict_next (dict, node);
      function (dict, node, context);
      node = next;
    }
}

static void
load_begin_internal (dict_load_t * load, dict_t * dict)
{
  load->dictptr = dict;
  load->nilnode.left = &load->nilnode;
  load->nilnode.right = &load->nilnode;
}

void
dict_load_begin (dict_load_t * load, dict_t * dict)
{
  assert (dict_isempty (dict));
  load_begin_internal (load, dict);
}

void
dict_load_next (dict_load_t * load, dnode_t * newnode, const void *key)
{
  dict_t *dict = load->dictptr;
  dnode_t *nil = &load->nilnode;

  assert (!dnode_is_in_a_dict (newnode));
  assert (dict->nodecount < dict->maxcount);

#ifndef NDEBUG
  if (dict->nodecount > 0)
    {
      if (dict->dupes)
	assert (dict->compare (nil->left->key, key) <= 0);
      else
	assert (dict->compare (nil->left->key, key) < 0);
    }
#endif

  newnode->key = key;
  nil->right->left = newnode;
  nil->right = newnode;
  newnode->left = nil;
  dict->nodecount++;
}

void
dict_load_end (dict_load_t * load)
{
  dict_t *dict = load->dictptr;
  dnode_t *tree[DICT_DEPTH_MAX] = { 0 };
  dnode_t *curr, *dictnil = dict_nil (dict), *loadnil = &load->nilnode, *next;
  dnode_t *complete = 0;
  dictcount_t fullcount = DICTCOUNT_T_MAX, nodecount = dict->nodecount;
  dictcount_t botrowcount;
  unsigned baselevel = 0, level = 0, i;

  assert (dnode_red == 0 && dnode_black == 1);

  while (fullcount >= nodecount && fullcount)
    fullcount >>= 1;

  botrowcount = nodecount - fullcount;

  for (curr = loadnil->left; curr != loadnil; curr = next)
    {
      next = curr->left;

      if (complete == NULL && botrowcount-- == 0)
	{
	  assert (baselevel == 0);
	  assert (level == 0);
	  baselevel = level = 1;
	  complete = tree[0];

	  if (complete != 0)
	    {
	      tree[0] = 0;
	      complete->right = dictnil;
	      while (tree[level] != 0)
		{
		  tree[level]->right = complete;
		  complete->parent = tree[level];
		  complete = tree[level];
		  tree[level++] = 0;
		}
	    }
	}

      if (complete == NULL)
	{
	  curr->left = dictnil;
	  curr->right = dictnil;
	  curr->color = level % 2;
	  complete = curr;

	  assert (level == baselevel);
	  while (tree[level] != 0)
	    {
	      tree[level]->right = complete;
	      complete->parent = tree[level];
	      complete = tree[level];
	      tree[level++] = 0;
	    }
	}
      else
	{
	  curr->left = complete;
	  curr->color = (level + 1) % 2;
	  complete->parent = curr;
	  tree[level] = curr;
	  complete = 0;
	  level = baselevel;
	}
    }

  if (complete == NULL)
    complete = dictnil;

  for (i = 0; i < DICT_DEPTH_MAX; i++)
    {
      if (tree[i] != 0)
	{
	  tree[i]->right = complete;
	  complete->parent = tree[i];
	  complete = tree[i];
	}
    }

  dictnil->color = dnode_black;
  dictnil->right = dictnil;
  complete->parent = dictnil;
  complete->color = dnode_black;
  dict_root (dict) = complete;

  assert (dict_verify (dict));
}

void
dict_merge (dict_t * dest, dict_t * source)
{
  dict_load_t load;
  dnode_t *leftnode = dict_first (dest), *rightnode = dict_first (source);

  assert (dict_similar (dest, source));

  if (source == dest)
    return;

  dest->nodecount = 0;
  load_begin_internal (&load, dest);

  for (;;)
    {
      if (leftnode != NULL && rightnode != NULL)
	{
	  if (dest->compare (leftnode->key, rightnode->key) < 0)
	    goto copyleft;
	  else
	    goto copyright;
	}
      else if (leftnode != NULL)
	{
	  goto copyleft;
	}
      else if (rightnode != NULL)
	{
	  goto copyright;
	}
      else
	{
	  assert (leftnode == NULL && rightnode == NULL);
	  break;
	}

    copyleft:
      {
	dnode_t *next = dict_next (dest, leftnode);
#ifndef NDEBUG
	leftnode->left = NULL;	/* suppress assertion in dict_load_next */
#endif
	dict_load_next (&load, leftnode, leftnode->key);
	leftnode = next;
	continue;
      }

    copyright:
      {
	dnode_t *next = dict_next (source, rightnode);
#ifndef NDEBUG
	rightnode->left = NULL;
#endif
	dict_load_next (&load, rightnode, rightnode->key);
	rightnode = next;
	continue;
      }
    }

  dict_clear (source);
  dict_load_end (&load);
}

#ifdef KAZLIB_TEST_MAIN

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>

typedef char input_t[256];

static int
tokenize (char *string, ...)
{
  char **tokptr;
  va_list arglist;
  int tokcount = 0;

  va_start (arglist, string);
  tokptr = va_arg (arglist, char **);
  while (tokptr)
    {
      while (*string && isspace ((unsigned char) *string))
	string++;
      if (!*string)
	break;
      *tokptr = string;
      while (*string && !isspace ((unsigned char) *string))
	string++;
      tokptr = va_arg (arglist, char **);
      tokcount++;
      if (!*string)
	break;
      *string++ = 0;
    }
  va_end (arglist);

  return tokcount;
}

static int
comparef (const void *key1, const void *key2)
{
  return strcmp (key1, key2);
}

static char *
dupstring (char *str)
{
  int sz = strlen (str) + 1;
  char *new = malloc (sz);
  if (new)
    memcpy (new, str, sz);
  return new;
}

static dnode_t *
new_node (void *c)
{
  static dnode_t few[5];
  static int count;

  if (count < 5)
    return few + count++;

  return NULL;
}

static void
del_node (dnode_t * n, void *c)
{
}

static int prompt = 0;

static void
construct (dict_t * d)
{
  input_t in;
  int done = 0;
  dict_load_t dl;
  dnode_t *dn;
  char *tok1, *tok2, *val;
  const char *key;
  char *help =
    "p                      turn prompt on\n"
    "q                      finish construction\n"
    "a <key> <val>          add new entry\n";

  if (!dict_isempty (d))
    puts ("warning: dictionary not empty!");

  dict_load_begin (&dl, d);

  while (!done)
    {
      if (prompt)
	putchar ('>');
      fflush (stdout);

      if (!fgets (in, sizeof (input_t), stdin))
	break;

      switch (in[0])
	{
	case '?':
	  puts (help);
	  break;
	case 'p':
	  prompt = 1;
	  break;
	case 'q':
	  done = 1;
	  break;
	case 'a':
	  if (tokenize (in + 1, &tok1, &tok2, (char **) 0) != 2)
	    {
	      puts ("what?");
	      break;
	    }
	  key = dupstring (tok1);
	  val = dupstring (tok2);
	  dn = dnode_create (val);

	  if (!key || !val || !dn)
	    {
	      puts ("out of memory");
	      free ((void *) key);
	      free (val);
	      if (dn)
		dnode_destroy (dn);
	    }

	  dict_load_next (&dl, dn, key);
	  break;
	default:
	  putchar ('?');
	  putchar ('\n');
	  break;
	}
    }

  dict_load_end (&dl);
}

int
main (void)
{
  input_t in;
  dict_t darray[10];
  dict_t *d = &darray[0];
  dnode_t *dn;
  int i;
  char *tok1, *tok2, *val;
  const char *key;

  char *help =
    "a <key> <val>          add value to dictionary\n"
    "d <key>                delete value from dictionary\n"
    "l <key>                lookup value in dictionary\n"
    "( <key>                lookup lower bound\n"
    ") <key>                lookup upper bound\n"
    "# <num>                switch to alternate dictionary (0-9)\n"
    "j <num> <num>          merge two dictionaries\n"
    "f                      free the whole dictionary\n"
    "k                      allow duplicate keys\n"
    "c                      show number of entries\n"
    "t                      dump whole dictionary in sort order\n"
    "m                      make dictionary out of sorted items\n"
    "p                      turn prompt on\n"
    "s                      switch to non-functioning allocator\n"
    "q                      quit";

  for (i = 0; i < sizeof darray / sizeof *darray; i++)
    dict_init (&darray[i], DICTCOUNT_T_MAX, comparef);

  for (;;)
    {
      if (prompt)
	putchar ('>');
      fflush (stdout);

      if (!fgets (in, sizeof (input_t), stdin))
	break;

      switch (in[0])
	{
	case '?':
	  puts (help);
	  break;
	case 'a':
	  if (tokenize (in + 1, &tok1, &tok2, (char **) 0) != 2)
	    {
	      puts ("what?");
	      break;
	    }
	  key = dupstring (tok1);
	  val = dupstring (tok2);

	  if (!key || !val)
	    {
	      puts ("out of memory");
	      free ((void *) key);
	      free (val);
	    }

	  if (!dict_alloc_insert (d, key, val))
	    {
	      puts ("dict_alloc_insert failed");
	      free ((void *) key);
	      free (val);
	      break;
	    }
	  break;
	case 'd':
	  if (tokenize (in + 1, &tok1, (char **) 0) != 1)
	    {
	      puts ("what?");
	      break;
	    }
	  dn = dict_lookup (d, tok1);
	  if (!dn)
	    {
	      puts ("dict_lookup failed");
	      break;
	    }
	  val = dnode_get (dn);
	  key = dnode_getkey (dn);
	  dict_delete_free (d, dn);

	  free (val);
	  free ((void *) key);
	  break;
	case 'f':
	  dict_free (d);
	  break;
	case 'l':
	case '(':
	case ')':
	  if (tokenize (in + 1, &tok1, (char **) 0) != 1)
	    {
	      puts ("what?");
	      break;
	    }
	  dn = 0;
	  switch (in[0])
	    {
	    case 'l':
	      dn = dict_lookup (d, tok1);
	      break;
	    case '(':
	      dn = dict_lower_bound (d, tok1);
	      break;
	    case ')':
	      dn = dict_upper_bound (d, tok1);
	      break;
	    }
	  if (!dn)
	    {
	      puts ("lookup failed");
	      break;
	    }
	  val = dnode_get (dn);
	  puts (val);
	  break;
	case 'm':
	  construct (d);
	  break;
	case 'k':
	  dict_allow_dupes (d);
	  break;
	case 'c':
	  printf ("%lu\n", (unsigned long) dict_count (d));
	  break;
	case 't':
	  for (dn = dict_first (d); dn; dn = dict_next (d, dn))
	    {
	      printf ("%s\t%s\n", (char *) dnode_getkey (dn),
		      (char *) dnode_get (dn));
	    }
	  break;
	case 'q':
	  exit (0);
	  break;
	case '\0':
	  break;
	case 'p':
	  prompt = 1;
	  break;
	case 's':
	  dict_set_allocator (d, new_node, del_node, NULL);
	  break;
	case '#':
	  if (tokenize (in + 1, &tok1, (char **) 0) != 1)
	    {
	      puts ("what?");
	      break;
	    }
	  else
	    {
	      int dictnum = atoi (tok1);
	      if (dictnum < 0 || dictnum > 9)
		{
		  puts ("invalid number");
		  break;
		}
	      d = &darray[dictnum];
	    }
	  break;
	case 'j':
	  if (tokenize (in + 1, &tok1, &tok2, (char **) 0) != 2)
	    {
	      puts ("what?");
	      break;
	    }
	  else
	    {
	      int dict1 = atoi (tok1), dict2 = atoi (tok2);
	      if (dict1 < 0 || dict1 > 9 || dict2 < 0 || dict2 > 9)
		{
		  puts ("invalid number");
		  break;
		}
	      dict_merge (&darray[dict1], &darray[dict2]);
	    }
	  break;
	default:
	  putchar ('?');
	  putchar ('\n');
	  break;
	}
    }

  return 0;
}

#endif
