#include <stdio.h>
#include <hash.h>


Hash *
sh_create(name, size)
     Rope name;
     unsigned int size;   
{
  static Hash *h;

  if(!(h = (Hash *) malloc(sizeof(Hash))))
    return((Hash *) NULL);

  h->size = size;
  if(!(h->entries = (HashEntry **) malloc(sizeof(HashEntry *) * size)))
    return((Hash *) NULL);

  h->name = name;
  bzero(h->entries, size * sizeof(Hash *));
  return(h);
}


void
sh_destroy(h)
    Hash *h;
{
  HashEntry *he;
  HashEntry *he2;
  int i;
  
  str_freeString(h->name);
  
  for(i = 0; i < h->size; i++)
    {
      he = h->entries[i];
      while(he)
	{
	  he2 = he->next;
	  free(he);
	  he = he2;
	}
    }

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


int
sh_hash(h, str)
     Hash *h;
     Rope str;
{
  unsigned int val = 0;
  
  while(str.length--)
    val += *(str.s)++;
  
  return(val % h->size);
}


HashEntry *
sh_fetch(h, str)
     Hash *h;
     Rope str;
{
  HashEntry *hp;

  if(!h->entries)
    return((HashEntry *) NULL);

  hp = h->entries[sh_hash(h, str)];
  while(hp)
    if(bcmp(str.s, hp->name.s, str.length) == 0)
      return(hp);
    else
      hp = hp->next;

  return((HashEntry *) NULL);
}


sh_store(h, name, data)
     Hash *h;
     Rope name;
     Rope data;
{
  HashEntry *hp;
  unsigned int val;

  if(!(hp = sh_fetch(h, name)))
    {
      if(!(hp = (HashEntry *) malloc(sizeof(HashEntry))))
	return(-1);
      
      hp->name = name;
      val = sh_hash(h, name);
      hp->next = h->entries[val];
      h->entries[val] = hp;
    }
      
  hp->data = data;
}


sh_dump(h)
     Hash *h;
{
  HashEntry *e;
  int i = 0;
  
  for(i = 0; i < h->size; i++)
    {
      e = h->entries[i];
      while(e)
	{
	  printf("%d. %s\n", i, e->name.s);
	  e = e->next;
	}
    }
}
