#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "hashtab.h"
#define HASH_SIZE 11
#define TEST_AMOUNT 100

typedef struct data_t
{
    int field1;
    int field2;
} data_t;

int compare_data(const void * data1, const void * data2)
{
    const data_t * check1 = (const data_t *)data1;
    const data_t * check2 = (const data_t *)data2;
    return (check1->field1 != check2->field1 || check1->field2 != check2->field2);
}

unsigned long make_data_key(const void * data)
{
    const data_t * check = (const data_t *)data;
    return (check->field1 * 37 + check->field2);
}

void delete_data(void * data)
{
    data_t * kill = (data_t *)data;
    free(kill);
}

int main()
{
    hash_tab * test_table;
    int some_num;
    int entry_count, kill_count;
    data_t * new_entry;
    data_t * test_rec;
    data_t * find_rec;

    srandom(time(NULL));
    test_table = init_hash_table("my table", compare_data, make_data_key,
				delete_data, HASH_SIZE);
    for (some_num = 0; some_num < TEST_AMOUNT; some_num++) {
	new_entry = (data_t *)malloc(sizeof(data_t));
	new_entry->field1 = some_num;
	new_entry->field2 = 10;
	add_hash_entry(test_table, new_entry);
    }

    entry_count = 0;
    init_hash_walk(test_table);
    while(test_rec = next_hash_walk(test_table)) {
	entry_count++;
    }
    fprintf(stderr, "Found %d entries.\n", entry_count);
    if (entry_count != TEST_AMOUNT) {
	fprintf(stderr, "Not all entries found!\n");
    }

    entry_count = 0;
    init_hash_walk(test_table);
    while(test_rec = next_hash_walk(test_table)) {
	data_t finder;
	finder.field1 = random() % TEST_AMOUNT;
	finder.field2 = 10;
	find_rec = find_hash_entry(test_table, &finder);
	if (!find_rec) {
	    fprintf(stderr, "Couldn't find valid entry!\n");
	    exit(1);
	}
	if (compare_data(&finder, find_rec)) {
	    fprintf(stderr, "find_hash_entry returned wrong data!\n");
	    exit(1);
	}
	entry_count++;
    }
    fprintf(stderr, "Found %d entries while searching.\n", entry_count);
    if (entry_count != TEST_AMOUNT) {
	fprintf(stderr, "Not all entries found!\n");
    }

    entry_count = 0;
    kill_count = 0;
    init_hash_walk(test_table);
    while(test_rec = next_hash_walk(test_table)) {
	data_t finder;
	entry_count++;
	finder.field1 = random() % TEST_AMOUNT;
	finder.field2 = 10;
	find_rec = find_hash_entry(test_table, &finder);
	if (!find_rec) {
	    continue; /* May have deleted already */
	}
	if (compare_data(&finder, find_rec)) {
	    fprintf(stderr, "find_hash_entry returned wrong data!\n");
	    exit(1);
	}
	if (random() % 2) { /* Flip a coin... */
	    if (find_rec == test_rec) {
		fprintf(stderr, "walk entry == search entry\n");
	    }
	    clear_hash_entry(test_table, find_rec);
	    kill_count++;
	}
    }
    fprintf(stderr, "Found %d entries while searching.\n", entry_count);
    fprintf(stderr, "Killed %d entries while walking and searching.\n", kill_count);

    entry_count = 0;
    init_hash_walk(test_table);
    while(test_rec = next_hash_walk(test_table)) {
	entry_count++;
    }
    fprintf(stderr, "Found %d entries after deletion.\n", entry_count);
    if (entry_count + kill_count != TEST_AMOUNT) {
	fprintf(stderr, "Totals do not add up to original amount!\n");
    }

    return 0;
}


syntax highlighted by Code2HTML, v. 0.9.1