📄 asmrulep.cpp
字号:
UINT32 ulNumThresholdR = 0; pThresholdR = pThreshold + ulNumThresholdL; float Right = RPreEvaluate(pNode->m_pRight, pVars, pPreVar, pThresholdR, ulNumThresholdR, bInvolveR); /* Handle aggregation of Threshold arrays */ switch (((OperatorNode *)pNode)->m_Data) { case HX_RE_GREATEREQUAL: case HX_RE_GREATER: 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}voidASMRuleExpression::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. */ BOOLASMRuleExpression::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;}BOOLASMRuleExpression::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);}voidASMRule::SetExpression(const char* pExpression){ m_pRuleExpression = new ASMRuleExpression(pExpression);}voidASMRule::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);}BOOLASMRuleBook::HasExpression(){ for (int i = 0; i < m_unNumRules; i++) { if (m_pRules[i].m_pRuleExpression) return TRUE; } return FALSE;}HX_RESULTASMRuleBook::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_RESULTASMRuleBook::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_RESULTASMRuleBook::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_RESULTASMRuleBook::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_RESULTASMRuleBook::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 TESTINGintmain(){ 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, \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -