|
|
//
// MODULE: APGTSCAC.CPP
//
// PURPOSE: Belief network caching support classes
// Each CBNCacheItem object effectively corresponds to a possible state of the belief
// network, and provides a next recommended action. More specifically, data member
// m_CItem provides
// - an array of nodes and a corresponding array of their states. Taken together,
// these represent a state of the network
// - an array of nodes, which constitute the recommendations as to what to try next
// based on this state of the network. The first node in the list is the node we
// will display; if the user says "don't want to try this now" we'd go on to the next,
// etc.
// These are collected into a CBNCache object, so if you get a hit on one of these network
// states, you can get your recommendation without needing the overhead of hitting BNTS.
//
// PROJECT: Generic Troubleshooter DLL for Microsoft AnswerPoint
//
// COMPANY: Saltmine Creative, Inc. (206)-633-4743 [email protected]
//
// AUTHOR: Roman Mach
//
// ORIGINAL DATE: 10-2-96
//
// NOTES:
//
// Version Date By Comments
//--------------------------------------------------------------------
// V0.1 - RM Original
// V0.2 6/4/97 RWM Local Version for Memphis
// V0.3 04/09/98 JM/OK+ Local Version for NT5
//
#include "stdafx.h"
#include "apgts.h"
#include "ErrorEnums.h"
//
//
CBNCacheItem::CBNCacheItem(const BN_CACHE_ITEM *pItem, CBNCacheItem* pcitNext) { m_dwErr = 0;
memcpy(&m_CItem, pItem, sizeof (BN_CACHE_ITEM)); m_CItem.uName = (UINT *)malloc(m_CItem.uNodeCount * sizeof (UINT)); m_CItem.uValue = (UINT *)malloc(m_CItem.uNodeCount * sizeof (UINT)); m_CItem.uRec = (UINT *)malloc(m_CItem.uRecCount * sizeof (UINT));
if (m_CItem.uName && m_CItem.uValue && m_CItem.uRec) { memcpy(m_CItem.uName, pItem->uName, m_CItem.uNodeCount * sizeof (UINT)); memcpy(m_CItem.uValue, pItem->uValue, m_CItem.uNodeCount * sizeof (UINT)); memcpy(m_CItem.uRec, pItem->uRec, m_CItem.uRecCount * sizeof (UINT)); } else m_dwErr = EV_GTS_ERROR_CAC_ALLOC_MEM;
m_pcitNext = pcitNext; };
//
//
CBNCacheItem::~CBNCacheItem() { if (m_CItem.uName) free(m_CItem.uName); if (m_CItem.uValue) free(m_CItem.uValue); if (m_CItem.uRec) free(m_CItem.uRec); };
//
//
DWORD CBNCacheItem::GetStatus() { return m_dwErr; }
//
//
CBNCache::CBNCache() { m_pcit = NULL; m_dwErr = 0; }
//
//
CBNCache::~CBNCache() { CBNCacheItem *pcit, *pti;
pcit = m_pcit; while (pcit) { pti = pcit; pcit = pcit->m_pcitNext; delete pti; } }
//
//
DWORD CBNCache::GetStatus() { return m_dwErr; }
// NOTE: Must call FindCacheItem first and not call this
// function to prevent duplicate records from going into cache
//
BOOL CBNCache::AddCacheItem(const BN_CACHE_ITEM *pList) { CBNCacheItem *pcit = new CBNCacheItem(pList, m_pcit);
if (pcit == NULL) m_dwErr = EV_GTS_ERROR_CAC_ALLOC_ITEM; else if (!m_dwErr) m_dwErr = pcit->GetStatus();
return (m_pcit = pcit) != NULL; }
// Find match, return false if not found, otherwise true and fills
// structure with found item
// Also move matched up to top and remove last item if too many
//
BOOL CBNCache::FindCacheItem(const BN_CACHE_ITEM *pList, UINT& count, UINT Name[]) { UINT uSize; CBNCacheItem *pcit, *pcitfirst, *pcitlp;
uSize = pList->uNodeCount * sizeof (UINT);
pcitlp = pcitfirst = pcit = m_pcit;
for (; pcit; pcit = pcit->m_pcitNext) { if (pList->uNodeCount == pcit->m_CItem.uNodeCount) { if (!memcmp(pList->uName, pcit->m_CItem.uName, uSize) && !memcmp(pList->uValue, pcit->m_CItem.uValue, uSize)) { // check not at top already
if (pcit != pcitfirst) { // remove from list
while (pcitlp) { if (pcitlp->m_pcitNext == pcit) { pcitlp->m_pcitNext = pcitlp->m_pcitNext->m_pcitNext; break; } pcitlp = pcitlp->m_pcitNext; }
// move to top
m_pcit = pcit; pcit->m_pcitNext = pcitfirst; } break; } } }
// count items
if (CountCacheItems() > MAXCACHESIZE) { // remove last item
if ((pcitlp = m_pcit) != NULL) { if (pcitlp->m_pcitNext) { while (pcitlp) { if (pcitlp->m_pcitNext->m_pcitNext == NULL) { delete pcitlp->m_pcitNext; pcitlp->m_pcitNext = NULL; break; } pcitlp = pcitlp->m_pcitNext; } } } }
if (pcit == NULL) return FALSE; count = pcit->m_CItem.uRecCount; memcpy(Name, pcit->m_CItem.uRec, count * sizeof (UINT));
return TRUE; }
// Get count of items in cache
//
UINT CBNCache::CountCacheItems() const { UINT uCount = 0;
for (CBNCacheItem* pcit = m_pcit; pcit; pcit = pcit->m_pcitNext, uCount++) { // do nothing: action is all in condition of for-loop
} return uCount; }
|