Leaked source code of windows server 2003
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.

239 lines
4.7 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. vs_hash.hxx
  5. Abstract:
  6. Template for a hash table class.
  7. Author:
  8. Adi Oltean
  9. Revision History:
  10. 06/03/2000 aoltean Porting it from ATL code in order to add string comparison
  11. --*/
  12. #ifndef _H_VSS_HASH_
  13. #define _H_VSS_HASH_
  14. ////////////////////////////////////////////////////////////////////////
  15. // Standard foo for file name aliasing. This code block must be after
  16. // all includes of VSS header files.
  17. //
  18. #ifdef VSS_FILE_ALIAS
  19. #undef VSS_FILE_ALIAS
  20. #endif
  21. #define VSS_FILE_ALIAS "INCHASHH"
  22. //
  23. ////////////////////////////////////////////////////////////////////////
  24. ////////////////////////////////////////////////////////////////////////////////////////
  25. // Utilities
  26. //
  27. inline BOOL VssHashAreKeysEqual( const LPCWSTR& lhK, const LPCWSTR& rhK )
  28. {
  29. return (::wcscmp(lhK, rhK) == 0);
  30. }
  31. inline BOOL VssHashAreKeysEqual( const LPWSTR& lhK, const LPWSTR& rhK )
  32. {
  33. return (::wcscmp(lhK, rhK) == 0);
  34. }
  35. template < class KeyType >
  36. inline BOOL VssHashAreKeysEqual( const KeyType& lhK, const KeyType& rhK )
  37. {
  38. return lhK == rhK;
  39. }
  40. ////////////////////////////////////////////////////////////////////////////////////////
  41. // Definitions
  42. //
  43. /*++
  44. Class:
  45. CVssSimpleMap
  46. Description:
  47. Intended for small number of simple types or pointers.
  48. Adapted from the ATL class to work with strings also.
  49. --*/
  50. template <class TKey, class TVal>
  51. class CVssSimpleMap
  52. {
  53. public:
  54. TKey* m_aKey;
  55. TVal* m_aVal;
  56. int m_nSize;
  57. // Construction/destruction
  58. CVssSimpleMap() : m_aKey(NULL), m_aVal(NULL), m_nSize(0)
  59. { }
  60. ~CVssSimpleMap()
  61. {
  62. RemoveAll();
  63. }
  64. // Operations
  65. int GetSize() const
  66. {
  67. return m_nSize;
  68. }
  69. BOOL Add(TKey key, TVal val)
  70. {
  71. TKey* pKey;
  72. pKey = (TKey*)realloc(m_aKey, (m_nSize + 1) * sizeof(TKey));
  73. if(pKey == NULL)
  74. return FALSE;
  75. m_aKey = pKey;
  76. TVal* pVal;
  77. pVal = (TVal*)realloc(m_aVal, (m_nSize + 1) * sizeof(TVal));
  78. if(pVal == NULL)
  79. return FALSE;
  80. m_aVal = pVal;
  81. m_nSize++;
  82. SetAtIndex(m_nSize - 1, key, val);
  83. return TRUE;
  84. }
  85. BOOL Remove(TKey key)
  86. {
  87. int nIndex = FindKey(key);
  88. if(nIndex == -1)
  89. return FALSE;
  90. // Call destructors in all cases (Bug 470439)
  91. m_aKey[nIndex].~TKey();
  92. m_aVal[nIndex].~TVal();
  93. if(nIndex != (m_nSize - 1))
  94. {
  95. memmove((void*)(m_aKey + nIndex), (void*)(m_aKey + nIndex + 1), (m_nSize - (nIndex + 1)) * sizeof(TKey));
  96. memmove((void*)(m_aVal + nIndex), (void*)(m_aVal + nIndex + 1), (m_nSize - (nIndex + 1)) * sizeof(TVal));
  97. }
  98. TKey* pKey;
  99. pKey = (TKey*)realloc(m_aKey, (m_nSize - 1) * sizeof(TKey));
  100. if(pKey != NULL || m_nSize == 1)
  101. m_aKey = pKey;
  102. TVal* pVal;
  103. pVal = (TVal*)realloc(m_aVal, (m_nSize - 1) * sizeof(TVal));
  104. if(pVal != NULL || m_nSize == 1)
  105. m_aVal = pVal;
  106. m_nSize--;
  107. return TRUE;
  108. }
  109. void RemoveAll()
  110. {
  111. if(m_aKey != NULL)
  112. {
  113. for(int i = 0; i < m_nSize; i++)
  114. {
  115. m_aKey[i].~TKey();
  116. m_aVal[i].~TVal();
  117. }
  118. free(m_aKey);
  119. m_aKey = NULL;
  120. }
  121. if(m_aVal != NULL)
  122. {
  123. free(m_aVal);
  124. m_aVal = NULL;
  125. }
  126. m_nSize = 0;
  127. }
  128. BOOL SetAt(TKey key, TVal val)
  129. {
  130. int nIndex = FindKey(key);
  131. if(nIndex == -1)
  132. return FALSE;
  133. SetAtIndex(nIndex, key, val);
  134. return TRUE;
  135. }
  136. TVal Lookup(TKey key) const
  137. {
  138. int nIndex = FindKey(key);
  139. if(nIndex == -1)
  140. return NULL; // must be able to convert
  141. return GetValueAt(nIndex);
  142. }
  143. TKey ReverseLookup(TVal val) const
  144. {
  145. int nIndex = FindVal(val);
  146. if(nIndex == -1)
  147. return NULL; // must be able to convert
  148. return GetKeyAt(nIndex);
  149. }
  150. TKey& GetKeyAt(int nIndex) const
  151. {
  152. ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  153. return m_aKey[nIndex];
  154. }
  155. TVal& GetValueAt(int nIndex) const
  156. {
  157. ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  158. return m_aVal[nIndex];
  159. }
  160. // Implementation
  161. template <typename T>
  162. class Wrapper
  163. {
  164. public:
  165. Wrapper(T& _t) : t(_t)
  166. {
  167. }
  168. template <typename _Ty>
  169. void *operator new(size_t, _Ty* p)
  170. {
  171. return p;
  172. }
  173. T t;
  174. };
  175. void SetAtIndex(int nIndex, TKey& key, TVal& val)
  176. {
  177. ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  178. new(m_aKey + nIndex) Wrapper<TKey>(key);
  179. new(m_aVal + nIndex) Wrapper<TVal>(val);
  180. }
  181. int FindKey(TKey& key) const
  182. {
  183. for(int i = 0; i < m_nSize; i++)
  184. {
  185. // [aoltean] Comparing strings also
  186. if(::VssHashAreKeysEqual(m_aKey[i], key))
  187. return i;
  188. }
  189. return -1; // not found
  190. }
  191. int FindVal(TVal& val) const
  192. {
  193. for(int i = 0; i < m_nSize; i++)
  194. {
  195. // [aoltean] Comparing strings also
  196. if(::VssHashAreKeysEqual(m_aVal[i], val))
  197. return i;
  198. }
  199. return -1; // not found
  200. }
  201. };
  202. #endif