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.

244 lines
6.9 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. IRTLTRACE("Now build the numeric hash table\n");
  101. CNumberTestHashTable ntht;
  102. IRTLVERIFY(LK_SUCCESS == ntht.InsertRecord(&tl));
  103. IRTLVERIFY(LK_SUCCESS == ntht.InsertRecord(&tk));
  104. IRTLVERIFY(LK_SUCCESS == ntht.InsertRecord(&tr));
  105. #ifdef LKR_APPLY_IF
  106. IRTLTRACE("Test ApplyIf()\n");
  107. CApplyIfTest ait;
  108. IRTLVERIFY(1 == ntht.ApplyIf(ait.Predicate, ait.Action, &ait));
  109. IRTLASSERT(3 == ait.m_cPreds && 2 == ait.m_cActions
  110. && 1 == ait.m_cSuccesses && 1 == ait.m_cFailures);
  111. IRTLTRACE("Test DeleteIf()\n");
  112. IRTLASSERT(3 == ntht.Size());
  113. ntht.DeleteIf(DeleteIfGt10, NULL);
  114. IRTLASSERT(1 == ntht.Size());
  115. IRTLTRACE("Check that the keys that were supposed to be deleted "
  116. "really are gone\n");
  117. IRTLASSERT(tl.m_n <= 10);
  118. IRTLVERIFY(LK_SUCCESS == ntht.FindKey(tl.m_n, &pTest) && pTest == &tl);
  119. ntht.AddRefRecord(pTest, LKAR_EXPLICIT_RELEASE); // release ref
  120. IRTLASSERT(tk.m_n > 10);
  121. IRTLVERIFY(LK_NO_SUCH_KEY == ntht.FindKey(tk.m_n, &pTest)
  122. && pTest == NULL);
  123. IRTLASSERT(tr.m_n > 10);
  124. IRTLVERIFY(LK_NO_SUCH_KEY == ntht.FindKey(tr.m_n, &pTest)
  125. && pTest == NULL);
  126. IRTLVERIFY(LK_SUCCESS == ntht.DeleteKey(tl.m_n));
  127. IRTLASSERT(0 == ntht.Size());
  128. #endif // LKR_APPLY_IF
  129. #ifdef LKR_DEPRECATED_ITERATORS
  130. IRTLTRACE("Check Iterators\n");
  131. DWORD cRec = 0;
  132. CStringTestHashTable::CIterator iter;
  133. LK_RETCODE lkrc = stht.InitializeIterator(&iter);
  134. while (lkrc == LK_SUCCESS)
  135. {
  136. ++cRec;
  137. CStringTestHashTable::Key pszKey = iter.Key();
  138. CStringTestHashTable::Record* pRec = iter.Record();
  139. IRTLASSERT(pRec == &tl || pRec == &tk || pRec == &tr);
  140. if (fVerbose)
  141. printf("Record(%p) contains \"%s\"\n", pRec, pszKey);
  142. lkrc = stht.IncrementIterator(&iter);
  143. }
  144. IRTLASSERT(lkrc == LK_NO_MORE_ELEMENTS);
  145. lkrc = stht.CloseIterator(&iter);
  146. IRTLASSERT(lkrc == LK_SUCCESS);
  147. IRTLASSERT(cRec == stht.Size());
  148. IRTLTRACE("Check const iterators\n");
  149. const CStringTestHashTable& sthtConst = stht;
  150. CStringTestHashTable::CConstIterator iterConst;
  151. cRec = 0;
  152. lkrc = sthtConst.InitializeIterator(&iterConst);
  153. while (lkrc == LK_SUCCESS)
  154. {
  155. ++cRec;
  156. const CStringTestHashTable::Key pszKey = iterConst.Key();
  157. const CStringTestHashTable::Record* pRec = iterConst.Record();
  158. IRTLASSERT(pRec == &tl || pRec == &tk || pRec == &tr);
  159. if (fVerbose)
  160. printf("Const Record(%p) contains \"%s\"\n", pRec, pszKey);
  161. lkrc = sthtConst.IncrementIterator(&iterConst);
  162. }
  163. IRTLASSERT(lkrc == LK_NO_MORE_ELEMENTS);
  164. lkrc = sthtConst.CloseIterator(&iterConst);
  165. IRTLASSERT(lkrc == LK_SUCCESS);
  166. IRTLASSERT(cRec == sthtConst.Size());
  167. #endif // LKR_DEPRECATED_ITERATORS
  168. #if 0
  169. IRTLTRACE("Check Clear\n");
  170. stht.Clear();
  171. IRTLASSERT(0 == stht.Size());
  172. #else
  173. IRTLTRACE("Check DeleteKey\n");
  174. IRTLVERIFY(LK_SUCCESS == stht.DeleteKey(tl.m_sz));
  175. IRTLVERIFY(LK_SUCCESS == stht.DeleteKey(tk.m_sz));
  176. IRTLVERIFY(LK_SUCCESS == stht.DeleteKey(tr.m_sz));
  177. #endif
  178. IRTLTRACE("Test done\n");
  179. // ~CTest will check for m_cRefs==0
  180. }
  181. int __cdecl
  182. main(
  183. int argc,
  184. char **argv)
  185. {
  186. Test(true);
  187. return(0) ;
  188. } /* main */