/////// File: HashTable.C /////// #include #include #include #include "HashTable.h" template HashTable::HashTable (Uint k /* = 8 */, Uint m /* = H_MULT */) : bits(k), mult(m), len(0) { int size = 1 << bits; ht = new List*[size]; for ( int i = 0; i < size; i++ ) ht[i] = NULL; } template HashTable::~HashTable() { int size = 1 << bits; for ( int i = 0; i < size; i++ ) if ( ht[i] ) delete(ht[i]); delete(ht); } Uint str_to_u(const char *str) // intentional file scope function { Uint value = 7u; char c; while ( (c = *str) != '\0' ) { value *= c; str++; } return(value); } template Uint HashTable::hash(const char* key) { Uint val = 0; val = str_to_u(key); return( (val*mult) >> (CHAR_BIT*sizeof(Uint) - bits)); } template int HashTable::get(const char* key, T& rval) { List* a = ht[hash(key)]; if ( !a ) return(noe); ListIterator next(*a); T item; while ( next(item) ) if ( strcmp (key, getkey(item)) == 0 ) { rval = item; return( ! noe); // entry found } return(noe); // not found } template int HashTable::is_on(char* key) // record already on table? { List* a = ht[hash(key)]; if ( !a || ! on_list(*a, key) ) return(noe); return( !noe ); } template // static private member function int HashTable::on_list (List& l, char* key) { T item; ListIterator next(l); while ( next(item) ) if ( strcmp (key, getkey(item)) == 0 ) return(1); // entry found return(0); // not found } template int HashTable::rid(const char* key) { Uint code = hash(key); List* a = ht[code]; if ( !a ) return(noe); ListIterator next(*a); T item; while ( next(item) ) if ( strcmp (key, getkey(item)) == 0 ) { next.del(); len--; if ( a->is_empty() ) ht[code] = NULL; return(! noe); } return(noe); } // enter new entry into hash table template void HashTable::put(T& a) // enter a into hash table { char *key = getkey(a); Uint hc = hash(key); List* l = ht[hc]; if ( l == NULL ) // loccation not used before { ht[hc] = new List(a); len++; return; } if ( ! on_list(*l, key) ) // if not already in table { len++; l->put_on(a); } // put record on table return; }