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.

356 lines
8.9 KiB

  1. /*++
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. hash.h
  5. Abstract:
  6. Declaration of the CHashTable class
  7. Author:
  8. mquinton 04-28-98
  9. Notes:
  10. Revision History:
  11. --*/
  12. #ifndef __HASH_H__
  13. #define __HASH_H__
  14. typedef struct _TABLEENTRY
  15. {
  16. ULONG_PTR HashKey;
  17. ULONG_PTR Element;
  18. CTAPI * pTapiObj;
  19. } TABLEENTRY;
  20. typedef struct _TABLEHEADER
  21. {
  22. DWORD dwUsedElements;
  23. TABLEENTRY * pEntries;
  24. } TABLEHEADER;
  25. class CHashTable
  26. {
  27. private:
  28. CRITICAL_SECTION m_cs;
  29. DWORD m_dwTables;
  30. DWORD m_dwEntriesPerTable;
  31. TABLEHEADER * m_pTables;
  32. public:
  33. CHashTable()
  34. {
  35. InitializeCriticalSection( &m_cs );
  36. }
  37. ~CHashTable()
  38. {
  39. DeleteCriticalSection( &m_cs );
  40. }
  41. DECLARE_TRACELOG_CLASS(CHashTable)
  42. void Lock()
  43. {
  44. //LOG((TL_INFO,"Hash Table locking......"));
  45. EnterCriticalSection( &m_cs );
  46. //LOG((TL_INFO,"Hash Table locked"));
  47. }
  48. void Unlock()
  49. {
  50. //LOG((TL_INFO,"Hash Table Unlocking......"));
  51. LeaveCriticalSection( &m_cs );
  52. //LOG((TL_INFO,"Hash Table Unlocked"));
  53. }
  54. HRESULT Initialize( DWORD dwEntries )
  55. {
  56. DWORD dwCount;
  57. BYTE * pStart;
  58. m_dwTables = 31;
  59. m_dwEntriesPerTable = dwEntries;
  60. m_pTables = (TABLEHEADER *)ClientAlloc( sizeof(TABLEHEADER) * m_dwTables );
  61. if ( NULL == m_pTables )
  62. {
  63. return E_OUTOFMEMORY;
  64. }
  65. pStart = (BYTE *)ClientAlloc( sizeof(TABLEENTRY) * m_dwTables * m_dwEntriesPerTable );
  66. if ( NULL == pStart )
  67. {
  68. ClientFree( m_pTables );
  69. return E_OUTOFMEMORY;
  70. }
  71. for ( dwCount = 0; dwCount < m_dwTables; dwCount++ )
  72. {
  73. m_pTables[dwCount].pEntries = (TABLEENTRY *)&( pStart[dwCount *
  74. m_dwEntriesPerTable * sizeof (TABLEENTRY)] );
  75. m_pTables[dwCount].dwUsedElements = 0;
  76. }
  77. return S_OK;
  78. }
  79. HRESULT Insert( ULONG_PTR HashKey, ULONG_PTR Element , CTAPI *pTapiObj = 0)
  80. {
  81. DWORD dwHashIndex;
  82. DWORD dwCount = 0;
  83. TABLEHEADER * pTableHeader;
  84. if ( HashKey == 0 )
  85. return S_OK;
  86. dwHashIndex = Hash( HashKey );
  87. pTableHeader = &(m_pTables[dwHashIndex]);
  88. if (pTableHeader->dwUsedElements == m_dwEntriesPerTable)
  89. {
  90. HRESULT hr;
  91. hr = Resize();
  92. if ( !SUCCEEDED(hr) )
  93. {
  94. return hr;
  95. }
  96. }
  97. while ( 0 != pTableHeader->pEntries[dwCount].HashKey )
  98. {
  99. dwCount ++;
  100. }
  101. if (dwCount >= m_dwEntriesPerTable)
  102. {
  103. LOG((TL_ERROR,"Hash Table insert: dwCount >= m_dwEntriesPerTable"));
  104. }
  105. pTableHeader->pEntries[dwCount].HashKey = HashKey;
  106. pTableHeader->pEntries[dwCount].Element = Element;
  107. pTableHeader->pEntries[dwCount].pTapiObj = pTapiObj;
  108. pTableHeader->dwUsedElements++;
  109. LOG((TL_INFO,"Hash Table insert: key %p - obj %p - tapi %p", HashKey, Element, pTapiObj));
  110. #ifdef DBG
  111. CheckForDups( pTableHeader );
  112. #endif
  113. return S_OK;
  114. }
  115. #ifdef DBG
  116. HRESULT CheckForDups( TABLEHEADER * pTableHeader )
  117. {
  118. DWORD dwCount;
  119. DWORD dwInner;
  120. for ( dwCount = 0; dwCount < m_dwEntriesPerTable; dwCount++ )
  121. {
  122. if (pTableHeader->pEntries[dwCount].HashKey == 0)
  123. continue;
  124. for ( dwInner = dwCount+1; dwInner < m_dwEntriesPerTable; dwInner++ )
  125. {
  126. if ( pTableHeader->pEntries[dwCount].HashKey ==
  127. pTableHeader->pEntries[dwInner].HashKey )
  128. {
  129. LOG((TL_ERROR, "HashTable - dup entry"));
  130. LOG((TL_ERROR, " dwCount = %lx, dwInner = %lx", dwCount,dwInner));
  131. LOG((TL_ERROR, " dwHash = %p", pTableHeader->pEntries[dwCount].HashKey));
  132. LOG(( TL_ERROR, "HashTable - dup entry"));
  133. LOG(( TL_ERROR, " dwCount = %lx, dwInner = %lx", dwCount,dwInner));
  134. LOG(( TL_ERROR, " HashKey = %p", pTableHeader->pEntries[dwCount].HashKey));
  135. DebugBreak();
  136. }
  137. }
  138. }
  139. return 0;
  140. }
  141. #endif // DBG
  142. HRESULT Remove( ULONG_PTR HashKey )
  143. {
  144. DWORD dwHashIndex;
  145. DWORD dwCount;
  146. TABLEHEADER * pTableHeader;
  147. LOG((TL_INFO,"Hash Table Remove: key %p ", HashKey));
  148. if ( HashKey == 0 )
  149. return S_OK;
  150. dwHashIndex = Hash( HashKey );
  151. pTableHeader = &(m_pTables[dwHashIndex]);
  152. for ( dwCount = 0; dwCount < m_dwEntriesPerTable; dwCount++ )
  153. {
  154. if ( HashKey == pTableHeader->pEntries[dwCount].HashKey )
  155. {
  156. LOG((TL_INFO,"Hash Table Remove: key %p - obj %p",HashKey,pTableHeader->pEntries[dwCount].Element));
  157. LOG(( TL_TRACE, "Hash Table Remove: key %p - obj %p",HashKey,pTableHeader->pEntries[dwCount].Element));
  158. break;
  159. }
  160. }
  161. if ( dwCount == m_dwEntriesPerTable )
  162. {
  163. return E_FAIL;
  164. }
  165. pTableHeader->pEntries[dwCount].HashKey = 0;
  166. pTableHeader->pEntries[dwCount].pTapiObj = 0;
  167. pTableHeader->dwUsedElements--;
  168. return S_OK;
  169. }
  170. HRESULT Find( ULONG_PTR HashKey, ULONG_PTR * pElement )
  171. {
  172. DWORD dwHashIndex;
  173. TABLEHEADER * pTableHeader;
  174. DWORD dwCount;
  175. if ( HashKey == 0 )
  176. {
  177. LOG((TL_INFO,"Find - Hash Table returning E_FAIL on Find(NULL)"));
  178. return E_FAIL;
  179. // return S_OK;
  180. }
  181. dwHashIndex = Hash( HashKey );
  182. pTableHeader = &(m_pTables[dwHashIndex]);
  183. for (dwCount = 0; dwCount < m_dwEntriesPerTable; dwCount++ )
  184. {
  185. if ( HashKey == pTableHeader->pEntries[dwCount].HashKey )
  186. {
  187. break;
  188. }
  189. }
  190. if ( dwCount == m_dwEntriesPerTable )
  191. {
  192. return E_FAIL;
  193. }
  194. *pElement = pTableHeader->pEntries[dwCount].Element;
  195. LOG((TL_INFO,"Find - Hash Table found: key %p - obj %p",HashKey,*pElement));
  196. return S_OK;
  197. }
  198. DWORD Hash( ULONG_PTR HashKey )
  199. {
  200. return (DWORD)((HashKey >> 4) % m_dwTables);
  201. }
  202. HRESULT Resize()
  203. {
  204. BYTE * pNewTable;
  205. BYTE * pOldTable;
  206. DWORD dwCount;
  207. DWORD dwNumEntries;
  208. dwNumEntries = 2 * m_dwEntriesPerTable;
  209. pNewTable = (BYTE *)ClientAlloc( sizeof(TABLEENTRY) * m_dwTables * dwNumEntries );
  210. if ( NULL == pNewTable )
  211. {
  212. return E_OUTOFMEMORY;
  213. }
  214. pOldTable = (BYTE *)(m_pTables[0].pEntries);
  215. for ( dwCount = 0; dwCount < m_dwTables; dwCount ++ )
  216. {
  217. CopyMemory(
  218. pNewTable,
  219. m_pTables[dwCount].pEntries,
  220. sizeof(TABLEENTRY) * m_dwEntriesPerTable
  221. );
  222. m_pTables[dwCount].pEntries = (TABLEENTRY*)pNewTable;
  223. pNewTable += sizeof(TABLEENTRY) * dwNumEntries;
  224. }
  225. ClientFree( pOldTable );
  226. m_dwEntriesPerTable = dwNumEntries;
  227. return S_OK;
  228. }
  229. void Shutdown()
  230. {
  231. ClientFree( m_pTables[0].pEntries );
  232. ClientFree( m_pTables );
  233. }
  234. HRESULT Flush( CTAPI * pTapiObj )
  235. {
  236. DWORD dwOuterCount;
  237. DWORD dwInnerCount;
  238. TABLEHEADER * pTableHeader;
  239. Lock();
  240. for ( dwOuterCount = 0; dwOuterCount < m_dwTables; dwOuterCount++ )
  241. {
  242. pTableHeader = &(m_pTables[dwOuterCount]);
  243. for ( dwInnerCount = 0; dwInnerCount < m_dwEntriesPerTable; dwInnerCount++ )
  244. {
  245. if ( pTapiObj == pTableHeader->pEntries[dwInnerCount].pTapiObj )
  246. {
  247. LOG((TL_INFO,"Hash Table Flush: key %p - obj %p - tapi %p",pTableHeader->pEntries[dwInnerCount].HashKey,pTableHeader->pEntries[dwInnerCount].Element, pTapiObj));
  248. LOG(( TL_ERROR, "Hash Table Flush: key %p - obj %p - tapi %p",pTableHeader->pEntries[dwInnerCount].HashKey,pTableHeader->pEntries[dwInnerCount].Element, pTapiObj));
  249. pTableHeader->pEntries[dwInnerCount].HashKey = 0;
  250. pTableHeader->pEntries[dwInnerCount].pTapiObj = 0;
  251. pTableHeader->dwUsedElements--;
  252. }
  253. } // end for dwInnerCount
  254. } // end for dwOuterCount
  255. Unlock();
  256. return S_OK;
  257. }
  258. };
  259. #endif