/* hash.c
 * Functions for hash-table
 *
 * Written by Matt Levy.
 * Modified by Artur Mikitiuk.
 * Modified  5 Sep 1999 by Neil Moore <neil@cs.uky.edu>
 *
 * Part of lderes.  See COPYRIGHT for copyright information.
 *
 */

#include <stdlib.h>
#include "global.h"
#include "hash.h"

symbol_table_entry *hashtable[HASH_TABLE_SIZE], *idIndex[HASH_TABLE_SIZE];
int count = 0;
int primesTable[] = {7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,
		    89,97,101,103,107,109,113,127,131,137,139};

symbol_table_entry *createHashEntry(char *name, int id)
{
  symbol_table_entry *newEntry;
  
  newEntry = (symbol_table_entry *) malloc(sizeof(symbol_table_entry));
  if (newEntry == NULL)
     fatal_error("Out of memory");
  newEntry->name = name;
  newEntry->id = id;
  newEntry->next = NULL;
  idIndex[id] = newEntry;
  return newEntry;
}

inline void initializeHashtable()
{
  int index;
  for (index = 0; index < HASH_TABLE_SIZE; index++){
     hashtable[index] = NULL;
     idIndex[index] = NULL;
  }
}

inline int generateKey(char *name)
{
  int key, bit = 0;
  for (key = 0; *name != '\0'; name++){
	 key = (key + (*name*primesTable[bit])) % MAX_INT;
	 /*	 key = (key + *name) % MAX_INT; */
	 bit = (bit+1) % INT_SIZE;
  }
  return key;
}

int hash(int key)
{
  return key % HASH_TABLE_SIZE;
}

int insert(char *name, int index)
{
  int key, location;
  symbol_table_entry *tempEntry;
  key = generateKey(name);
  location = hash(key);
  if (hashtable[location] == NULL) {
	 hashtable[location] = createHashEntry(name,index);
  } else {
	 tempEntry = hashtable[location];
	 hashtable[location] = createHashEntry(name,index);
	 hashtable[location]->next = tempEntry;
  }
  count++; /* DISPLAY(printf("%d %s\n",count,name)); */
  return location;
}

inline int lookupLocation(char *name)
{
  int key, location;
  symbol_table_entry *tempEntry;
  
  key = generateKey(name);
  location = hash(key);
  for (tempEntry = hashtable[location]; tempEntry != NULL;
      tempEntry = tempEntry->next)
	 if (strcmp(tempEntry->name,name) == 0)
		return tempEntry->id;
  return -1;
}

inline char *lookupName(int id)
{
  if (idIndex[id] == 0)
	 return NULL;
  return idIndex[id]->name;
}

inline int hashTableSize()
{
  return count;
}
