Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

117 lines
2.4 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #ifndef CSTRINGHASH_H
  8. #define CSTRINGHASH_H
  9. #pragma once
  10. #include "string.h"
  11. #define STRING_HASH_TABLE_SIZE 701
  12. template <class T> class CStringHash
  13. {
  14. public:
  15. CStringHash()
  16. {
  17. memset( m_HashTable, 0, sizeof( StringHashNode_t * ) * STRING_HASH_TABLE_SIZE );
  18. }
  19. ~CStringHash()
  20. {
  21. int i;
  22. for( i = 0; i < STRING_HASH_TABLE_SIZE; i++ )
  23. {
  24. StringHashNode_t *curEntry;
  25. curEntry = m_HashTable[i];
  26. if( curEntry )
  27. {
  28. StringHashNode_t *next;
  29. next = curEntry->next;
  30. delete curEntry;
  31. curEntry = next;
  32. }
  33. }
  34. }
  35. // return false if it already exists
  36. // there can only be one entry for each string.
  37. bool Insert( const char *string, T val )
  38. {
  39. unsigned int hashID = HashString( string );
  40. StringHashNode_t *newEntry;
  41. if( !m_HashTable[hashID] )
  42. {
  43. // first on at this hashID
  44. // fixme: need to make the allocation function configurable.
  45. newEntry = m_HashTable[hashID] = new StringHashNode_t;
  46. newEntry->next = NULL;
  47. }
  48. else
  49. {
  50. StringHashNode_t *curEntry;
  51. curEntry = m_HashTable[hashID];
  52. while( curEntry )
  53. {
  54. if( stricmp( curEntry->string, string ) == 0 )
  55. {
  56. // replace the data at the current entry with the enw data.
  57. curEntry->data = val;
  58. return false;
  59. }
  60. curEntry = curEntry->next;
  61. }
  62. newEntry = new StringHashNode_t;
  63. newEntry->next = m_HashTable[hashID];
  64. m_HashTable[hashID] = newEntry;
  65. }
  66. int len = strlen( string ) + 1;
  67. newEntry->string = new char[len];
  68. Q_strncpy( newEntry->string, string, len );
  69. newEntry->data = val;
  70. return true;
  71. }
  72. T Find( const char *string )
  73. {
  74. int hashID = HashString( string );
  75. StringHashNode_t *curEntry;
  76. curEntry = m_HashTable[hashID];
  77. while( curEntry )
  78. {
  79. if( stricmp( curEntry->string, string ) == 0 )
  80. {
  81. return curEntry->data;
  82. }
  83. curEntry = curEntry->next;
  84. }
  85. return NULL;
  86. }
  87. private:
  88. unsigned int HashString( const char *string )
  89. {
  90. const char *s = string;
  91. unsigned int result = 0;
  92. while( *s )
  93. {
  94. result += tolower( ( int )*s ) * 6029;
  95. result *= 5749;
  96. s++;
  97. }
  98. return result % STRING_HASH_TABLE_SIZE;
  99. }
  100. typedef struct StringHashNode_s
  101. {
  102. char *string;
  103. T data;
  104. struct StringHashNode_s *next;
  105. } StringHashNode_t;
  106. StringHashNode_t *m_HashTable[STRING_HASH_TABLE_SIZE];
  107. };
  108. #endif // CSTRINGHASH_H