#include "index.h"
#include <stdio.h>
#include <malloc.h>
#include <string.h>

/* simplistic collection class... */

Index *newIndex(int hashmod, int isString)
{
	Index *c;
	int i;
	c = (Index *) malloc(sizeof(Index));
	if (!c) return 0;
	memset(c, 0, sizeof(Index));
	c->ptr = (void **) malloc(hashmod * sizeof(void *));
	c->hashmod = hashmod;
	c->isString = isString;
	if (c->ptr) memset(c->ptr, 0, hashmod*sizeof(void *));
	return c;
}

IndexNode *newIndexNode()
{
	IndexNode *node;
	node = (IndexNode *) malloc(sizeof(IndexNode));
	if (!node) return 0;
	memset(node, 0, sizeof(IndexNode));
	return node;
}

void deleteIndex(Index *c)
{
	int i;
	IndexNode *p;
	if (!c) return;

	/* free index nodes */
	for (i=0;i<c->hashmod;i++) {
		while (c->ptr[i]) {
			p = c->ptr[i];
			c->ptr[i] = p->next;
			if (c->isString)
				free(p->u.ks.keystr);
			free(p);
		}
	}
	if (c->ptr) free(c->ptr);
	free(c);
}

int calcHash(Index *c, int key1, int key2)
{
	int i = key1+key2;
	if (i<0) i = -i;
	return (i % c->hashmod);
}

int calcHashStr(Index *c, char *str)
{
	int sum, i;
	sum = 0;
	for (i=0;i<4;i++)
		if (*str)
			sum += *str++;
	return (sum % c->hashmod);
}

void setIndexEntry(Index *c, int val, int key1, int key2)
{
	int bucket;
	IndexNode *p;
	bucket = calcHash(c, key1, key2);
	for (p = c->ptr[bucket];p; p=p->next) {
		if (p->u.kn.key1==key1 && p->u.kn.key2==key2) {
			p->slot = val;
			return;
		}
	}
	/* insert into table */
	p = newIndexNode();
	p->slot = val;
	p->u.kn.key1 = key1;
	p->u.kn.key2 = key2;
	p->next = c->ptr[bucket];
	c->ptr[bucket] = p;
}

void setIndexEntryString(Index *c, int val, char *str)
{
	int bucket;
	IndexNode *p;
	bucket = calcHashStr(c, str);
	for (p = c->ptr[bucket];p; p=p->next) {
		if (strcmp(p->u.ks.keystr,str)==0) {
			p->slot = val;
			return;
		}
	}
	/* insert into table */
	p = newIndexNode();
	p->slot = val;
	p->u.ks.keystr = strdup(str);
	p->next = c->ptr[bucket];
	c->ptr[bucket] = p;
}

int findIndexEntry(Index *c, int key1, int key2)
{
	int bucket;
	IndexNode *p;
	if (!c) return -1;
	bucket = calcHash(c, key1, key2);
	for (p = c->ptr[bucket];p; p=p->next) {
		if (p->u.kn.key1==key1 && p->u.kn.key2==key2) {
			return p->slot;
		}
	}
	return -1;
}

int findIndexEntryString(Index *c, char *str)
{
	int bucket;
	IndexNode *p;
	if (!c) return -1;
	bucket = calcHashStr(c, str);
	for (p = c->ptr[bucket];p; p=p->next) {
		if (strcmp(p->u.ks.keystr, str)==0) {
			return p->slot;
		}
	}
	return -1;
}

