📄 asmrulep.cpp
字号:
case HX_RE_LESSEQUAL:
case HX_RE_LESS:
case HX_RE_EQUAL:
case HX_RE_NOTEQUAL:
if (bInvolveR)
{
bInvolvesTheOpenVariable = TRUE;
*pThreshold = Left;
pThreshold++;
ulNumThreshold++;
RETURN ((float)1);
}
if (bInvolveL)
{
bInvolvesTheOpenVariable = TRUE;
*pThreshold = Right;
pThreshold++;
ulNumThreshold++;
RETURN ((float)1);
}
break;
case HX_RE_AND:
if ((Left && bInvolveR) || (Right && bInvolveL))
{
bInvolvesTheOpenVariable = TRUE;
UINT32 ulSize = ulNumThresholdL + ulNumThresholdR;
pThreshold += ulSize;
ulNumThreshold += ulSize;
RETURN ((float)1);
}
else
{
RETURN ((float)0);
}
case HX_RE_OR:
if (Left || bInvolveL || Right || bInvolveR)
{
bInvolvesTheOpenVariable = TRUE;
UINT32 ulSize = ulNumThresholdL + ulNumThresholdR;
pThreshold += ulSize;
ulNumThreshold += ulSize;
RETURN ((float)1);
}
else
{
RETURN ((float)0);
}
}
switch (((OperatorNode *)pNode)->m_Data)
{
case HX_RE_GREATEREQUAL:
RETURN ((float)(Left >= Right));
case HX_RE_GREATER:
RETURN ((float)(Left > Right));
case HX_RE_LESSEQUAL:
RETURN ((float)(Left <= Right));
case HX_RE_LESS:
RETURN ((float)(Left < Right));
case HX_RE_EQUAL:
RETURN ((float)(Left == Right));
case HX_RE_NOTEQUAL:
RETURN ((float)(Left != Right));
case HX_RE_AND:
RETURN ((float)(Left && Right));
case HX_RE_OR:
RETURN ((float)(Left || Right));
default:
HX_ASSERT(0);
RETURN ((float)0);
}
}
default:
HX_ASSERT(0);
RETURN ((float)0);
}
exitpoint:
return retval;
#undef RETURN
}
void
ASMRuleExpression::PreEvaluate(float*& pThreshold, UINT32& ulNumThreshold,
IHXValues* pVariables, const char* pPreVar)
{
BOOL bJunk = 0;
RPreEvaluate(m_pHead, pVariables, pPreVar,
pThreshold, ulNumThreshold, bJunk);
}
/*
* This is a recursive expression evaluator that will determine whether
* or not the given variable occurs anywhere in the expression.
*/
BOOL
ASMRuleExpression::RFindVariable(Node* pNode, const char* pVariable)
{
if (!pNode)
return FALSE;
switch(pNode->m_Type)
{
case HX_RE_VARIABLE:
{
if (strcasecmp(((VariableNode *)pNode)->m_Data, pVariable) == 0)
{
return TRUE;
}
}
break;
case HX_RE_OPERATOR:
{
return (RFindVariable(pNode->m_pLeft, pVariable) ||
RFindVariable(pNode->m_pRight, pVariable));
}
case HX_RE_INTEGER:
case HX_RE_FLOAT:
default:
break;
}
return FALSE;
}
BOOL
ASMRuleExpression::FindVariable(const char* pVariable)
{
return RFindVariable(m_pHead, pVariable);
}
class Rule
{
public:
Rule();
void SetExpression(const char* pExpression);
void Dump();
private:
ASMRuleExpression* m_pASMRuleExpression;
// Add Properties Definitions Here
};
ASMRule::ASMRule()
: m_pRuleExpression(0)
{
m_pRuleProps = new CHXHeader;
HX_ASSERT(m_pRuleProps != NULL);
if(m_pRuleProps)
{
m_pRuleProps->AddRef();
}
}
ASMRule::~ASMRule()
{
HX_RELEASE(m_pRuleProps);
HX_DELETE(m_pRuleExpression);
}
void
ASMRule::SetExpression(const char* pExpression)
{
m_pRuleExpression = new ASMRuleExpression(pExpression);
}
void
ASMRule::Dump()
{
m_pRuleExpression->Dump();
}
ASMRuleBook::ASMRuleBook(const char* pRuleBook)
: m_pValidRulesArray(NULL)
, m_pDeletedRulesArray(NULL)
, m_pRuleBook(NULL)
, m_LastError(HXR_OK)
{
m_ulNumThresholds = 1; // always have a default
int i;
const char* pRule;
// Count Rules
i = 0;
BOOL bSingleQuote = 0;
BOOL bDoubleQuote = 0;
for (pRule = pRuleBook; *pRule; pRule++)
{
if ((*pRule == '\'') && (!bDoubleQuote))
bSingleQuote = !bSingleQuote;
if ((*pRule == '"') && (!bSingleQuote))
bDoubleQuote = !bDoubleQuote;
// Count the number of semi-colons (number of rules)
if ((bSingleQuote == 0) && (bDoubleQuote == 0) && (*pRule == ';'))
i++;
}
m_unNumRules = i;
m_pRules = new ASMRule[i];
if(!m_pRules)
{
m_LastError = HXR_OUTOFMEMORY;
return;
}
//printf ("%d Rules\n", i);
// Iterate through each rule
m_pRuleBook = new char[ strlen( pRuleBook ) + 1 ];
if(!m_pRuleBook)
{
m_LastError = HXR_OUTOFMEMORY;
HX_DELETE(m_pRules);
return;
}
else
{
memcpy( (void*) m_pRuleBook, pRuleBook, strlen( pRuleBook ) + 1 );
}
m_LastError = Reset();
}
ASMRuleBook::~ASMRuleBook()
{
delete [] m_pRules;
if( m_pValidRulesArray )
{
HX_VECTOR_DELETE(m_pValidRulesArray);
}
if( m_pDeletedRulesArray )
{
HX_VECTOR_DELETE(m_pDeletedRulesArray);
}
HX_VECTOR_DELETE(m_pRuleBook);
}
BOOL
ASMRuleBook::HasExpression()
{
for (int i = 0; i < m_unNumRules; i++)
{
if (m_pRules[i].m_pRuleExpression)
return TRUE;
}
return FALSE;
}
HX_RESULT
ASMRuleBook::GetProperties(UINT16 unRuleNumber, IHXValues*& pRuleProps)
{
pRuleProps = m_pRules[unRuleNumber].m_pRuleProps;
if( pRuleProps )
{
pRuleProps->AddRef();
}
return HXR_OK;
}
/* Uses REvaluate to return the current subscription given pVariables */
HX_RESULT
ASMRuleBook::GetSubscription(BOOL* pSubInfo, IHXValues* pVariables)
{
UINT32 i = 0;
for (i = 0; i < m_unNumRules; i++)
{
if( m_pDeletedRulesArray && m_pDeletedRulesArray[i] == TRUE )
{
pSubInfo[i] = 0;
}
else if (m_pRules[i].m_pRuleExpression)
{
pSubInfo[i] = m_pRules[i].m_pRuleExpression->Evaluate(pVariables);
}
else
{
pSubInfo[i] = 1;
}
}
return HXR_OK;
}
/*
* Uses RFindVariable to return information on which rules contain a
* given variable in their expressions
*/
HX_RESULT
ASMRuleBook::FindVariable(BOOL* pFound, const char* pVariable)
{
UINT32 i = 0;
for (i = 0; i < m_unNumRules; i++)
{
if (m_pRules[i].m_pRuleExpression)
{
pFound[i] = m_pRules[i].m_pRuleExpression->FindVariable(pVariable);
}
else
{
pFound[i] = FALSE;
}
}
return HXR_OK;
}
/*
* Uses GetProperties to return information on which rules contain a
* given property
*/
HX_RESULT
ASMRuleBook::FindProperty(BOOL* pFound, const char* pProperty)
{
HX_RESULT hResult = HXR_OK;
UINT32 i = 0;
IHXValues* pProperties = NULL;
IHXBuffer* pBuffer = NULL;
for (i = 0; i < m_unNumRules; i++)
{
hResult = GetProperties((UINT16)i, pProperties);
if (HXR_OK == hResult)
{
hResult = pProperties->GetPropertyCString(pProperty, pBuffer);
if (HXR_OK == hResult)
{
pFound[i] = TRUE;
HX_RELEASE(pBuffer);
}
HX_RELEASE(pProperties);
}
}
return HXR_OK;
}
static int FloatCompare(const void* p1, const void* p2)
{
if (*(float*)p1 < *(float*)p2)
return -1;
if (*(float*)p1 > *(float*)p2)
return 1;
return 0;
}
/*
* Uses RPreEvaluate to return the array of threshold values,
* given pVariables and pPreVar (the free variable)
* Caveat: Your variables must say "0" for pPreVar in pVariables.
*/
HX_RESULT
ASMRuleBook::GetPreEvaluate(float* pThreshold, UINT32& ulNumThreshold,
IHXValues* pVariables, const char* pPreVar)
{
UINT16 i;
float* pUnsortedFinal = new float[m_ulNumThresholds+1];
float* pTemp = pUnsortedFinal;
UINT32 ulUFNum = 0;
ulNumThreshold = 0;
/* Get everything into a unsorted array with duplicates */
for (i = 0; i < m_unNumRules; i++)
{
if (m_pRules[i].m_pRuleExpression)
{
m_pRules[i].m_pRuleExpression->PreEvaluate(pTemp, ulUFNum,
pVariables, pPreVar);
}
}
/*
* XXXSMP Totally disgusting and doesn't belong here. So much for
* a clean, extensible function.
*/
IHXValues* pValues = 0;
IHXBuffer* pBuffer = 0;
pUnsortedFinal[ulUFNum] = (float)0;
for (i = 0; i < m_unNumRules; i++)
{
BOOL bOn = TRUE;
if (m_pRules[i].m_pRuleExpression)
{
bOn = m_pRules[i].m_pRuleExpression->Evaluate(pVariables);
}
if (bOn)
{
GetProperties((UINT16) i, pValues);
if (HXR_OK == pValues->GetPropertyCString("AverageBandwidth",
pBuffer))
{
pUnsortedFinal[ulUFNum] += atoi((char*)pBuffer->GetBuffer());
pBuffer->Release();
}
if (HXR_OK == pValues->GetPropertyCString("DropByN",
pBuffer))
{
pUnsortedFinal[ulUFNum] += 1;
pBuffer->Release();
}
HX_RELEASE(pValues);
}
}
ulUFNum++;
pUnsortedFinal[ulUFNum] = (float)0;
qsort(pUnsortedFinal, ulUFNum+1, sizeof(float), FloatCompare);
/* Sort and squash duplicates into the output array */
pTemp = pUnsortedFinal;
float fLast = *pUnsortedFinal;
*pThreshold = *pUnsortedFinal;
pTemp++;
pThreshold++;
ulNumThreshold++;
for (i = 0; i < ulUFNum; i++)
{
if (*pTemp > fLast)
{
fLast = *pTemp;
*pThreshold = fLast;
pThreshold++;
ulNumThreshold++;
}
pTemp++;
}
delete [] pUnsortedFinal;
return HXR_OK;
}
#ifdef TESTING
int
main()
{
const char* pRuleBook =
{
/* Rule 0 */
" \
#(24000 <= $Bandwidth) && ($Cpu > 50), \
TolerablePacketLoss=1.5, \
AverageBandwidth=4000, \
AverageBandwidthStd=0, \
Priority=7; \
"
/* Rule 1 */
" \
#(20000 <= $Bandwidth), \
TolerablePacketLoss=1.5, \
AverageBandwidth=4000, \
AverageBandwidthStd=0, \
Priority=7; \
"
/* Rule 2 */
" \
# $Bandwidth >= 16000, \
TolerablePacketLoss=1.5, \
AverageBandwidth=16000, \
AverageBandwidthStd=0, \
Priority=7; \
"
/* Rule 3 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -