static struct factPatternNode *FindPatternNode( struct factPatternNode *listOfNodes, struct lhsParseNode *thePattern, struct factPatternNode **nodeBeforeMatch, unsigned endSlot) { *nodeBeforeMatch = NULL; /*==========================================================*/ /* Loop through the nodes at the given level in the pattern */ /* network looking for a node that can be reused (shared)? */ /*==========================================================*/ while (listOfNodes != NULL) { /*==========================================================*/ /* If the type of the pattern node and the expression being */ /* tested by the pattern node are the same as the type and */ /* expression for the pattern field being added, then */ /* return the pattern node because it can be shared with */ /* the pattern field being added. */ /*==========================================================*/ if ((thePattern->type == SF_WILDCARD) || (thePattern->type == SF_VARIABLE)) { if ((listOfNodes->header.singlefieldNode) && (listOfNodes->header.endSlot == endSlot) && (listOfNodes->whichField == thePattern->index) && (listOfNodes->whichSlot == (thePattern->slotNumber - 1)) && IdenticalExpression(listOfNodes->networkTest,thePattern->networkTest)) { return(listOfNodes); } } else if ((thePattern->type == MF_WILDCARD) || (thePattern->type == MF_VARIABLE)) { if ((listOfNodes->header.multifieldNode) && (listOfNodes->header.endSlot == endSlot) && (listOfNodes->leaveFields == thePattern->singleFieldsAfter) && (listOfNodes->whichField == thePattern->index) && (listOfNodes->whichSlot == (thePattern->slotNumber - 1)) && IdenticalExpression(listOfNodes->networkTest,thePattern->networkTest)) { return(listOfNodes); } } /*==================================*/ /* Move on to the next node at this */ /* level in the pattern network. */ /*==================================*/ *nodeBeforeMatch = listOfNodes; listOfNodes = listOfNodes->rightNode; } /*==============================================*/ /* A shareable pattern node could not be found. */ /*==============================================*/ return(NULL); }
globle BOOLEAN IdenticalExpression( struct expr *firstList, struct expr *secondList) { /*==============================================*/ /* Compare each argument in both expressions by */ /* following the nextArg list. */ /*==============================================*/ for (; (firstList != NULL) && (secondList != NULL); firstList = firstList->nextArg, secondList = secondList->nextArg) { /*=========================*/ /* Compare type and value. */ /*=========================*/ if (firstList->type != secondList->type) { return(FALSE); } if (firstList->value != secondList->value) { return (FALSE); } /*==============================*/ /* Compare the arguments lists. */ /*==============================*/ if (IdenticalExpression(firstList->argList,secondList->argList) == FALSE) { return(FALSE); } } /*=====================================================*/ /* If firstList and secondList aren't both NULL, then */ /* one of the lists contains more expressions than the */ /* other. */ /*=====================================================*/ if (firstList != secondList) return(FALSE); /*============================*/ /* Expressions are identical. */ /*============================*/ return(TRUE); }
/*************************************************** NAME : FindHashedExpression DESCRIPTION : Determines if a given expression is in the expression hash table INPUTS : 1) The expression 2) A buffer to hold the hash value 3) A buffer to hold the previous node in the hash chain RETURNS : The expression hash table entry (NULL if not found) SIDE EFFECTS : None NOTES : None ***************************************************/ static EXPRESSION_HN *FindHashedExpression( EXPRESSION *exp, unsigned *hashval, EXPRESSION_HN **prv) { EXPRESSION_HN *exphash; if (exp == NULL) return(NULL); *hashval = HashExpression(exp); *prv = NULL; exphash = ExpressionHashTable[*hashval]; while (exphash != NULL) { if (IdenticalExpression(exphash->exp,exp)) return(exphash); *prv = exphash; exphash = exphash->nxt; } return(NULL); }
static int TestJoinForReuse( struct joinNode *testJoin, unsigned firstJoin, unsigned negatedRHS, unsigned existsRHS, unsigned int isLogical, struct expr *joinTest, struct expr *secondaryJoinTest, struct expr *leftHash, struct expr *rightHash) { /*==================================================*/ /* The first join of a rule may only be shared with */ /* a join that has its firstJoin field set to TRUE. */ /*==================================================*/ if (testJoin->firstJoin != firstJoin) return(FALSE); /*========================================================*/ /* A join connected to a not CE may only be shared with a */ /* join that has its patternIsNegated field set to TRUE. */ /*========================================================*/ if ((testJoin->patternIsNegated != negatedRHS) && (! existsRHS)) return(FALSE); /*==========================================================*/ /* A join connected to an exists CE may only be shared with */ /* a join that has its patternIsExists field set to TRUE. */ /*==========================================================*/ if (testJoin->patternIsExists != existsRHS) return(FALSE); /*==========================================================*/ /* If the join added is associated with a logical CE, then */ /* either the join to be shared must be associated with a */ /* logical CE or the beta memory must be empty (since */ /* joins associate an extra field with each partial match). */ /*==========================================================*/ if ((isLogical == TRUE) && (testJoin->logicalJoin == FALSE) && BetaMemoryNotEmpty(testJoin)) { return(FALSE); } /*===============================================================*/ /* The expression associated with the join must be identical to */ /* the networkTest expression stored with the join to be shared. */ /*===============================================================*/ if (IdenticalExpression(testJoin->networkTest,joinTest) != TRUE) { return(FALSE); } if (IdenticalExpression(testJoin->secondaryNetworkTest,secondaryJoinTest) != TRUE) { return(FALSE); } /*====================================================================*/ /* The alpha memory hashing values associated with the join must be */ /* identical to the hashing values stored with the join to be shared. */ /*====================================================================*/ if (IdenticalExpression(testJoin->leftHash,leftHash) != TRUE) { return(FALSE); } if (IdenticalExpression(testJoin->rightHash,rightHash) != TRUE) { return(FALSE); } /*=============================================*/ /* The join can be shared since all conditions */ /* for sharing have been satisfied. */ /*=============================================*/ return(TRUE); }
static struct expr *SwitchParse( void *theEnv, struct expr *top, char *infile) { struct token theToken; EXPRESSION *theExp,*chk; int default_count = 0; /*============================*/ /* Process the switch value */ /*============================*/ IncrementIndentDepth(theEnv,3); SavePPBuffer(theEnv," "); top->argList = theExp = ParseAtomOrExpression(theEnv,infile,NULL); if (theExp == NULL) goto SwitchParseError; /*========================*/ /* Parse case statements. */ /*========================*/ GetToken(theEnv,infile,&theToken); while (theToken.type != RPAREN) { PPBackup(theEnv); PPCRAndIndent(theEnv); SavePPBuffer(theEnv,theToken.printForm); if (theToken.type != LPAREN) goto SwitchParseErrorAndMessage; GetToken(theEnv,infile,&theToken); SavePPBuffer(theEnv," "); if ((theToken.type == SYMBOL) && (strcmp(ValueToString(theToken.value),"case") == 0)) { if (default_count != 0) goto SwitchParseErrorAndMessage; theExp->nextArg = ParseAtomOrExpression(theEnv,infile,NULL); SavePPBuffer(theEnv," "); if (theExp->nextArg == NULL) goto SwitchParseError; for (chk = top->argList->nextArg ; chk != theExp->nextArg ; chk = chk->nextArg) { if ((chk->type == theExp->nextArg->type) && (chk->value == theExp->nextArg->value) && IdenticalExpression(chk->argList,theExp->nextArg->argList)) { PrintErrorID(theEnv,"PRCDRPSR",3,TRUE); EnvPrintRouter(theEnv,WERROR,"Duplicate case found in switch function.\n"); goto SwitchParseError; } } GetToken(theEnv,infile,&theToken); if ((theToken.type != SYMBOL) ? TRUE : (strcmp(ValueToString(theToken.value),"then") != 0)) goto SwitchParseErrorAndMessage; } else if ((theToken.type == SYMBOL) && (strcmp(ValueToString(theToken.value),"default") == 0)) { if (default_count) goto SwitchParseErrorAndMessage; theExp->nextArg = GenConstant(theEnv,RVOID,NULL); default_count = 1; } else goto SwitchParseErrorAndMessage; theExp = theExp->nextArg; if (ExpressionData(theEnv)->svContexts->rtn == TRUE) ExpressionData(theEnv)->ReturnContext = TRUE; if (ExpressionData(theEnv)->svContexts->brk == TRUE) ExpressionData(theEnv)->BreakContext = TRUE; IncrementIndentDepth(theEnv,3); PPCRAndIndent(theEnv); theExp->nextArg = GroupActions(theEnv,infile,&theToken,TRUE,NULL,FALSE); DecrementIndentDepth(theEnv,3); ExpressionData(theEnv)->ReturnContext = FALSE; ExpressionData(theEnv)->BreakContext = FALSE; if (theExp->nextArg == NULL) goto SwitchParseError; theExp = theExp->nextArg; PPBackup(theEnv); PPBackup(theEnv); SavePPBuffer(theEnv,theToken.printForm); GetToken(theEnv,infile,&theToken); } DecrementIndentDepth(theEnv,3); return(top); SwitchParseErrorAndMessage: SyntaxErrorMessage(theEnv,"switch function"); SwitchParseError: ReturnExpression(theEnv,top); DecrementIndentDepth(theEnv,3); return(NULL); }