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.

170 lines
5.2 KiB

  1. //--------------------------------------------------------------------
  2. // An example of how to create a wrapper for CLKRHashTable
  3. //--------------------------------------------------------------------
  4. #include <lkrhash.h>
  5. #ifndef __LKRHASH_NO_NAMESPACE__
  6. #define LKRHASH_NS LKRhash
  7. // using namespace LKRhash;
  8. #else // __LKRHASH_NO_NAMESPACE__
  9. #define LKRHASH_NS
  10. #endif // __LKRHASH_NO_NAMESPACE__
  11. #ifndef __HASHFN_NO_NAMESPACE__
  12. #define HASHFN_NS HashFn
  13. // using namespace HashFn;
  14. #else // __HASHFN_NO_NAMESPACE__
  15. #define HASHFN_NS
  16. #endif // __HASHFN_NO_NAMESPACE__
  17. // some random class
  18. class CTest
  19. {
  20. public:
  21. enum {BUFFSIZE=20};
  22. int m_n; // This will also be a key
  23. __int64 m_n64; // This will be a third key
  24. char m_sz[BUFFSIZE]; // This will be the primary key
  25. bool m_fWhatever;
  26. mutable LONG m_cRefs; // Reference count for lifetime management.
  27. // Must be mutable to use 'const CTest*' in
  28. // hashtables
  29. CTest(int n, const char* psz, bool f)
  30. : m_n(n), m_n64(((__int64) n << 32) | n), m_fWhatever(f), m_cRefs(0)
  31. {
  32. strncpy(m_sz, psz, BUFFSIZE-1);
  33. m_sz[BUFFSIZE-1] = '\0';
  34. }
  35. ~CTest()
  36. {
  37. IRTLASSERT(m_cRefs == 0);
  38. }
  39. };
  40. // A typed hash table of CTests, keyed on the string field. Case-insensitive.
  41. class CStringTestHashTable
  42. : public LKRHASH_NS::CTypedHashTable<CStringTestHashTable,
  43. const CTest, const char*>
  44. {
  45. public:
  46. CStringTestHashTable()
  47. : LKRHASH_NS::CTypedHashTable<CStringTestHashTable, const CTest,
  48. const char*>("string",
  49. LK_DFLT_MAXLOAD,
  50. LK_SMALL_TABLESIZE,
  51. LK_DFLT_NUM_SUBTBLS)
  52. {}
  53. static const char*
  54. ExtractKey(const CTest* pTest)
  55. {
  56. return pTest->m_sz;
  57. }
  58. static DWORD
  59. CalcKeyHash(const char* pszKey)
  60. {
  61. return HASHFN_NS::HashStringNoCase(pszKey);
  62. }
  63. static int
  64. CompareKeys(const char* pszKey1, const char* pszKey2)
  65. {
  66. return _stricmp(pszKey1, pszKey2);
  67. }
  68. static LONG
  69. AddRefRecord(const CTest* pTest, LK_ADDREF_REASON lkar)
  70. {
  71. LONG l;
  72. if (lkar > 0)
  73. {
  74. // or, perhaps, pIFoo->AddRef() (watch out for marshalling)
  75. // or ++pTest->m_cRefs (single-threaded only)
  76. l = InterlockedIncrement(&pTest->m_cRefs);
  77. }
  78. else if (lkar < 0)
  79. {
  80. // or, perhaps, pIFoo->Release() or --pTest->m_cRefs;
  81. l = InterlockedDecrement(&pTest->m_cRefs);
  82. // For some hashtables, it may also make sense to add the following
  83. // if (l == 0) delete pTest;
  84. // but that would typically only apply when InsertRecord was
  85. // used thus
  86. // lkrc = ht.InsertRecord(new CTest(foo, bar));
  87. }
  88. else
  89. IRTLASSERT(0);
  90. IRTLTRACE("AddRef(%p, %s) %d, cRefs == %d\n",
  91. pTest, pTest->m_sz, lkar, l);
  92. return l;
  93. }
  94. };
  95. // Another typed hash table of CTests. This one is keyed on the numeric field.
  96. class CNumberTestHashTable
  97. : public LKRHASH_NS::CTypedHashTable<CNumberTestHashTable,
  98. const CTest, int>
  99. {
  100. public:
  101. CNumberTestHashTable()
  102. : LKRHASH_NS::CTypedHashTable<CNumberTestHashTable, const CTest, int>(
  103. "number") {}
  104. static int ExtractKey(const CTest* pTest) {return pTest->m_n;}
  105. static DWORD CalcKeyHash(int nKey) {return HASHFN_NS::Hash(nKey);}
  106. static int CompareKeys(int nKey1, int nKey2) {return nKey1 - nKey2;}
  107. static LONG AddRefRecord(const CTest* pTest, LK_ADDREF_REASON lkar)
  108. {
  109. int nIncr = (lkar > 0) ? +1 : -1;
  110. LONG l = InterlockedExchangeAdd(&pTest->m_cRefs, nIncr);
  111. IRTLTRACE("AddRef(%p, %d) %d (%d), cRefs == %d\n",
  112. pTest, pTest->m_n, nIncr, (int) lkar, l);
  113. return l;
  114. }
  115. };
  116. // Third typed hash table of CTests. This one is keyed on the __int64 field.
  117. #undef NUM64
  118. #ifdef NUM64
  119. class CNum64TestHashTable
  120. : public LKRHASH_NS::CTypedHashTable<CNum64TestHashTable,
  121. const CTest, __int64>
  122. {
  123. public:
  124. CNum64TestHashTable()
  125. : LKRHASH_NS::CTypedHashTable<CNum64TestHashTable, const CTest, __int64>(
  126. "num64") {}
  127. static __int64 ExtractKey(const CTest* pTest) {return pTest->m_n64;}
  128. static DWORD CalcKeyHash(__int64 nKey) {return HASHFN_NS::Hash(nKey);}
  129. static int CompareKeys(__int64 nKey1, __int64 nKey2) {return nKey1 - nKey2;}
  130. static LONG AddRefRecord(const CTest* pTest, LK_ADDREF_REASON lkar)
  131. {
  132. int nIncr = (lkar > 0) ? +1 : -1;
  133. LONG l = InterlockedExchangeAdd(&pTest->m_cRefs, nIncr);
  134. IRTLTRACE("AddRef(%p, %d) %d (%d), cRefs == %d\n",
  135. pTest, pTest->m_n, nIncr, (int) lkar, l);
  136. return l;
  137. }
  138. };
  139. #endif // NUM64