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

#include <pthread.h>

#include "naht.h"

int		int_compare (void *va, void *vb)
{
	/*
	** To use naht, you will need to provide
	** some function that compares 2 items,
	** and returns 0 if they are not the same.
	*/

	int	a, b;

	a = *(int *) va;
	b = *(int *) vb;

	return (a == b);
}

void	int_discard (void *va)
{
	/*
	** This function will be called whenever
	** an item will be forcibly be removed
	** from storage to make room for a new
	** item. If you want to save your items,
	** this callback would be the place to
	** do it.
	*/

	int	a;
	
	a = *(int *) va;

	printf ("Discarding %d\n", a);
}

void	do_something (void *vp)
{
}


void	*test_routine (void *np)
{
	nahtT *n = (nahtT *) np;
	int		a, b, i;
	void	*vp;

	for (i=0; i<50000; i++)
	{
		b = random();
		/*
		** Look for a random number in the naht
		*/
		vp = naht_find (n, b, &b);
		if (!vp)
		{
			/*
			** If its not found, add it
			*/
			naht_insert (n, b, &b);
			vp = naht_find (n, b, &b);
		}
	
		if (vp)
		{
			a = *(int *)vp;
		} else
		{
			a = -1;
		}

		if (a != b) 
		{
			printf ("FAILED\n");
		}
	}
	return NULL;
}


int main (int argc, char **argv)
{
	nahtT 		*n;
#ifdef THREAD_SAFE
#define THREADS	8
	pthread_t	t[THREADS];
	int			i;
#endif

	/*
	** Initialize a 2 MB naht to store int's.
	*/

	n = naht_init (sizeof(int), 2.0, int_compare, int_discard);
	if (!n)
	{
		fprintf (stderr, "naht_init() failed\n");
		return (0);
	}

#ifdef THREAD_SAFE	
	for (i=0; i<THREADS; i++) pthread_create (&t[i], NULL, test_routine, (void *) n);
	for (i=0; i<THREADS; i++) pthread_join (t[i], NULL);
#else
	test_routine((void *)n);
#endif

	/*
	** Do something to all of the items currently in the hash table
	*/

	naht_walk (n, do_something);

	/*
	** Clean up after you are done
	*/
	naht_free (n);

	printf ("OK\n");
	return (0);
}
