#include "openaxiom-c-macros.h"
#define _HASH_C
#include "debug.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "halloc.h"
#include "hash.h"
void
hash_init(HashTable *table, int size, EqualFunction equal,
HashcodeFunction hash_code)
{
int i;
table->table =
(HashEntry **) halloc(size * sizeof(HashEntry *), "HashEntry");
for (i = 0; i < size; i++)
table->table[i] = NULL;
table->size = size;
table->equal = equal;
table->hash_code = hash_code;
table->num_entries = 0;
}
void
free_hash(HashTable* table, FreeFunction free_fun)
{
if (table) {
int i;
for (i = 0; i < table->size; i++) {
HashEntry *e, *next;
for (e = table->table[i]; e != NULL;) {
next = e->next;
(*free_fun) ((char*) e->data);
(*e).data=0;
free(e);
e = next;
}
}
free(table->table);
}
}
void
hash_insert(HashTable* table, char* data, const char *key)
{
HashEntry *entry = (HashEntry *) halloc(sizeof(HashEntry), "HashEntry");
int code;
entry->data = data;
entry->key = key;
code = (*table->hash_code) (key, table->size) % table->size;
#ifdef DEBUG
fprintf(stderr, "Hash value = %d\n", code);
#endif
entry->next = table->table[code];
table->table[code] = entry;
table->num_entries++;
}
char *
hash_find(HashTable* table, const char *key)
{
HashEntry *entry;
int code = table->hash_code(key, table->size) % table->size;
for (entry = table->table[code]; entry != NULL; entry = entry->next)
if ((*table->equal) (entry->key, key))
return entry->data;
return NULL;
}
char *
hash_replace(HashTable* table, char* data, const char* key)
{
HashEntry *entry;
int code = table->hash_code(key, table->size) % table->size;
for (entry = table->table[code]; entry != NULL; entry = entry->next)
if ((*table->equal) (entry->key, key)) {
entry->data = data;
return entry->data;
}
return NULL;
}
void
hash_delete(HashTable* table, const char* key)
{
HashEntry **entry;
int code = table->hash_code(key, table->size) % table->size;
for (entry = &table->table[code]; *entry != NULL; entry = &((*entry)->next))
if ((*table->equal) ((*entry)->key, key)) {
*entry = (*entry)->next;
table->num_entries--;
return;
}
}
void
hash_map(HashTable* table, MappableFunction func)
{
int i;
HashEntry *e;
if (table == NULL)
return;
for (i = 0; i < table->size; i++)
for (e = table->table[i]; e != NULL; e = e->next)
(*func) (e->data);
}
HashEntry *
hash_copy_entry(HashEntry *e)
{
HashEntry *ne;
if (e == NULL)
return e;
ne = (HashEntry *) halloc(sizeof(HashEntry), "HashEntry");
ne->data = e->data;
ne->key = e->key;
ne->next = hash_copy_entry(e->next);
return ne;
}
HashTable *
hash_copy_table(HashTable* table)
{
HashTable *nt = (HashTable *) halloc(sizeof(HashTable), "copy hash table");
int i;
nt->size = table->size;
nt->num_entries = table->num_entries;
nt->equal = table->equal;
nt->hash_code = table->hash_code;
nt->table = (HashEntry **) halloc(nt->size * sizeof(HashEntry *),
"copy table");
for (i = 0; i < table->size; i++)
nt->table[i] = hash_copy_entry(table->table[i]);
return nt;
}
int
string_hash(const char* s, int size)
{
int c = 0;
const char *p =s;
while (*p)
c += *p++;
return c % size;
}
int
string_equal(const char* s1, const char* s2)
{
return (strcmp(s1, s2) == 0);
}
char *
alloc_string(const char* str)
{
char * result;
result = halloc(strlen(str)+1,"alloc_string");
strcpy(result,str);
return (result);
}