/**************************************************************

phot_hash.c (C-Munipack project)
HASH table
Copyright (C) 2003 David Motl, dmotl@volny.cz

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

**************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "hash.h"
#include "cmpack_common.h"

/********************   Public functions    ***********************/

/* Init table */
void hash_init(CmpackHashTable *tab)
{
	memset(tab->tab, 0, HASHSIZE*sizeof(CmpackHashItem*)); 
}

/* Insert key to the table */
void hash_insert(CmpackHashTable *tab, const char *key, void *ptr)
{
	CmpackHashItem *item = (CmpackHashItem*) cmpack_calloc(1, sizeof(CmpackHashItem));
	if (item) {
		item->ptr = ptr;
		item->next = tab->tab[key[0]&HASHMASK];
		tab->tab[key[0]&HASHMASK] = item;
	}
}

/* Search record in the table */
void *hash_search(CmpackHashTable *tab, const char *key)
{
	CmpackHashItem *first = tab->tab[key[0]&HASHMASK];
	while (first) {
		if (strcmp(*((char**)first->ptr), key)==0)
			return first->ptr;
		first = first->next;
	}
	return NULL;
}

/* Delete key from the table */
void hash_delete(CmpackHashTable *tab, const char *key, void *ptr)
{
	CmpackHashItem *item, *next, *prev;
	CmpackHashItem **plist = &tab->tab[key[0]&HASHMASK];
	
	item = *plist;
	prev = NULL;
	while (item) {
		next = item->next;
		if (item->ptr == ptr) {
			if (prev) 
				prev->next = next;
			else
				*plist = next; 
			cmpack_free(item);	
			break;
		}
		prev = item;
		item = next;
	}
}

/* Clear the table */
void hash_clear(CmpackHashTable *tab)
{
	int i;
	CmpackHashItem *item, *next;
	
	for (i=0; i<HASHSIZE; i++) {
		item = tab->tab[i];
		while (item) {
			next = item->next;
			cmpack_free(item);
			item = next;
		}
	}
	memset(tab->tab, 0, HASHSIZE*sizeof(CmpackHashItem*));
}
