Source code of Windows XP (NT5)
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.

200 lines
4.5 KiB

  1. //
  2. // FHash.h
  3. //
  4. // This file contains a template class for a hash table.
  5. // The template has two arguments, the type of the Data Elements and the
  6. // type of the Key.
  7. //
  8. // The Data type must support the following :
  9. //
  10. // class Data {
  11. // Data() ;
  12. // Data( Data & ) ;
  13. // ~Data() ;
  14. // Key& GetKey() ;
  15. // int MatchKey() ; /* NOTE : MatchKey returns non-zero on equality
  16. // } ;
  17. //
  18. // The Key class has no requirements.
  19. //
  20. //
  21. #ifndef _FHASH_H_
  22. #define _FHASH_H_
  23. //#include "..\assert\assert.h"
  24. #ifndef Assert
  25. #define Assert _ASSERT
  26. #endif
  27. //------------------------------------------------------------
  28. template< class Data, class Key >
  29. class TFHash {
  30. //
  31. // This class defines a Hash table which can grow dynamically to
  32. // accomodate insertions into the table. The table only grows, and
  33. // does not shrink.
  34. //
  35. private :
  36. struct CFreeElement {
  37. struct CFreeElement* m_pNext ;
  38. } ;
  39. //
  40. // The CBucket structure defines the elements within the hash table.
  41. //
  42. struct CBucket {
  43. Data m_data ;
  44. CBucket* m_pNext ;
  45. CBucket( Data& d ) : m_data( d ), m_pNext( 0 ) {
  46. }
  47. CBucket( ) : m_pNext( 0 ) {
  48. }
  49. void* operator new( size_t size, void* pv ) {
  50. if( pv != 0 ) {
  51. return pv ;
  52. }
  53. //
  54. // Get memory which is DWORDLONG aligned !
  55. //
  56. return (void*) ::new DWORDLONG[ (size + sizeof( DWORDLONG ) - 1) / sizeof( DWORDLONG ) ] ;
  57. }
  58. void operator delete( void * pv ) {}
  59. #if _MSC_VER >= 1200
  60. void operator delete( void * p, void *pv ) {}
  61. #endif
  62. private :
  63. CBucket( CBucket& ) {}
  64. } ;
  65. //
  66. // Linked list of free memory we've cached to avoid always going
  67. // through C runtimes for allocations !
  68. //
  69. CFreeElement* m_pFreeStack ;
  70. //
  71. // Number of Free Blocks we've cached on the stack
  72. //
  73. int m_cFreeStack ;
  74. //
  75. // Maximum number of Free Blocks we should cache !
  76. //
  77. int m_cMaxFreeStack ;
  78. int m_cBuckets ; // Number of Buckets used in index computation
  79. int m_cActiveBuckets ; // Number of Buckets we are actually using
  80. // Assert( m_cBuckets >= m_cActiveBuckets ) always true.
  81. int m_cNumAlloced ; // Number of Buckets we have allocated
  82. // Assert( m_cNumAlloced >= m_cActiveBuckets ) must
  83. // always be true.
  84. int m_cIncrement ; // The amount we should grow the hash table when we
  85. // decide to grow it.
  86. int m_load ; // The number of CBuckets we should allow in each
  87. // collision chain (on average).
  88. long m_cInserts ; // A counter that we use to determine when to grow the
  89. // hash table.
  90. DWORD (* m_pfnHash)( const Key& k ) ; // The function we use to compute hash values.
  91. // (Provided by the Caller of Init())
  92. CBucket** m_ppBucket ; // An array of pointer to buckets.
  93. DWORD ComputeIndex( DWORD dw ) ; // The function we use to compute the
  94. // position of an element in the hash table given its
  95. // Hash Value.
  96. public :
  97. TFHash( ) ;
  98. ~TFHash( ) ;
  99. BOOL Init( int cInitial,
  100. int cIncrement,
  101. DWORD (* pfnHash)( const Key& ),
  102. int load = 2,
  103. int cMaxFreeStack = 128
  104. ) ;
  105. //
  106. // Check that the hash table is in a valid state
  107. // if fCheckHash == TRUE we will walk all the buckets and check that
  108. // the data hashes to the correct value !
  109. //
  110. BOOL IsValid( BOOL fCheckHash = FALSE ) ;
  111. //
  112. // Insert a piece of Data into the Hash Table
  113. //
  114. Data* InsertDataHash( DWORD dw,
  115. Data& d
  116. ) ;
  117. //
  118. // Insert a piece of Data into the Hash Table
  119. //
  120. Data* InsertData( Data& d ) ;
  121. //
  122. // Search for a given Key in the Hash Table - return a pointer
  123. // to the Data within our Bucket object
  124. //
  125. Data* SearchKeyHash( DWORD dw,
  126. Key& k
  127. ) ;
  128. //
  129. // Search for a given Key in the Hash Table - return a pointer
  130. // to the Data within our Bucket object
  131. //
  132. Data* SearchKey( Key& k ) ;
  133. //
  134. // Search for a given Key in the Hash Table and delete the
  135. // data if present. if pd != 0 then we will check that the key
  136. // we find is actually within the CBucket object which pd lies within.
  137. //
  138. BOOL DeleteData( Key& k,
  139. Data* pd = 0
  140. ) ;
  141. //
  142. // Insert the given block of data into the hash table.
  143. // We will make a copy of the Data Object and store it in one
  144. // of our bucket objects.
  145. //
  146. BOOL Insert( Data& d ) ;
  147. //
  148. // Find the given key in the table and copy the Data object into
  149. // the out parameter 'd'
  150. //
  151. BOOL Search( Key& k,
  152. Data &d
  153. ) ;
  154. //
  155. // Delete the key and associated data from the table.
  156. //
  157. BOOL Delete( Key k ) ;
  158. //
  159. // Discards any memory we have allocated - after this, you must
  160. // call Init() again!
  161. //
  162. void Clear( ) ;
  163. } ;
  164. #include "fhash.inl"
  165. #endif // _FHASH_H_