//[c]dictionary.cpp - a simple hashtable class //[c] //[l]: Header File:dictionary.h //[c] //[of]: Includes //[c] #include //[c] #include "dictionary.h" //[cf] //[of]: Constants //[c] #define default_size 10 #define max(x, y) (((x)>(y))?(x):(y)) //[cf] //[of]: Private //[c] //[of]: increaseTally() //[c]increase the counter of items //[c]grow the array if more than 75% of slots are used //[c] void Dictionary::increaseTally() { tally++; if( 4*tally>3*size ) resize(size*3/2); } //[cf] //[of]: decreaseTally() //[c]decrease the counter of items //[c]reduce the array if less than 30% of slots are used //[c] void Dictionary::decreaseTally() { tally--; if( 3*tally0 && notEmpty(location) ) { if( match(key(location), k) ) return value(location); location++; if( location==size ) location = 0; count--; } return NULL; } //[cf] //[c] //[c]Adding - Removing //[c] //[of]: add(key, value) //[c]Puts a value //[c] //[c] There must be at least one free slot. //[c] If there were already a value at this slot, the old value is returned. //[c] In such a case, the returned value, and the passed key are no more //[c] referenced by the dictionary, it is the responsibility of the sub-class //[c] to free them. //[c] void* Dictionary::add(void* k, void* v) { int location = slot(k); int count = 1; while( true ) { if( notEmpty(location) ) { if( match(k, key(location)) ) { void* old = value(location); setValue(location, v); return old; } else { location++; if( location==size ) location = 0; count++; } } else { setKey (location, k); setValue (location, v); collisions = max(count, collisions); increaseTally(); return NULL; } } // never happens, but make compilers happy return NULL; } //[cf] //[of]: remove (key) //[c]Removes an item //[c] //[c] Returns the item for the given key or nil if not found. //[c] void Dictionary::remove(void* k) { int location = slot(k); int count = collisions; while( count>0 && notEmpty(location) ) { if( match(k, key(location)) ) { clear(location); location++; if( location==size ) location=0; fillUp(location); // useless if we are going to resize decreaseTally(); return; } location++; if( location==size ) location=0; count--; } return; } //[cf]