// Emacs: -*- C++ -*-

//
//	Copyright 1993, Center for Computer Vision and Visualization,
//	University of Florida.  All rights reserved.
//

static char copyright[] = "Copyright 1993, Center for Computer Vision and Visualization,\nUniversity of Florida.  All rights reserved.\n";

static char rcsid[] = "$Id: HashTable.c,v 1.9 1994/01/31 16:36:55 thoth Exp $";

// 
// $Log: HashTable.c,v $
// Revision 1.9  1994/01/31  16:36:55  thoth
// We now document internal errors when they occur.
//
// Revision 1.8  1993/05/28  15:05:25  thoth
// removed dependency on with-ia-pointset*
//
// Revision 1.7  93/05/27  18:05:06  thoth
// eliminated dependency on internal testing file.
// 
// Revision 1.6  93/05/26  16:57:42  thoth
// Copyright Notices
// 
// Revision 1.5  93/02/12  16:21:21  thoth
// more comments
// 
// Revision 1.4  92/12/16  14:48:03  thoth
// conversion to IA_ mostly complete
// 
// Revision 1.3  92/09/14  10:09:36  thoth
// the hash table data pointers are now the responsibility of IntPointSet
// 
// Revision 1.2  92/08/26  13:42:45  thoth
// eliminated cruft to work around g++ brokenness
// 
// Revision 1.1  92/08/23  13:30:04  thoth
// Initial revision
// 
// 

#include <stdlib.h>
#include "HashTable.h"

#ifdef IA_PRII
#pragma implementation
#endif

IA_HashTable::IA_HashTable() {
    for (int i=0; i<TBLSIZE; i++)
	this->buckets[i] = 0;
}
IA_HashTable::~IA_HashTable() {
    for (int i=0; i<TBLSIZE; i++) {
	link *scan=this->buckets[i];
	while (scan) {
	    link *temp = scan;
	    scan = scan->next;
	    delete temp;
	}
    }
}

int IA_HashTable::reference(HType in, HType *out)
{
    *out = in;

    link	**scan;

    for (scan = &this->buckets[in->hash_self(TBLSIZE)];
	 *scan && !(*scan)->data->equal(in);
	 scan = &(*scan)->next) {
    }

    if (*scan) {
	// we found an ->equal()
	*out = (*scan)->data;
	return 1;
    } else {
	// there are none ->equal()
	*scan = new link;
	(*scan)->next = 0;
	(*scan)->data = in;
	return 0;
    }
}

void IA_HashTable:: remove(HType in)
{
    link	**target;

    for (target = &this->buckets[in->hash_self(TBLSIZE)];
	 *target && (*target)->data != in;
	 target = &(*target)->next) {
    }

    link	*temp;
    temp = *target;

    if (temp==0) {
	IA::internal_error(__FILE__, __LINE__);
    }

    *target = temp->next;
    // the data is not our responsibility
    delete temp;
}
