template class HashTable { public: HashTable( int inSize ); ~HashTable(); Type lookup( int inKeyA, int inKeyB, char *outFound ); void insert( int inKeyA, int inKeyB, Type inItem ); // flush all entries from table void clear(); private: int mSize; Type *mTable; char *mSetFlags; int *mKeysA; int *mKeysB; int mHitCount; int mMissCount; int computeHash( int inKeyA, int inKeyB ); }; // Wow... never new that template function implementations must be in the // same file as the declaration template HashTable::HashTable( int inSize ) : mSize( inSize ), mTable( new Type[ inSize ] ), mSetFlags( new char[ inSize ] ), mKeysA( new int[ inSize ] ), mKeysB( new int[ inSize ] ), mHitCount( 0 ), mMissCount( 0 ) { clear(); } #include template HashTable::~HashTable() { delete [] mTable; delete [] mSetFlags; delete [] mKeysA; delete [] mKeysB; printf( "%d hits, %d misses, %f hit ratio\n", mHitCount, mMissCount, mHitCount / (double)( mHitCount + mMissCount ) ); } template inline int HashTable::computeHash( int inKeyA, int inKeyB ) { int hashKey = ( inKeyA * 734727 + inKeyB * 263474 ) % mSize; if( hashKey < 0 ) { hashKey += mSize; } return hashKey; } template Type HashTable::lookup( int inKeyA, int inKeyB, char *outFound ) { int hashKey = computeHash( inKeyA, inKeyB ); if( mSetFlags[ hashKey ] && mKeysA[ hashKey ] == inKeyA && mKeysB[ hashKey ] == inKeyB ) { // hit mHitCount ++; *outFound = true; } else { // miss mMissCount ++; *outFound = false; } return mTable[ hashKey ]; } template void HashTable::insert( int inKeyA, int inKeyB, Type inItem ) { int hashKey = computeHash( inKeyA, inKeyB ); mSetFlags[ hashKey ] = true; mKeysA[ hashKey ] = inKeyA; mKeysB[ hashKey ] = inKeyB; mTable[ hashKey ] = inItem; } template void HashTable::clear() { for( int i=0; i