chash.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. // Notes
  2. // Make sure extension is stripped if it needs to be
  3. // Template class must have
  4. // 1. A GetName() accessor - a null terminated string case insensitive
  5. // 2. A Destroy() function - normally "delete this"
  6. // 3. SetNext(T *) and T *GetNext() functions
  7. #define HASH_SIZE 1024
  8. template <class T, int TSize = HASH_SIZE, int (*TCompare)(const char *, const char *) = &strcmp>
  9. class CHash
  10. {
  11. private:
  12. T *mHashTable[TSize];
  13. T *mNext;
  14. int mCount;
  15. T *mPrevious; // Internal work variable
  16. long mHash; // Internal work variable
  17. // Creates the hash value and sets the mHash member
  18. void CreateHash(const char *key)
  19. {
  20. int i = 0;
  21. char letter;
  22. mHash = 0;
  23. letter = *key++;
  24. while (letter)
  25. {
  26. mHash += (long)(letter) * (i + 119);
  27. i++;
  28. letter = *key++;
  29. }
  30. mHash &= TSize - 1;
  31. }
  32. public:
  33. // Constructor
  34. CHash(void)
  35. {
  36. memset(mHashTable, NULL, sizeof(mHashTable));
  37. mNext = NULL;
  38. mCount = 0;
  39. mPrevious = NULL;
  40. mHash = 0;
  41. }
  42. // Destructor
  43. ~CHash(void)
  44. {
  45. #ifdef _DEBUG
  46. // Com_OPrintf("Shutting down %s hash table .....", typeid(T).name());
  47. #endif
  48. clear();
  49. #ifdef _DEBUG
  50. // Com_OPrintf(" done\n");
  51. #endif
  52. }
  53. // Returns the total number of entries in the hash table
  54. int count(void) const { return(mCount); }
  55. // Inserts an item into the hash table
  56. void insert(T *item)
  57. {
  58. CreateHash(item->GetName());
  59. item->SetNext(mHashTable[mHash]);
  60. mHashTable[mHash] = item;
  61. mCount++;
  62. }
  63. // Finds an item in the hash table (sets the mPrevious member)
  64. T *find(const char *key)
  65. {
  66. CreateHash(key);
  67. T *item = mHashTable[mHash];
  68. mPrevious = NULL;
  69. while(item)
  70. {
  71. mNext = item->GetNext();
  72. if(!TCompare(item->GetName(), key))
  73. {
  74. return(item);
  75. }
  76. mPrevious = item;
  77. item = mNext;
  78. }
  79. return(NULL);
  80. }
  81. // Remove item from the hash table referenced by key
  82. bool remove(const char *key)
  83. {
  84. T *item = find(key);
  85. if(item)
  86. {
  87. T *next = item->GetNext();
  88. if(mPrevious)
  89. {
  90. mPrevious->SetNext(next);
  91. }
  92. else
  93. {
  94. mHashTable[mHash] = next;
  95. }
  96. item->Destroy();
  97. mCount--;
  98. return(true);
  99. }
  100. return(false);
  101. }
  102. // Remove item from hash referenced by item
  103. bool remove(T *item)
  104. {
  105. return(remove(item->GetName()));
  106. }
  107. // Returns the first valid entry
  108. T *head(void)
  109. {
  110. mHash = -1;
  111. mNext = NULL;
  112. return(next());
  113. }
  114. // Returns the next entry in the hash table
  115. T *next(void)
  116. {
  117. T *item;
  118. assert(mHash < TSize);
  119. if(mNext)
  120. {
  121. item = mNext;
  122. mNext = item->GetNext();
  123. return(item);
  124. }
  125. mHash++;
  126. for( ; mHash < TSize; mHash++)
  127. {
  128. item = mHashTable[mHash];
  129. if(item)
  130. {
  131. mNext = item->GetNext();
  132. return(item);
  133. }
  134. }
  135. return(NULL);
  136. }
  137. // Destroy all entries in the hash table
  138. void clear(void)
  139. {
  140. T *item = head();
  141. while(item)
  142. {
  143. remove(item);
  144. item = next();
  145. }
  146. }
  147. // Override the [] operator
  148. T *operator[](const char *key) { return(find(key)); }
  149. };
  150. // end