/* ternary.c - Ternary Search Trees
   Copyright (C) 2001 Free Software Foundation, Inc.

   Contributed by Daniel Berlin (dan@cgsoftware.com)

   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2, or (at your option) any
   later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
   USA.  */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

#include <stdio.h>

#include "libiberty.h"
#include "ternary.h"

/* Non-recursive so we don't waste stack space/time on large
   insertions. */

PTR
ternary_insert (root, s, data, replace)
     ternary_tree *root;
     const char *s;
     PTR data;
     int replace;
{
  int diff;
  ternary_tree curr, *pcurr;

  /* Start at the root. */
  pcurr = root;
  /* Loop until we find the right position */
  while ((curr = *pcurr))
    {
      /* Calculate the difference */
      diff = *s - curr->splitchar;
      /* Handle current char equal to node splitchar */
      if (diff == 0)
	{
	  /* Handle the case of a string we already have */
	  if (*s++ == 0)
	    {
	      if (replace)
		curr->eqkid = (ternary_tree) data;
	      return (PTR) curr->eqkid;
	    }
	  pcurr = &(curr->eqkid);
	}
      /* Handle current char less than node splitchar */
      else if (diff < 0)
	{
	  pcurr = &(curr->lokid);
	}
      /* Handle current char greater than node splitchar */
      else
	{
	  pcurr = &(curr->hikid);
	}
    }
  /* It's not a duplicate string, and we should insert what's left of
     the string, into the tree rooted at curr */
  for (;;)
    {
      /* Allocate the memory for the node, and fill it in */
      *pcurr = (ternary_tree) xmalloc (sizeof (ternary_node));
      curr = *pcurr;
      curr->splitchar = *s;
      curr->lokid = curr->hikid = curr->eqkid = 0;

      /* Place nodes until we hit the end of the string.
         When we hit it, place the data in the right place, and
         return.
       */
      if (*s++ == 0)
	{
	  curr->eqkid = (ternary_tree) data;
	  return data;
	}
      pcurr = &(curr->eqkid);
    }
}

/* Free the ternary search tree rooted at p. */
void
ternary_cleanup (p)
     ternary_tree p;
{
  if (p)
    {
      ternary_cleanup (p->lokid);
      if (p->splitchar)
	ternary_cleanup (p->eqkid);
      ternary_cleanup (p->hikid);
      free (p);
    }
}

/* Non-recursive find of a string in the ternary tree */
PTR
ternary_search (p, s)
     const ternary_node *p;
     const char *s;
{
  const ternary_node *curr;
  int diff, spchar;
  spchar = *s;
  curr = p;
  /* Loop while we haven't hit a NULL node or returned */
  while (curr)
    {
      /* Calculate the difference */
      diff = spchar - curr->splitchar;
      /* Handle the equal case */
      if (diff == 0)
	{
	  if (spchar == 0)
	    return (PTR) curr->eqkid;
	  spchar = *++s;
	  curr = curr->eqkid;
	}
      /* Handle the less than case */
      else if (diff < 0)
	curr = curr->lokid;
      /* All that's left is greater than */
      else
	curr = curr->hikid;
    }
  return NULL;
}

/* For those who care, the recursive version of the search. Useful if
   you want a starting point for pmsearch or nearsearch. */
static PTR
ternary_recursivesearch (p, s)
     const ternary_node *p;
     const char *s;
{
  if (!p)
    return 0;
  if (*s < p->splitchar)
    return ternary_recursivesearch (p->lokid, s);
  else if (*s > p->splitchar)
    return ternary_recursivesearch (p->hikid, s);
  else
    {
      if (*s == 0)
	return (PTR) p->eqkid;
      return ternary_recursivesearch (p->eqkid, ++s);
    }
}
