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.

201 lines
5.2 KiB

  1. /*===================================================================
  2. Microsoft Denali
  3. Microsoft Confidential.
  4. Copyright 1996 Microsoft Corporation. All Rights Reserved.
  5. Component: Link list and Hash table
  6. File: Hashing.h
  7. Owner: PramodD
  8. This is the Link list and Hash table class header file.
  9. ===================================================================*/
  10. #ifndef HASHING_H
  11. #define HASHING_H
  12. // General purpose hash function
  13. typedef DWORD (*HashFunction)( const BYTE *pBytes, int cBytes );
  14. // Default hash function
  15. extern DWORD DefaultHash( const BYTE *pBytes, int cBytes );
  16. // unicode hash function, based on algorithm used by ::DefaultHash, CASE INSENSITIVE
  17. extern DWORD UnicodeUpcaseHash( const BYTE *pKey, int cbKey );
  18. // multi-byte ucase hash function, based on algorithm used by ::DefaultHash, CASE INSENSITIVE
  19. extern DWORD MultiByteUpcaseHash( const BYTE *pKey, int cbKey );
  20. // Cache pointers. The 4-byte address is the DWORD.
  21. extern DWORD PtrHash( const BYTE *pKey, int );
  22. // CLSID hashing.
  23. extern DWORD CLSIDHash( const BYTE *pKey, int );
  24. /*
  25. The CLinkElem class is intended to be used as a base class for
  26. other link lists and/or hash table implementations.
  27. The name is used for identification and search purposes.
  28. The previous and next pointers are used for traversal.
  29. The Info member is the number of elements in bucket following
  30. this element.
  31. */
  32. struct CLinkElem
  33. {
  34. BYTE * m_pKey; // Unique key - unknown datatype
  35. short m_cbKey; // length of the key
  36. short m_Info; // Link list element info
  37. CLinkElem * m_pPrev; // Previous element in link list
  38. CLinkElem * m_pNext; // Next element in link list
  39. CLinkElem();
  40. virtual ~CLinkElem() {} // Did not allocate so we do not delete
  41. HRESULT Init(void *pKey, int cKeyLen);
  42. };
  43. /*
  44. This Hash Table class is used to store and find Named elements
  45. of the type CLinkElem. Classes derived from CLinkElem can use
  46. this class.
  47. The principal requirements for the implementation are:
  48. Speed of search
  49. Forward and backward traversal through stored elements
  50. The expected use of this class is as follows.
  51. The user calls the Init method with a size argument to indicate
  52. the number of buckets.
  53. CLinkElems are added to the Hash table using AddElem()
  54. CLinkElems are searched for by name using FindElemByName()
  55. CLinkElems are searched for by index using FindElemByIndex()
  56. CLinkElems are removed by name using DeleteElem()
  57. Reference counting should be implemented by the class derived
  58. from CLinkElem.
  59. */
  60. #define PREALLOCATED_BUCKETS_MAX 25
  61. class CHashTable
  62. {
  63. protected:
  64. DWORD m_fInited : 1;
  65. DWORD m_fBucketsAllocated : 1;
  66. CLinkElem * m_pHead;
  67. CLinkElem * m_pTail;
  68. CLinkElem ** m_rgpBuckets;
  69. HashFunction m_pfnHash;
  70. UINT m_cBuckets;
  71. UINT m_Count;
  72. CLinkElem * m_rgpBucketsBuffer[PREALLOCATED_BUCKETS_MAX];
  73. protected:
  74. HRESULT AllocateBuckets();
  75. virtual BOOL FIsEqual( const void * pKey1, int cbKey1, const void * pKey2, int cbKey2 );
  76. // inline access functions
  77. public:
  78. CLinkElem * Head(void);
  79. CLinkElem * Tail(void);
  80. UINT Buckets(void);
  81. UINT Count(void);
  82. public:
  83. CHashTable(HashFunction = DefaultHash);
  84. virtual ~CHashTable(void); // We allocate and need a destructor
  85. HRESULT Init(UINT cBuckets = 11);
  86. HRESULT UnInit(void);
  87. void ReInit();
  88. CLinkElem * AddElem(CLinkElem *pElem, BOOL fTestDups = TRUE);
  89. CLinkElem * FindElem(const void *pKey, int cKeyLen);
  90. CLinkElem * DeleteElem(const void *pKey, int cKeyLen);
  91. CLinkElem * RemoveElem( CLinkElem *pLE );
  92. void AssertValid() const;
  93. };
  94. inline CLinkElem * CHashTable::Head(void) { return m_pHead; }
  95. inline CLinkElem * CHashTable::Tail(void) { return m_pTail; }
  96. inline UINT CHashTable::Buckets(void) { return m_cBuckets; }
  97. inline UINT CHashTable::Count(void) { return m_Count; }
  98. #ifndef DBG
  99. inline void CHashTable::AssertValid() const {}
  100. #endif
  101. /*
  102. * CHashTableStr
  103. *
  104. * This is exactly the same as a CHashTable, but the elements are understood to be pointers
  105. * to Unicode strings, and the string compares are done **CASE INSENSITIVE**
  106. */
  107. class CHashTableStr : public CHashTable
  108. {
  109. protected:
  110. BOOL FIsEqual( const void * pKey1, int cbKey1, const void * pKey2, int cbKey2 );
  111. public:
  112. CHashTableStr(HashFunction = UnicodeUpcaseHash);
  113. };
  114. /*
  115. * CHashTableMBStr
  116. *
  117. * This is exactly the same as a CHashTable, but the elements are understood to be pointers
  118. * to multi-byte strings, and the string compares are done **CASE INSENSITIVE**
  119. */
  120. class CHashTableMBStr : public CHashTable
  121. {
  122. protected:
  123. BOOL FIsEqual( const void * pKey1, int cbKey1, const void * pKey2, int cbKey2 );
  124. public:
  125. CHashTableMBStr(HashFunction = MultiByteUpcaseHash);
  126. };
  127. /*
  128. * CHashTablePtr
  129. *
  130. * CHashTable where but the elements are hashed by pointers
  131. * used as DWORD hash values
  132. */
  133. class CHashTablePtr : public CHashTable
  134. {
  135. protected:
  136. BOOL FIsEqual(const void *pKey1, int, const void *pKey2, int);
  137. public:
  138. CHashTablePtr(HashFunction = PtrHash);
  139. };
  140. /*
  141. * CHashTableCLSID
  142. *
  143. * CHashTable where but the elements are hashed by CLSIDs
  144. */
  145. class CHashTableCLSID : public CHashTable
  146. {
  147. protected:
  148. BOOL FIsEqual(const void *pKey1, int, const void *pKey2, int);
  149. public:
  150. CHashTableCLSID(HashFunction = CLSIDHash);
  151. };
  152. #endif // HASHING_H