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.

212 lines
4.6 KiB

  1. //
  2. // MODULE: APGTSCAC.CPP
  3. //
  4. // PURPOSE: Belief network caching support classes
  5. // Each CBNCacheItem object effectively corresponds to a possible state of the belief
  6. // network, and provides a next recommended action. More specifically, data member
  7. // m_CItem provides
  8. // - an array of nodes and a corresponding array of their states. Taken together,
  9. // these represent a state of the network
  10. // - an array of nodes, which constitute the recommendations as to what to try next
  11. // based on this state of the network. The first node in the list is the node we
  12. // will display; if the user says "don't want to try this now" we'd go on to the next,
  13. // etc.
  14. // These are collected into a CBNCache object, so if you get a hit on one of these network
  15. // states, you can get your recommendation without needing the overhead of hitting BNTS.
  16. //
  17. // PROJECT: Generic Troubleshooter DLL for Microsoft AnswerPoint
  18. //
  19. // COMPANY: Saltmine Creative, Inc. (206)-633-4743 [email protected]
  20. //
  21. // AUTHOR: Roman Mach
  22. //
  23. // ORIGINAL DATE: 10-2-96
  24. //
  25. // NOTES:
  26. //
  27. // Version Date By Comments
  28. //--------------------------------------------------------------------
  29. // V0.1 - RM Original
  30. // V0.2 6/4/97 RWM Local Version for Memphis
  31. // V0.3 04/09/98 JM/OK+ Local Version for NT5
  32. //
  33. #include "stdafx.h"
  34. #include "apgts.h"
  35. #include "ErrorEnums.h"
  36. //
  37. //
  38. CBNCacheItem::CBNCacheItem(const BN_CACHE_ITEM *pItem, CBNCacheItem* pcitNext)
  39. {
  40. m_dwErr = 0;
  41. memcpy(&m_CItem, pItem, sizeof (BN_CACHE_ITEM));
  42. m_CItem.uName = (UINT *)malloc(m_CItem.uNodeCount * sizeof (UINT));
  43. m_CItem.uValue = (UINT *)malloc(m_CItem.uNodeCount * sizeof (UINT));
  44. m_CItem.uRec = (UINT *)malloc(m_CItem.uRecCount * sizeof (UINT));
  45. if (m_CItem.uName && m_CItem.uValue && m_CItem.uRec) {
  46. memcpy(m_CItem.uName, pItem->uName, m_CItem.uNodeCount * sizeof (UINT));
  47. memcpy(m_CItem.uValue, pItem->uValue, m_CItem.uNodeCount * sizeof (UINT));
  48. memcpy(m_CItem.uRec, pItem->uRec, m_CItem.uRecCount * sizeof (UINT));
  49. }
  50. else
  51. m_dwErr = EV_GTS_ERROR_CAC_ALLOC_MEM;
  52. m_pcitNext = pcitNext;
  53. };
  54. //
  55. //
  56. CBNCacheItem::~CBNCacheItem()
  57. {
  58. if (m_CItem.uName)
  59. free(m_CItem.uName);
  60. if (m_CItem.uValue)
  61. free(m_CItem.uValue);
  62. if (m_CItem.uRec)
  63. free(m_CItem.uRec);
  64. };
  65. //
  66. //
  67. DWORD CBNCacheItem::GetStatus()
  68. {
  69. return m_dwErr;
  70. }
  71. //
  72. //
  73. CBNCache::CBNCache()
  74. {
  75. m_pcit = NULL;
  76. m_dwErr = 0;
  77. }
  78. //
  79. //
  80. CBNCache::~CBNCache()
  81. {
  82. CBNCacheItem *pcit, *pti;
  83. pcit = m_pcit;
  84. while (pcit) {
  85. pti = pcit;
  86. pcit = pcit->m_pcitNext;
  87. delete pti;
  88. }
  89. }
  90. //
  91. //
  92. DWORD CBNCache::GetStatus()
  93. {
  94. return m_dwErr;
  95. }
  96. // NOTE: Must call FindCacheItem first and not call this
  97. // function to prevent duplicate records from going into cache
  98. //
  99. BOOL CBNCache::AddCacheItem(const BN_CACHE_ITEM *pList)
  100. {
  101. CBNCacheItem *pcit = new CBNCacheItem(pList, m_pcit);
  102. if (pcit == NULL)
  103. m_dwErr = EV_GTS_ERROR_CAC_ALLOC_ITEM;
  104. else if (!m_dwErr)
  105. m_dwErr = pcit->GetStatus();
  106. return (m_pcit = pcit) != NULL;
  107. }
  108. // Find match, return false if not found, otherwise true and fills
  109. // structure with found item
  110. // Also move matched up to top and remove last item if too many
  111. //
  112. BOOL CBNCache::FindCacheItem(const BN_CACHE_ITEM *pList, UINT& count, UINT Name[])
  113. {
  114. UINT uSize;
  115. CBNCacheItem *pcit, *pcitfirst, *pcitlp;
  116. uSize = pList->uNodeCount * sizeof (UINT);
  117. pcitlp = pcitfirst = pcit = m_pcit;
  118. for (; pcit; pcit = pcit->m_pcitNext)
  119. {
  120. if (pList->uNodeCount == pcit->m_CItem.uNodeCount)
  121. {
  122. if (!memcmp(pList->uName, pcit->m_CItem.uName, uSize) &&
  123. !memcmp(pList->uValue, pcit->m_CItem.uValue, uSize))
  124. {
  125. // check not at top already
  126. if (pcit != pcitfirst)
  127. {
  128. // remove from list
  129. while (pcitlp) {
  130. if (pcitlp->m_pcitNext == pcit)
  131. {
  132. pcitlp->m_pcitNext = pcitlp->m_pcitNext->m_pcitNext;
  133. break;
  134. }
  135. pcitlp = pcitlp->m_pcitNext;
  136. }
  137. // move to top
  138. m_pcit = pcit;
  139. pcit->m_pcitNext = pcitfirst;
  140. }
  141. break;
  142. }
  143. }
  144. }
  145. // count items
  146. if (CountCacheItems() > MAXCACHESIZE)
  147. {
  148. // remove last item
  149. if ((pcitlp = m_pcit) != NULL)
  150. {
  151. if (pcitlp->m_pcitNext)
  152. {
  153. while (pcitlp)
  154. {
  155. if (pcitlp->m_pcitNext->m_pcitNext == NULL)
  156. {
  157. delete pcitlp->m_pcitNext;
  158. pcitlp->m_pcitNext = NULL;
  159. break;
  160. }
  161. pcitlp = pcitlp->m_pcitNext;
  162. }
  163. }
  164. }
  165. }
  166. if (pcit == NULL)
  167. return FALSE;
  168. count = pcit->m_CItem.uRecCount;
  169. memcpy(Name, pcit->m_CItem.uRec, count * sizeof (UINT));
  170. return TRUE;
  171. }
  172. // Get count of items in cache
  173. //
  174. UINT CBNCache::CountCacheItems() const
  175. {
  176. UINT uCount = 0;
  177. for (CBNCacheItem* pcit = m_pcit; pcit; pcit = pcit->m_pcitNext, uCount++)
  178. {
  179. // do nothing: action is all in condition of for-loop
  180. }
  181. return uCount;
  182. }