windows-nt/Source/XPSP1/NT/enduser/troubleshoot/control/apgtscac.cpp
2020-09-26 16:20:57 +08:00

213 lines
4.6 KiB
C++

//
// 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 support@saltmine.com
//
// 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;
}