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.

252 lines
4.9 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. CVssHashMap
  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. if(nIndex != (m_nSize - 1))
  91. {
  92. m_aKey[nIndex].~TKey();
  93. #if _MSC_VER >= 1200
  94. m_aVal[nIndex].~TVal();
  95. #else
  96. TVal * t1;
  97. t1 = &m_aVal[nIndex];
  98. t1->~TVal();
  99. #endif
  100. memmove((void*)(m_aKey + nIndex), (void*)(m_aKey + nIndex + 1), (m_nSize - (nIndex + 1)) * sizeof(TKey));
  101. memmove((void*)(m_aVal + nIndex), (void*)(m_aVal + nIndex + 1), (m_nSize - (nIndex + 1)) * sizeof(TVal));
  102. }
  103. TKey* pKey;
  104. pKey = (TKey*)realloc(m_aKey, (m_nSize - 1) * sizeof(TKey));
  105. if(pKey != NULL || m_nSize == 1)
  106. m_aKey = pKey;
  107. TVal* pVal;
  108. pVal = (TVal*)realloc(m_aVal, (m_nSize - 1) * sizeof(TVal));
  109. if(pVal != NULL || m_nSize == 1)
  110. m_aVal = pVal;
  111. m_nSize--;
  112. return TRUE;
  113. }
  114. void RemoveAll()
  115. {
  116. if(m_aKey != NULL)
  117. {
  118. for(int i = 0; i < m_nSize; i++)
  119. {
  120. m_aKey[i].~TKey();
  121. #if _MSC_VER >= 1200
  122. m_aVal[i].~TVal();
  123. #else
  124. TVal * t1;
  125. t1 = &m_aVal[i];
  126. t1->~TVal();
  127. #endif
  128. }
  129. free(m_aKey);
  130. m_aKey = NULL;
  131. }
  132. if(m_aVal != NULL)
  133. {
  134. free(m_aVal);
  135. m_aVal = NULL;
  136. }
  137. m_nSize = 0;
  138. }
  139. BOOL SetAt(TKey key, TVal val)
  140. {
  141. int nIndex = FindKey(key);
  142. if(nIndex == -1)
  143. return FALSE;
  144. SetAtIndex(nIndex, key, val);
  145. return TRUE;
  146. }
  147. TVal Lookup(TKey key) const
  148. {
  149. int nIndex = FindKey(key);
  150. if(nIndex == -1)
  151. return NULL; // must be able to convert
  152. return GetValueAt(nIndex);
  153. }
  154. TKey ReverseLookup(TVal val) const
  155. {
  156. int nIndex = FindVal(val);
  157. if(nIndex == -1)
  158. return NULL; // must be able to convert
  159. return GetKeyAt(nIndex);
  160. }
  161. TKey& GetKeyAt(int nIndex) const
  162. {
  163. ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  164. return m_aKey[nIndex];
  165. }
  166. TVal& GetValueAt(int nIndex) const
  167. {
  168. ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  169. return m_aVal[nIndex];
  170. }
  171. // Implementation
  172. template <typename T>
  173. class Wrapper
  174. {
  175. public:
  176. Wrapper(T& _t) : t(_t)
  177. {
  178. }
  179. template <typename _Ty>
  180. void *operator new(size_t, _Ty* p)
  181. {
  182. return p;
  183. }
  184. T t;
  185. };
  186. void SetAtIndex(int nIndex, TKey& key, TVal& val)
  187. {
  188. ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  189. new(m_aKey + nIndex) Wrapper<TKey>(key);
  190. new(m_aVal + nIndex) Wrapper<TVal>(val);
  191. }
  192. int FindKey(TKey& key) const
  193. {
  194. for(int i = 0; i < m_nSize; i++)
  195. {
  196. // [aoltean] Comparing strings also
  197. if(::VssHashAreKeysEqual(m_aKey[i], key))
  198. return i;
  199. }
  200. return -1; // not found
  201. }
  202. int FindVal(TVal& val) const
  203. {
  204. for(int i = 0; i < m_nSize; i++)
  205. {
  206. // [aoltean] Comparing strings also
  207. if(::VssHashAreKeysEqual(m_aVal[i], val))
  208. return i;
  209. }
  210. return -1; // not found
  211. }
  212. };
  213. #endif