/* @configure_input@ */

/*
**  Copyright 1998-2002 University of Illinois Board of Trustees
**  Copyright 1998-2002 Mark D. Roth
**  All rights reserved. 
**
**  @LISTHASH_PREFIX@_hash.c - hash table routines
**
**  Mark D. Roth <roth@uiuc.edu>
**  Campus Information Technologies and Educational Services
**  University of Illinois at Urbana-Champaign
*/

#include <@LISTHASH_PREFIX@/config.h>
#include <@LISTHASH_PREFIX@/compat.h>

#include <@LISTHASH_PREFIX@/@LISTHASH_PREFIX@_listhash.h>

#include <stdio.h>
#include <errno.h>

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


/*
** @LISTHASH_PREFIX@_hashptr_reset() - reset a hash pointer
*/
void
@LISTHASH_PREFIX@_hashptr_reset(@LISTHASH_PREFIX@_hashptr_t *hp)
{
  @LISTHASH_PREFIX@_listptr_reset(&(hp->node));
  hp->bucket = -1;
}


/*
** @LISTHASH_PREFIX@_hashptr_data() - retrieve the data being pointed to
*/
void *
@LISTHASH_PREFIX@_hashptr_data(@LISTHASH_PREFIX@_hashptr_t *hp)
{
  return @LISTHASH_PREFIX@_listptr_data(&(hp->node));
}


/*
** @LISTHASH_PREFIX@_str_hashfunc() - default hash function, optimized for
**              7-bit strings
*/
unsigned int
@LISTHASH_PREFIX@_str_hashfunc(char *key, unsigned int num_buckets)
{
#if 0
  register unsigned result = 0;
  register int i;

  if (key == NULL)
    return 0;

  for (i = 0; *key != '\0' && i < 32; i++)
    result = result * 33U + *key++;

  return (result % num_buckets);
#else
  if (key == NULL)
    return 0;

  return (key[0] % num_buckets);
#endif
}


/*
** @LISTHASH_PREFIX@_hash_nents() - return number of elements from hash
*/
unsigned int
@LISTHASH_PREFIX@_hash_nents(@LISTHASH_PREFIX@_hash_t *h)
{
  return h->nents;
}


/*
** @LISTHASH_PREFIX@_hash_new() - create a new hash
*/
@LISTHASH_PREFIX@_hash_t *
@LISTHASH_PREFIX@_hash_new(int num, @LISTHASH_PREFIX@_hashfunc_t hashfunc)
{
  @LISTHASH_PREFIX@_hash_t *hash;

  hash = (@LISTHASH_PREFIX@_hash_t *)calloc(1, sizeof(@LISTHASH_PREFIX@_hash_t));
  if (hash == NULL)
    return NULL;
  hash->numbuckets = num;
  if (hashfunc != NULL)
    hash->hashfunc = hashfunc;
  else
    hash->hashfunc = (@LISTHASH_PREFIX@_hashfunc_t)@LISTHASH_PREFIX@_str_hashfunc;

  hash->table = (@LISTHASH_PREFIX@_list_t **)calloc(num, sizeof(@LISTHASH_PREFIX@_list_t *));
  if (hash->table == NULL)
  {
    free(hash);
    return NULL;
  }

  return hash;
}


/*
** @LISTHASH_PREFIX@_hash_next() - get next element in hash
** returns:
**  1      data found
**  0      end of list
*/
int
@LISTHASH_PREFIX@_hash_next(@LISTHASH_PREFIX@_hash_t *h,
          @LISTHASH_PREFIX@_hashptr_t *hp)
{
#ifdef DS_DEBUG
  printf("==> @LISTHASH_PREFIX@_hash_next(h=0x%lx, hp={%d,0x%lx})\n",
         h, hp->bucket, hp->node);
#endif

  if (hp->bucket >= 0 && hp->node != NULL &&
      @LISTHASH_PREFIX@_list_next(h->table[hp->bucket], &(hp->node)) != 0)
  {
#ifdef DS_DEBUG
    printf("    @LISTHASH_PREFIX@_hash_next(): found additional "
           "data in current bucket (%d), returing 1\n",
           hp->bucket);
#endif
    return 1;
  }

#ifdef DS_DEBUG
  printf("    @LISTHASH_PREFIX@_hash_next(): done with bucket %d\n",
         hp->bucket);
#endif

  for (hp->bucket++; hp->bucket < h->numbuckets; hp->bucket++)
  {
#ifdef DS_DEBUG
    printf("    @LISTHASH_PREFIX@_hash_next(): "
           "checking bucket %d\n", hp->bucket);
#endif
    hp->node = NULL;
    if (h->table[hp->bucket] != NULL &&
        @LISTHASH_PREFIX@_list_next(h->table[hp->bucket],
                &(hp->node)) != 0)
    {
#ifdef DS_DEBUG
      printf("    @LISTHASH_PREFIX@_hash_next(): "
             "found data in bucket %d, returing 1\n",
             hp->bucket);
#endif
      return 1;
    }
  }

  if (hp->bucket == h->numbuckets)
  {
#ifdef DS_DEBUG
    printf("    @LISTHASH_PREFIX@_hash_next(): hash pointer "
           "wrapped to 0\n");
#endif
    hp->bucket = -1;
    hp->node = NULL;
  }

#ifdef DS_DEBUG
  printf("<== @LISTHASH_PREFIX@_hash_next(): no more data, "
         "returning 0\n");
#endif
  return 0;
}


/*
** @LISTHASH_PREFIX@_hash_del() - delete an entry from the hash
** returns:
**  0      success
**  -1 (and sets errno)  failure
*/
int
@LISTHASH_PREFIX@_hash_del(@LISTHASH_PREFIX@_hash_t *h,
         @LISTHASH_PREFIX@_hashptr_t *hp)
{
  if (hp->bucket < 0
      || hp->bucket >= h->numbuckets
      || h->table[hp->bucket] == NULL
      || hp->node == NULL)
  {
    errno = EINVAL;
    return -1;
  }

  @LISTHASH_PREFIX@_list_del(h->table[hp->bucket], &(hp->node));
  h->nents--;
  return 0;
}


/*
** @LISTHASH_PREFIX@_hash_empty() - empty the hash
*/
void
@LISTHASH_PREFIX@_hash_empty(@LISTHASH_PREFIX@_hash_t *h, @LISTHASH_PREFIX@_freefunc_t freefunc)
{
  int i;

  for (i = 0; i < h->numbuckets; i++)
    if (h->table[i] != NULL)
      @LISTHASH_PREFIX@_list_empty(h->table[i], freefunc);

  h->nents = 0;
}


/*
** @LISTHASH_PREFIX@_hash_free() - delete all of the nodes in the hash
*/
void
@LISTHASH_PREFIX@_hash_free(@LISTHASH_PREFIX@_hash_t *h, @LISTHASH_PREFIX@_freefunc_t freefunc)
{
  int i;

  for (i = 0; i < h->numbuckets; i++)
    if (h->table[i] != NULL)
      @LISTHASH_PREFIX@_list_free(h->table[i], freefunc);

  free(h->table);
  free(h);
}


/*
** @LISTHASH_PREFIX@_hash_search() - iterative search for an element in a hash
** returns:
**  1      match found
**  0      no match
*/
int
@LISTHASH_PREFIX@_hash_search(@LISTHASH_PREFIX@_hash_t *h,
            @LISTHASH_PREFIX@_hashptr_t *hp, void *data,
            @LISTHASH_PREFIX@_matchfunc_t matchfunc)
{
  while (@LISTHASH_PREFIX@_hash_next(h, hp) != 0)
    if ((*matchfunc)(data, @LISTHASH_PREFIX@_listptr_data(&(hp->node))) != 0)
      return 1;

  return 0;
}


/*
** @LISTHASH_PREFIX@_hash_getkey() - hash-based search for an element in a hash
** returns:
**  1      match found
**  0      no match
*/
int
@LISTHASH_PREFIX@_hash_getkey(@LISTHASH_PREFIX@_hash_t *h,
            @LISTHASH_PREFIX@_hashptr_t *hp, void *key,
            @LISTHASH_PREFIX@_matchfunc_t matchfunc)
{
#ifdef DS_DEBUG
  printf("==> @LISTHASH_PREFIX@_hash_getkey(h=0x%lx, hp={%d,0x%lx}, "
         "key=0x%lx, matchfunc=0x%lx)\n",
         h, hp->bucket, hp->node, key, matchfunc);
#endif

  if (hp->bucket == -1)
  {
    hp->bucket = (*(h->hashfunc))(key, h->numbuckets);
#ifdef DS_DEBUG
    printf("    @LISTHASH_PREFIX@_hash_getkey(): hp->bucket "
           "set to %d\n", hp->bucket);
#endif
  }

  if (h->table[hp->bucket] == NULL)
  {
#ifdef DS_DEBUG
    printf("    @LISTHASH_PREFIX@_hash_getkey(): no list "
           "for bucket %d, returning 0\n", hp->bucket);
#endif
    hp->bucket = -1;
    return 0;
  }

#ifdef DS_DEBUG
  printf("<== @LISTHASH_PREFIX@_hash_getkey(): "
         "returning @LISTHASH_PREFIX@_list_search()\n");
#endif
  return @LISTHASH_PREFIX@_list_search(h->table[hp->bucket], &(hp->node),
               key, matchfunc);
}


/*
** @LISTHASH_PREFIX@_hash_add() - add an element to the hash
** returns:
**  0      success
**  -1 (and sets errno)  failure
*/
int
@LISTHASH_PREFIX@_hash_add(@LISTHASH_PREFIX@_hash_t *h, void *data)
{
  int bucket, i;

#ifdef DS_DEBUG
  printf("==> @LISTHASH_PREFIX@_hash_add(h=0x%lx, data=0x%lx)\n",
         h, data);
#endif

  bucket = (*(h->hashfunc))(data, h->numbuckets);
#ifdef DS_DEBUG
  printf("    @LISTHASH_PREFIX@_hash_add(): inserting in bucket %d\n",
         bucket);
#endif
  if (h->table[bucket] == NULL)
  {
#ifdef DS_DEBUG
    printf("    @LISTHASH_PREFIX@_hash_add(): creating new list\n");
#endif
    h->table[bucket] = @LISTHASH_PREFIX@_list_new(LIST_QUEUE, NULL);
  }

#ifdef DS_DEBUG
  printf("<== @LISTHASH_PREFIX@_hash_add(): "
         "returning @LISTHASH_PREFIX@_list_add()\n");
#endif
  i = @LISTHASH_PREFIX@_list_add(h->table[bucket], data);
  if (i == 0)
    h->nents++;
  return i;
}


