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.

261 lines
7.7 KiB

  1. /* Test driver for class HashTable */
  2. /* Author: Paul Larson, [email protected] */
  3. /* Much hacked upon by George V. Reilly, [email protected] */
  4. #include <windows.h>
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include "str-num.h"
  9. #ifdef LKR_APPLY_IF
  10. // A class to exercise ApplyIf()
  11. class CApplyIfTest
  12. {
  13. public:
  14. static LK_PREDICATE WINAPI
  15. Predicate(const CTest* pTest, void* pvState)
  16. {
  17. CApplyIfTest* pThis = static_cast<CApplyIfTest*>(pvState);
  18. ++pThis->m_cPreds;
  19. IRTLTRACE("CApplyIfTest::Predicate(%p (%s, %d), %p)\n",
  20. pTest, pTest->m_sz, pTest->m_n, pThis);
  21. return ((pTest->m_n % 10 == 7)
  22. ? LKP_PERFORM
  23. : LKP_NO_ACTION);
  24. }
  25. static LK_ACTION WINAPI
  26. Action(const CTest* pTest, void* pvState)
  27. {
  28. CApplyIfTest* pThis = static_cast<CApplyIfTest*>(pvState);
  29. ++pThis->m_cActions;
  30. LK_ACTION lka = ((pTest->m_n > 30)
  31. ? LKA_SUCCEEDED
  32. : LKA_FAILED);
  33. IRTLTRACE("CApplyIfTest::Action(%p (%s, %d), %p) %s\n",
  34. pTest, pTest->m_sz, pTest->m_n, pThis,
  35. lka == LKA_SUCCEEDED ? "succeeded" : "failed");
  36. if (lka == LKA_SUCCEEDED)
  37. ++pThis->m_cSuccesses;
  38. else if (lka == LKA_FAILED)
  39. ++pThis->m_cFailures;
  40. return lka;
  41. }
  42. int m_cPreds;
  43. int m_cActions;
  44. int m_cSuccesses;
  45. int m_cFailures;
  46. CApplyIfTest()
  47. : m_cPreds(0), m_cActions(0), m_cSuccesses(0), m_cFailures(0)
  48. {}
  49. };
  50. // The Predicate and Action functions can be static member functions,
  51. // but don't have to be
  52. LK_PREDICATE WINAPI
  53. DeleteIfGt10(
  54. const CTest* pTest,
  55. void* pvState)
  56. {
  57. IRTLTRACE("DeleteIfGt10(%p, %s, %p) = %d\n",
  58. pTest, pTest->m_sz, pvState, pTest->m_n);
  59. return ((pTest->m_n > 10)
  60. ? LKP_PERFORM
  61. : LKP_NO_ACTION);
  62. }
  63. #endif // LKR_APPLY_IF
  64. void Test(
  65. bool fVerbose)
  66. {
  67. // Some objects for the hash tables
  68. CTest tl(5, "Larson", true);
  69. CTest tk(17, "Krishnan", false);
  70. CTest tr(37, "Reilly", true);
  71. // A string-keyed hash table
  72. CStringTestHashTable stht;
  73. IRTLVERIFY(LK_SUCCESS == stht.InsertRecord(&tl));
  74. IRTLVERIFY(LK_SUCCESS == stht.InsertRecord(&tk));
  75. IRTLVERIFY(LK_SUCCESS == stht.InsertRecord(&tr));
  76. IRTLTRACE("Check the overwrite feature of InsertRecord\n");
  77. IRTLVERIFY(LK_KEY_EXISTS == stht.InsertRecord(&tr, false));
  78. IRTLASSERT(tr.m_cRefs == 1);
  79. IRTLVERIFY(LK_SUCCESS == stht.InsertRecord(&tr, true));
  80. IRTLASSERT(tr.m_cRefs == 1); // 1+1-1 == 1
  81. IRTLTRACE("Check that the keys are really present in the table and that "
  82. "the refcounting works\n");
  83. const CTest* pTest = NULL;
  84. IRTLVERIFY(LK_SUCCESS == stht.FindKey(tl.m_sz, &pTest) && pTest == &tl);
  85. IRTLASSERT(tl.m_cRefs == 2);
  86. IRTLVERIFY(LK_SUCCESS == stht.FindKey(tk.m_sz, &pTest) && pTest == &tk);
  87. IRTLASSERT(tk.m_cRefs == 2);
  88. IRTLVERIFY(LK_SUCCESS == stht.FindKey(tr.m_sz, &pTest) && pTest == &tr);
  89. IRTLASSERT(tr.m_cRefs == 2);
  90. IRTLVERIFY(LK_SUCCESS == stht.FindRecord(&tr));
  91. IRTLASSERT(tr.m_cRefs == 2); // FindRecord does not addref
  92. IRTLTRACE("Look for a key under an alternate spelling "
  93. "(case-insensitive)\n");
  94. IRTLVERIFY(LK_SUCCESS == stht.FindKey("rEiLlY", &pTest) && pTest == &tr);
  95. IRTLASSERT(tr.m_cRefs == 3);
  96. IRTLTRACE("Release the references added by FindKey\n");
  97. stht.AddRefRecord(&tl, LKAR_EXPLICIT_RELEASE);
  98. tk.m_cRefs--;
  99. tr.m_cRefs = 1;
  100. #ifdef NUM64
  101. IRTLTRACE("Quick test of the __int64 keys\n");
  102. CNum64TestHashTable ntht64;
  103. IRTLVERIFY(LK_SUCCESS == ntht64.InsertRecord(&tr));
  104. IRTLVERIFY(LK_SUCCESS == ntht64.FindKey(tr.m_n64, &pTest));
  105. ntht64.AddRefRecord(pTest, LKAR_EXPLICIT_RELEASE); // release ref
  106. IRTLVERIFY(LK_SUCCESS == ntht64.DeleteKey(tr.m_n64));
  107. #endif // NUM64
  108. IRTLTRACE("Now build the numeric hash table\n");
  109. CNumberTestHashTable ntht;
  110. IRTLVERIFY(LK_SUCCESS == ntht.InsertRecord(&tl));
  111. IRTLVERIFY(LK_SUCCESS == ntht.InsertRecord(&tk));
  112. IRTLVERIFY(LK_SUCCESS == ntht.InsertRecord(&tr));
  113. #ifdef LKR_APPLY_IF
  114. IRTLTRACE("Test ApplyIf()\n");
  115. CApplyIfTest ait;
  116. IRTLVERIFY(1 == ntht.ApplyIf(ait.Predicate, ait.Action, &ait));
  117. IRTLASSERT(3 == ait.m_cPreds && 2 == ait.m_cActions
  118. && 1 == ait.m_cSuccesses && 1 == ait.m_cFailures);
  119. IRTLTRACE("Test DeleteIf()\n");
  120. IRTLASSERT(3 == ntht.Size());
  121. ntht.DeleteIf(DeleteIfGt10, NULL);
  122. IRTLASSERT(1 == ntht.Size());
  123. IRTLTRACE("Check that the keys that were supposed to be deleted "
  124. "really are gone\n");
  125. IRTLASSERT(tl.m_n <= 10);
  126. IRTLVERIFY(LK_SUCCESS == ntht.FindKey(tl.m_n, &pTest) && pTest == &tl);
  127. ntht.AddRefRecord(pTest, LKAR_EXPLICIT_RELEASE); // release ref
  128. IRTLASSERT(tk.m_n > 10);
  129. IRTLVERIFY(LK_NO_SUCH_KEY == ntht.FindKey(tk.m_n, &pTest)
  130. && pTest == NULL);
  131. IRTLASSERT(tr.m_n > 10);
  132. IRTLVERIFY(LK_NO_SUCH_KEY == ntht.FindKey(tr.m_n, &pTest)
  133. && pTest == NULL);
  134. IRTLVERIFY(LK_SUCCESS == ntht.DeleteKey(tl.m_n));
  135. IRTLASSERT(0 == ntht.Size());
  136. #endif // LKR_APPLY_IF
  137. #ifdef LKR_DEPRECATED_ITERATORS
  138. IRTLTRACE("Check Iterators\n");
  139. DWORD cRec = 0;
  140. CStringTestHashTable::CIterator iter;
  141. LK_RETCODE lkrc = stht.InitializeIterator(&iter);
  142. while (lkrc == LK_SUCCESS)
  143. {
  144. ++cRec;
  145. CStringTestHashTable::Key pszKey = iter.Key();
  146. CStringTestHashTable::Record* pRec = iter.Record();
  147. IRTLASSERT(pRec == &tl || pRec == &tk || pRec == &tr);
  148. if (fVerbose)
  149. printf("Record(%p) contains \"%s\"\n", pRec, pszKey);
  150. lkrc = stht.IncrementIterator(&iter);
  151. }
  152. IRTLASSERT(lkrc == LK_NO_MORE_ELEMENTS);
  153. lkrc = stht.CloseIterator(&iter);
  154. IRTLASSERT(lkrc == LK_SUCCESS);
  155. IRTLASSERT(cRec == stht.Size());
  156. IRTLTRACE("Check const iterators\n");
  157. const CStringTestHashTable& sthtConst = stht;
  158. CStringTestHashTable::CConstIterator iterConst;
  159. cRec = 0;
  160. lkrc = sthtConst.InitializeIterator(&iterConst);
  161. while (lkrc == LK_SUCCESS)
  162. {
  163. ++cRec;
  164. const CStringTestHashTable::Key pszKey = iterConst.Key();
  165. const CStringTestHashTable::Record* pRec = iterConst.Record();
  166. IRTLASSERT(pRec == &tl || pRec == &tk || pRec == &tr);
  167. if (fVerbose)
  168. printf("Const Record(%p) contains \"%s\"\n", pRec, pszKey);
  169. lkrc = sthtConst.IncrementIterator(&iterConst);
  170. }
  171. IRTLASSERT(lkrc == LK_NO_MORE_ELEMENTS);
  172. lkrc = sthtConst.CloseIterator(&iterConst);
  173. IRTLASSERT(lkrc == LK_SUCCESS);
  174. IRTLASSERT(cRec == sthtConst.Size());
  175. #endif // LKR_DEPRECATED_ITERATORS
  176. #if 0
  177. IRTLTRACE("Check Clear\n");
  178. stht.Clear();
  179. IRTLASSERT(0 == stht.Size());
  180. #else
  181. IRTLTRACE("Check DeleteKey\n");
  182. IRTLVERIFY(LK_SUCCESS == stht.DeleteKey(tl.m_sz));
  183. IRTLVERIFY(LK_SUCCESS == stht.DeleteKey(tk.m_sz));
  184. IRTLTRACE("Exercise DeleteKey(pRecord)\n");
  185. IRTLVERIFY(LK_SUCCESS == stht.DeleteKey("rEiLlY", &pTest)
  186. && pTest == &tr);
  187. IRTLASSERT(tr.m_cRefs == 1);
  188. tr.m_cRefs = 0;
  189. #endif
  190. IRTLTRACE("Test done\n");
  191. // ~CTest will check for m_cRefs==0
  192. }
  193. int __cdecl
  194. main(
  195. int argc,
  196. char **argv)
  197. {
  198. IrtlSetDebugOutput(1);
  199. Test(true);
  200. return(0) ;
  201. } /* main */