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.

155 lines
4.0 KiB

  1. // Helper funcs for string maps
  2. #ifndef _BSTRHASH_INC
  3. #define _BSTRHASH_INC
  4. #pragma warning( disable : 4786 )
  5. #include <map>
  6. using namespace std;
  7. #include "lkrhash.h"
  8. template <class _Key, class _Val>
  9. class CLKWrap
  10. {
  11. public:
  12. #ifdef MEM_DBG
  13. char m_id[8];
  14. #endif
  15. _Key m_k;
  16. _Val m_v;
  17. mutable LONG m_cRefs;
  18. CLKWrap(_Key k, _Val v, char* id = "CLKWrap") : m_k(k), m_v(v), m_cRefs(0)
  19. {
  20. #ifdef MEM_DBG
  21. memcpy(m_id, id, 8);
  22. #endif
  23. }
  24. ~CLKWrap()
  25. {
  26. }
  27. };
  28. template <class _Val>
  29. class CRawCIBstrHash
  30. : public CTypedHashTable<CRawCIBstrHash<_Val>, const CLKWrap<BSTR,_Val>, BSTR>
  31. {
  32. public:
  33. typedef CLKWrap<BSTR,_Val> ValueType;
  34. CRawCIBstrHash(LPCSTR name) :
  35. CTypedHashTable<CRawCIBstrHash, const CLKWrap<BSTR,_Val>, BSTR>(name)
  36. {}
  37. CRawCIBstrHash(LPCSTR name, double maxload, DWORD initsize, DWORD num_subtbls) :
  38. CTypedHashTable<CRawCIBstrHash, const CLKWrap<BSTR,_Val>, BSTR>(name,maxload,initsize,num_subtbls)
  39. {}
  40. static BSTR ExtractKey(const CLKWrap<BSTR,_Val> *pEntry)
  41. { return pEntry->m_k; }
  42. static DWORD CalcKeyHash(BSTR pstrKey)
  43. { return HashStringNoCase(pstrKey); }
  44. static bool EqualKeys(BSTR x, BSTR y)
  45. {
  46. if (x == NULL)
  47. {
  48. return (y==NULL ? TRUE : FALSE);
  49. }
  50. if (!y) return FALSE;
  51. return (_wcsicmp(x,y) == 0);
  52. }
  53. static void AddRefRecord(const CLKWrap<BSTR,_Val>* pTest, int nIncr)
  54. {
  55. IRTLTRACE(_TEXT("AddRef(%p, %s) %d, cRefs == %d\n"),
  56. pTest, pTest->m_k, nIncr, pTest->m_cRefs);
  57. if (nIncr == +1)
  58. {
  59. // or, perhaps, pIFoo->AddRef() (watch out for marshalling)
  60. // or ++pTest->m_cRefs (single-threaded only)
  61. InterlockedIncrement(&pTest->m_cRefs);
  62. }
  63. else if (nIncr == -1)
  64. {
  65. // or, perhaps, pIFoo->Release() or --pTest->m_cRefs;
  66. LONG l = InterlockedDecrement(&pTest->m_cRefs);
  67. // For some hashtables, it may also make sense to add the following
  68. if (l == 0) delete pTest;
  69. // but that would typically only apply when InsertRecord was
  70. // used thus
  71. // lkrc = ht.InsertRecord(new CTest(foo, bar));
  72. }
  73. else
  74. IRTLASSERT(0);
  75. }
  76. };
  77. // For normal built in types as keys
  78. template <class _Key,class _Val>
  79. class CGenericHash
  80. : public CTypedHashTable<CGenericHash<_Key,_Val>, const CLKWrap<_Key,_Val>, _Key>
  81. {
  82. public:
  83. typedef CLKWrap<_Key,_Val> ValueType;
  84. CGenericHash(LPCSTR name) :
  85. CTypedHashTable<CGenericHash, const ValueType, _Key>(name)
  86. {}
  87. CGenericHash(LPCSTR name, double maxload, DWORD initsize, DWORD num_subtbls) :
  88. CTypedHashTable<CGenericHash, const ValueType, _Key>(name,maxload,initsize,num_subtbls)
  89. {}
  90. static _Key ExtractKey(const CLKWrap<_Key,_Val> *pEntry)
  91. { return pEntry->m_k; }
  92. static DWORD CalcKeyHash(_Key psKey)
  93. { return Hash(psKey); }
  94. static bool EqualKeys(_Key x, _Key y)
  95. { return (x==y); }
  96. static void AddRefRecord(const CLKWrap<_Key,_Val>* pTest, int nIncr)
  97. {
  98. IRTLTRACE(_TEXT("AddRef(%p, %s) %d, cRefs == %d\n"),
  99. pTest, pTest->m_k, nIncr, pTest->m_cRefs);
  100. if (nIncr == +1)
  101. {
  102. // or, perhaps, pIFoo->AddRef() (watch out for marshalling)
  103. // or ++pTest->m_cRefs (single-threaded only)
  104. InterlockedIncrement(&pTest->m_cRefs);
  105. }
  106. else if (nIncr == -1)
  107. {
  108. // or, perhaps, pIFoo->Release() or --pTest->m_cRefs;
  109. LONG l = InterlockedDecrement(&pTest->m_cRefs);
  110. // For some hashtables, it may also make sense to add the following
  111. if (l == 0) delete pTest;
  112. // but that would typically only apply when InsertRecord was
  113. // used thus
  114. // lkrc = ht.InsertRecord(new CTest(foo, bar));
  115. }
  116. else
  117. IRTLASSERT(0);
  118. }
  119. };
  120. #include <map>
  121. using namespace std;
  122. class RawBstrLT
  123. {
  124. public:
  125. bool operator()(const BSTR& x, const BSTR& y) const
  126. {
  127. return (_wcsicmp(x,y) < 0);
  128. }
  129. };
  130. #endif