//////////////////////////////////////////////////////////////////////////////////////// // RAVEN STANDARD TEMPLATE LIBRARY // (c) 2002 Activision // // // Hash Pool // --------- // The hash pool stores raw data of variable size. It uses a hash table to check for // redundant data, and upon finding any, will return the existing handle. Otherwise // it copies the data to memory and returns a new handle. // // // NOTES: // // // //////////////////////////////////////////////////////////////////////////////////////// #if !defined(RATL_HASH_POOL_VS_INC) #define RATL_HASH_POOL_VS_INC //////////////////////////////////////////////////////////////////////////////////////// // Includes //////////////////////////////////////////////////////////////////////////////////////// #if !defined(RATL_COMMON_INC) #include "ratl_common.h" #endif namespace ratl { //////////////////////////////////////////////////////////////////////////////////////// // The Hash Pool //////////////////////////////////////////////////////////////////////////////////////// template class hash_pool { int mHandles[SIZE_HANDLES]; // each handle holds the start index of it's data int mDataAlloc; // where the next chunck of data will go char mData[SIZE]; #ifdef _DEBUG int mFinds; // counts how many total finds have run int mCurrentCollisions; // counts how many collisions on the last find int mTotalCollisions; // counts the total number of collisions int mTotalAllocs; #endif //////////////////////////////////////////////////////////////////////////////////// // This function searches for a handle which already stores the data (assuming the // handle is a hash within range SIZE_HANDLES). // // If it failes, it returns false, and the handle passed in points to the next // free slot. //////////////////////////////////////////////////////////////////////////////////// bool find_existing(int& handle, const void* data, int datasize) { #ifdef _DEBUG mFinds++; mCurrentCollisions = 0; #endif while (mHandles[handle]) // So long as a handle exists there { if (mem::eql((void*)(&mData[mHandles[handle]]), data, datasize)) { return true; // found } handle=(handle+1)&(SIZE_HANDLES-1); // incriment the handle #ifdef _DEBUG mCurrentCollisions ++; mTotalCollisions ++; //assert(mCurrentCollisions < 16); // If We Had 16+ Collisions, Hash May Be Inefficient. // Evaluate SIZE and SIZEHANDLES #endif } return false; // failed to find } //////////////////////////////////////////////////////////////////////////////////// // A simple hash function for the range of [0, SIZE_HANDLES] //////////////////////////////////////////////////////////////////////////////////// int hash(const void* data, int datasize) { int h=0; for (int i=0; i=0 && handle