//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #ifndef CSTRINGHASH_H #define CSTRINGHASH_H #pragma once #include "string.h" #define STRING_HASH_TABLE_SIZE 701 template class CStringHash { public: CStringHash() { memset( m_HashTable, 0, sizeof( StringHashNode_t * ) * STRING_HASH_TABLE_SIZE ); } ~CStringHash() { int i; for( i = 0; i < STRING_HASH_TABLE_SIZE; i++ ) { StringHashNode_t *curEntry; curEntry = m_HashTable[i]; if( curEntry ) { StringHashNode_t *next; next = curEntry->next; delete curEntry; curEntry = next; } } } // return false if it already exists // there can only be one entry for each string. bool Insert( const char *string, T val ) { unsigned int hashID = HashString( string ); StringHashNode_t *newEntry; if( !m_HashTable[hashID] ) { // first on at this hashID // fixme: need to make the allocation function configurable. newEntry = m_HashTable[hashID] = new StringHashNode_t; newEntry->next = NULL; } else { StringHashNode_t *curEntry; curEntry = m_HashTable[hashID]; while( curEntry ) { if( stricmp( curEntry->string, string ) == 0 ) { // replace the data at the current entry with the enw data. curEntry->data = val; return false; } curEntry = curEntry->next; } newEntry = new StringHashNode_t; newEntry->next = m_HashTable[hashID]; m_HashTable[hashID] = newEntry; } int len = strlen( string ) + 1; newEntry->string = new char[len]; Q_strncpy( newEntry->string, string, len ); newEntry->data = val; return true; } T Find( const char *string ) { int hashID = HashString( string ); StringHashNode_t *curEntry; curEntry = m_HashTable[hashID]; while( curEntry ) { if( stricmp( curEntry->string, string ) == 0 ) { return curEntry->data; } curEntry = curEntry->next; } return NULL; } private: unsigned int HashString( const char *string ) { const char *s = string; unsigned int result = 0; while( *s ) { result += tolower( ( int )*s ) * 6029; result *= 5749; s++; } return result % STRING_HASH_TABLE_SIZE; } typedef struct StringHashNode_s { char *string; T data; struct StringHashNode_s *next; } StringHashNode_t; StringHashNode_t *m_HashTable[STRING_HASH_TABLE_SIZE]; }; #endif // CSTRINGHASH_H