123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- // Notes
- // Make sure extension is stripped if it needs to be
- // Template class must have
- // 1. A GetName() accessor - a null terminated string case insensitive
- // 2. A Destroy() function - normally "delete this"
- // 3. SetNext(T *) and T *GetNext() functions
- #define HASH_SIZE 1024
- template <class T, int TSize = HASH_SIZE, int (*TCompare)(const char *, const char *) = &strcmp>
- class CHash
- {
- private:
- T *mHashTable[TSize];
- T *mNext;
- int mCount;
- T *mPrevious; // Internal work variable
- long mHash; // Internal work variable
- // Creates the hash value and sets the mHash member
- void CreateHash(const char *key)
- {
- int i = 0;
- char letter;
- mHash = 0;
- letter = *key++;
- while (letter)
- {
- mHash += (long)(letter) * (i + 119);
- i++;
- letter = *key++;
- }
- mHash &= TSize - 1;
- }
- public:
- // Constructor
- CHash(void)
- {
- memset(mHashTable, NULL, sizeof(mHashTable));
- mNext = NULL;
- mCount = 0;
- mPrevious = NULL;
- mHash = 0;
- }
- // Destructor
- ~CHash(void)
- {
- #ifdef _DEBUG
- // Com_OPrintf("Shutting down %s hash table .....", typeid(T).name());
- #endif
- clear();
- #ifdef _DEBUG
- // Com_OPrintf(" done\n");
- #endif
- }
- // Returns the total number of entries in the hash table
- int count(void) const { return(mCount); }
- // Inserts an item into the hash table
- void insert(T *item)
- {
- CreateHash(item->GetName());
- item->SetNext(mHashTable[mHash]);
- mHashTable[mHash] = item;
- mCount++;
- }
- // Finds an item in the hash table (sets the mPrevious member)
- T *find(const char *key)
- {
- CreateHash(key);
- T *item = mHashTable[mHash];
- mPrevious = NULL;
- while(item)
- {
- mNext = item->GetNext();
- if(!TCompare(item->GetName(), key))
- {
- return(item);
- }
- mPrevious = item;
- item = mNext;
- }
- return(NULL);
- }
- // Remove item from the hash table referenced by key
- bool remove(const char *key)
- {
- T *item = find(key);
- if(item)
- {
- T *next = item->GetNext();
- if(mPrevious)
- {
- mPrevious->SetNext(next);
- }
- else
- {
- mHashTable[mHash] = next;
- }
- item->Destroy();
- mCount--;
- return(true);
- }
- return(false);
- }
- // Remove item from hash referenced by item
- bool remove(T *item)
- {
- return(remove(item->GetName()));
- }
- // Returns the first valid entry
- T *head(void)
- {
- mHash = -1;
- mNext = NULL;
- return(next());
- }
- // Returns the next entry in the hash table
- T *next(void)
- {
- T *item;
- assert(mHash < TSize);
- if(mNext)
- {
- item = mNext;
- mNext = item->GetNext();
- return(item);
- }
- mHash++;
- for( ; mHash < TSize; mHash++)
- {
- item = mHashTable[mHash];
- if(item)
- {
- mNext = item->GetNext();
- return(item);
- }
- }
- return(NULL);
- }
- // Destroy all entries in the hash table
- void clear(void)
- {
- T *item = head();
- while(item)
- {
- remove(item);
- item = next();
- }
- }
- // Override the [] operator
- T *operator[](const char *key) { return(find(key)); }
- };
- // end
|