00001
00002
00003 #include "index.h"
00004 #include "rules.h"
00005 #include "debug.h"
00006 #include "configuration.h"
00007 #define RE_ERROR(x) if(x) { goto error; }
00008
00009 #ifdef USE_EIRODS
00010 #include <assert.h>
00011 #else
00012 #ifndef DEBUG
00013 typedef struct {
00014 char action[MAX_ACTION_SIZE];
00015 int numberOfStringArgs;
00016 funcPtr callAction;
00017 } microsdef_t;
00018 extern int NumOfAction;
00019 extern microsdef_t MicrosTable[];
00020 #endif
00021 #endif // ifdef USE_EIRODS
00022
00023 Hashtable *coreRuleFuncMapDefIndex = NULL;
00024 Hashtable *appRuleFuncMapDefIndex = NULL;
00025 Hashtable *microsTableIndex = NULL;
00026
00027 void clearIndex(Hashtable **ruleIndex)
00028 {
00029 if (*ruleIndex!=NULL) {
00030 deleteHashTable(*ruleIndex, free);
00031 *ruleIndex = NULL;
00032 }
00033 }
00034
00035
00036
00037 int createRuleStructIndex(ruleStruct_t *inRuleStrct, Hashtable *ruleIndex)
00038 {
00039 if (ruleIndex == NULL)
00040 return 0;
00041 int i;
00042 for (i=0;i<inRuleStrct->MaxNumOfRules;i++) {
00043 char *key = inRuleStrct->action[i];
00044 int *value=(int *)malloc(sizeof(int));
00045 *value = i;
00046
00047 if (insertIntoHashTable(ruleIndex, key,value) == 0) {
00048 return 0;
00049 }
00050 }
00051 return 1;
00052 }
00053
00054 int createCondIndex(Region *r) {
00055
00056 int i;
00057 for(i=0;i<ruleEngineConfig.coreFuncDescIndex->current->size;i++) {
00058 struct bucket *b = ruleEngineConfig.coreFuncDescIndex->current->buckets[i];
00059
00060 struct bucket *resumingBucket = b;
00061
00062 while(resumingBucket!=NULL) {
00063
00064 FunctionDesc *fd = (FunctionDesc *) resumingBucket->value;
00065 resumingBucket = resumingBucket->next;
00066 if(getNodeType(fd) != N_FD_RULE_INDEX_LIST) {
00067 continue;
00068 }
00069 RuleIndexList *ruleIndexList= FD_RULE_INDEX_LIST(fd);
00070 #ifdef DEBUG_INDEX
00071 printf("processing rule pack %s into condIndex\n", resumingBucket->key);
00072 #endif
00073
00074
00075 RuleIndexListNode *currIndexNode = ruleIndexList->head;
00076
00077 while(currIndexNode!=NULL) {
00078 Hashtable *processedStrs = newHashTable2(MAX_NUM_RULES * 2, r);
00079 RuleIndexListNode *startIndexNode = currIndexNode;
00080 RuleIndexListNode *finishIndexNode = NULL;
00081 int groupCount = 0;
00082 Node *condExp = NULL;
00083 Node *params = NULL;
00084
00085 while(currIndexNode != NULL) {
00086 RuleDesc *rd = getRuleDesc(currIndexNode->ruleIndex);
00087 Node *ruleNode = rd->node;
00088 if(!(
00089 rd->ruleType == RK_REL
00090 )) {
00091 finishIndexNode = currIndexNode;
00092 currIndexNode = currIndexNode->next;
00093 break;
00094 }
00095 Node *ruleCond = ruleNode->subtrees[1];
00096 while(getNodeType(ruleCond) == N_TUPLE && ruleCond->degree == 1) {
00097 ruleCond = ruleCond->subtrees[0];
00098 }
00099 if(!(
00100 getNodeType(ruleCond) == N_APPLICATION &&
00101 getNodeType(ruleCond->subtrees[0]) == TK_TEXT &&
00102 strcmp(ruleCond->subtrees[0]->text, "==") == 0 &&
00103 getNodeType(ruleCond->subtrees[1]) == N_TUPLE &&
00104 ruleCond->subtrees[1]->degree == 2 &&
00105 getNodeType(ruleCond->subtrees[1]->subtrees[1]) == TK_STRING
00106 )) {
00107 finishIndexNode = currIndexNode;
00108 currIndexNode = currIndexNode->next;
00109 break;
00110 }
00111 char *strVal = ruleCond->subtrees[1]->subtrees[1]->text;
00112 if(lookupFromHashTable(processedStrs, strVal)!=NULL
00113 ) {
00114 finishIndexNode = currIndexNode;
00115 break;
00116 }
00117 int i;
00118 if(condExp == NULL) {
00119 condExp = ruleCond->subtrees[1]->subtrees[0];
00120 params = ruleNode->subtrees[0]->subtrees[0];
00121
00122 } else if(RULE_NODE_NUM_PARAMS(ruleNode) == params->degree) {
00123 Hashtable *varMapping = newHashTable2(100, r);
00124 for(i=0;i<params->degree;i++) {
00125 updateInHashTable(varMapping, params->subtrees[i]->text, ruleNode->subtrees[0]->subtrees[0]->subtrees[i]->text);
00126 }
00127 if(!eqExprNodeSyntacticVarMapping(condExp, ruleCond->subtrees[0], varMapping)) {
00128 finishIndexNode = currIndexNode;
00129 break;
00130 }
00131 } else {
00132 finishIndexNode = currIndexNode;
00133 break;
00134 }
00135
00136 insertIntoHashTable(processedStrs, strVal, strVal);
00137 groupCount ++;
00138
00139 currIndexNode = currIndexNode ->next;
00140 }
00141
00142
00143 if(groupCount < COND_INDEX_THRESHOLD) {
00144 continue;
00145 }
00146
00147 #ifdef DEBUG_INDEX
00148 printf("inserting rule group %s(%d) into ruleEngineConfig.condIndex\n", resumingBucket->key, groupCount);
00149 #endif
00150 Hashtable *groupHashtable = newHashTable2(groupCount * 2, r);
00151 CondIndexVal *civ = newCondIndexVal(condExp, params, groupHashtable, r);
00152
00153 RuleIndexListNode *instIndexNode = startIndexNode;
00154 while(instIndexNode != finishIndexNode) {
00155 int ri = instIndexNode->ruleIndex;
00156 Node *ruleNode = getRuleDesc(ri)->node;
00157 removeNodeFromRuleIndexList(ruleIndexList, instIndexNode);
00158 Node *ruleCond = ruleNode->subtrees[1];
00159 while(getNodeType(ruleCond) == N_TUPLE && ruleCond->degree == 1) {
00160 ruleCond = ruleCond->subtrees[0];
00161 }
00162 char *strVal = ruleCond->subtrees[1]->subtrees[1]->text;
00163 #ifdef DEBUG_INDEX
00164 printf("inserting rule cond str %s, index %d into ruleEngineConfig.condIndex\n", strVal, ri);
00165 #endif
00166
00167 insertIntoHashTable(groupHashtable, strVal, instIndexNode);
00168 instIndexNode = instIndexNode->next;
00169 }
00170 insertIntoRuleIndexList(ruleIndexList, startIndexNode->prev, civ, r);
00171 }
00172
00173 }
00174
00175 }
00176 return 1;
00177
00178 }
00179 void insertIntoRuleIndexList(RuleIndexList *rd, RuleIndexListNode *prev, CondIndexVal *civ, Region *r) {
00180 if(prev == NULL) {
00181 RuleIndexListNode *n = newRuleIndexListNode2(civ, prev, rd->head, r);
00182 rd->head = n;
00183 if(rd->tail == NULL) {
00184 rd->tail = n;
00185 }
00186 } else {
00187 RuleIndexListNode *n = newRuleIndexListNode2(civ, prev, prev->next, r);
00188 if(prev->next == NULL) {
00189 rd->tail = n;
00190 }
00191 prev->next = n;
00192 }
00193 }
00194 void removeNodeFromRuleIndexList2(RuleIndexList *rd, int i) {
00195 RuleIndexListNode *n = rd->head;
00196 while(n!=NULL && n->ruleIndex != i) {
00197 n=n->next;
00198 }
00199 if(n!=NULL) {
00200 removeNodeFromRuleIndexList(rd, n);
00201 }
00202 }
00203 void removeNodeFromRuleIndexList(RuleIndexList *rd, RuleIndexListNode *n) {
00204 if(n==rd->head) {
00205 rd->head = n->next;
00206 }
00207 if(n==rd->tail) {
00208 rd->tail = n->next;
00209 }
00210 if(n->next!=NULL) {
00211 n->next->prev = n->prev;
00212 }
00213 if(n->prev!=NULL) {
00214 n->prev->next = n->next;
00215 }
00216 }
00217 void appendRuleNodeToRuleIndexList(RuleIndexList *list, int i, Region *r) {
00218 RuleIndexListNode *listNode = newRuleIndexListNode(i, list->tail, NULL, r);
00219 list->tail ->next = listNode;
00220 list->tail = listNode;
00221
00222 }
00223 void prependRuleNodeToRuleIndexList(RuleIndexList *list, int i, Region *r) {
00224 RuleIndexListNode *listNode = newRuleIndexListNode(i, NULL, list->head, r);
00225 listNode->next = list->head;
00226 list->head = listNode;
00227
00228 }
00229
00230
00231
00232 int createRuleNodeIndex(RuleSet *inRuleSet, Hashtable *ruleIndex, int offset, Region *r)
00233 {
00234
00235 int i;
00236 for (i=0;i<inRuleSet->len;i++) {
00237 RuleDesc *rd = inRuleSet->rules[i];
00238 Node *ruleNode = rd->node;
00239 if(ruleNode == NULL)
00240 continue;
00241 RuleType ruleType = rd->ruleType;
00242 if(ruleType == RK_REL || ruleType == RK_FUNC) {
00243 char *key = ruleNode->subtrees[0]->text;
00244 FunctionDesc *fd = (FunctionDesc *) lookupFromHashTable(ruleIndex, key);
00245 if(fd != NULL) {
00246
00247 if(getNodeType(fd)==N_FD_RULE_INDEX_LIST) {
00248 RuleIndexList *list = FD_RULE_INDEX_LIST(fd);
00249 appendRuleNodeToRuleIndexList(list, i + offset, r);
00250 } else if(getNodeType(fd) == N_FD_EXTERNAL) {
00251
00252 if (updateInHashTable(ruleIndex, key, newRuleIndexListFD(newRuleIndexList(key, i + offset, r),fd->exprType, r)) == 0) {
00253 return 0;
00254 }
00255 } else {
00256
00257 return -1;
00258 }
00259 } else {
00260
00261 if (insertIntoHashTable(ruleIndex, key, newRuleIndexListFD(newRuleIndexList(key, i + offset, r), NULL, r)) == 0) {
00262 return 0;
00263 }
00264 }
00265 }
00266 }
00267
00268 return 1;
00269 }
00270
00271
00272
00273 int createFuncMapDefIndex(rulefmapdef_t *inFuncStrct, Hashtable **ruleIndex)
00274 {
00275 clearIndex(ruleIndex);
00276 *ruleIndex = newHashTable(MAX_NUM_OF_DVARS*2);
00277 if (*ruleIndex == NULL)
00278 return 0;
00279 int i;
00280 for (i=0;i<inFuncStrct->MaxNumOfFMaps;i++) {
00281 char *key = inFuncStrct->funcName[i];
00282 int *value=(int *)malloc(sizeof(int));
00283 *value = i;
00284
00285 if (insertIntoHashTable(*ruleIndex, key,value) == 0) {
00286 deleteHashTable(*ruleIndex, free);
00287 *ruleIndex=NULL;
00288 return 0;
00289 }
00290 }
00291 return 1;
00292 }
00293
00294
00295
00296 int createMacorsIndex()
00297 {
00298 #ifdef USE_EIRODS
00299 rodsLog( LOG_ERROR, "createMacorsIndex :: calling function which is supposedly not used." );
00300 assert( 0 );
00301 #else
00302 clearIndex(µsTableIndex);
00303 microsTableIndex = newHashTable(NumOfAction*2);
00304 if (microsTableIndex == NULL)
00305 return 0;
00306 int i;
00307 for (i=0;i<NumOfAction;i++) {
00308 char *key = MicrosTable[i].action;
00309 int *value=(int *)malloc(sizeof(int));
00310 *value = i;
00311 if (insertIntoHashTable(microsTableIndex, key,value) == 0) {
00312 deleteHashTable(microsTableIndex, free);
00313 microsTableIndex=NULL;
00314 return 0;
00315 }
00316 }
00317 return 1;
00318 #endif
00319 }
00320
00321 int findNextRuleFromIndex(Env *ruleIndex, char *action, int i, RuleIndexListNode **node) {
00322 int k = i;
00323 if (ruleIndex!=NULL) {
00324 FunctionDesc *fd = (FunctionDesc *)lookupFromHashTable(ruleIndex->current, action);
00325 if(fd != NULL) {
00326 if (getNodeType(fd)!=N_FD_RULE_INDEX_LIST) {
00327 return NO_MORE_RULES_ERR;
00328 }
00329 RuleIndexList *l=FD_RULE_INDEX_LIST(fd);
00330 RuleIndexListNode *b = l->head;
00331 while(k!=0) {
00332 if(b!=NULL) {
00333 b = b->next;
00334 k--;
00335 } else {
00336 break;
00337 }
00338 }
00339 if (b!=NULL) {
00340 *node = b;
00341 return 0;
00342 }
00343 }
00344 return findNextRuleFromIndex(ruleIndex->previous, action, k, node);
00345 }
00346
00347 return NO_MORE_RULES_ERR;
00348 }
00349
00350
00351
00352 int findNextRule2(char *action, int i, RuleIndexListNode **node) {
00353 if (isComponentInitialized(ruleEngineConfig.extFuncDescIndexStatus)) {
00354 int ii = findNextRuleFromIndex(ruleEngineConfig.extFuncDescIndex, action, i, node);
00355 if (ii!=NO_MORE_RULES_ERR) {
00356 return 0;
00357 } else {
00358 return NO_MORE_RULES_ERR;
00359 }
00360 } else {
00361 return NO_MORE_RULES_ERR;
00362 }
00363 }
00364
00365 int mapExternalFuncToInternalProc2(char *funcName)
00366 {
00367 int *i;
00368
00369 if (appRuleFuncMapDefIndex!=NULL && (i=(int *)lookupFromHashTable(appRuleFuncMapDefIndex, funcName))!=NULL) {
00370 strcpy(funcName, appRuleFuncMapDef.func2CMap[*i]);
00371 return(1);
00372 }
00373 if (coreRuleFuncMapDefIndex!=NULL && (i=(int *)lookupFromHashTable(coreRuleFuncMapDefIndex, funcName))!=NULL) {
00374 strcpy(funcName, coreRuleFuncMapDef.func2CMap[*i]);
00375 return(1);
00376 }
00377 return(0);
00378 }
00379 int actionTableLookUp2(char *action)
00380 {
00381 int *i;
00382
00383 if ((i=(int *)lookupFromHashTable(microsTableIndex, action))!=NULL) {
00384 return (*i);
00385 }
00386
00387 return (UNMATCHED_ACTION_ERR);
00388 }
00389 void deleteCondIndexVal(CondIndexVal *h) {
00390 deleteHashTable(h->valIndex, nop);
00391 }
00392
00393 char *convertRuleNameArityToKey(char *ruleName, int arity) {
00394
00395 char *key = (char *)malloc(strlen(ruleName) + 3);
00396 sprintf(key, "%02d%s", arity, ruleName);
00397 return key;
00398 }
00399
00400 RuleIndexList *newRuleIndexList(char *ruleName, int ruleIndex, Region *r) {
00401 RuleIndexList *list = (RuleIndexList *)region_alloc(r, sizeof(RuleIndexList));
00402 list->ruleName = cpStringExt(ruleName, r);
00403 list->head = list->tail = newRuleIndexListNode(ruleIndex, NULL, NULL, r);
00404 return list;
00405 }
00406
00407 RuleIndexListNode *newRuleIndexListNode(int ruleIndex, RuleIndexListNode *prev, RuleIndexListNode *next, Region *r) {
00408 RuleIndexListNode *node = (RuleIndexListNode *)region_alloc(r, sizeof(RuleIndexListNode));
00409 memset(node, 0, sizeof(RuleIndexListNode));
00410 node->ruleIndex = ruleIndex;
00411 node->secondaryIndex = 0;
00412 node->prev = prev;
00413 node->next = next;
00414 return node;
00415
00416 }
00417
00418 RuleIndexListNode *newRuleIndexListNode2(CondIndexVal *civ, RuleIndexListNode *prev, RuleIndexListNode *next, Region *r) {
00419 RuleIndexListNode *node = (RuleIndexListNode *)region_alloc(r, sizeof(RuleIndexListNode));
00420 memset(node, 0, sizeof(RuleIndexListNode));
00421 node->condIndex = civ;
00422 node->secondaryIndex = 1;
00423 node->prev = prev;
00424 node->next = next;
00425 return node;
00426
00427 }
00428 CondIndexVal *newCondIndexVal(Node *condExp, Node *params, Hashtable *groupHashtable, Region *r) {
00429 CondIndexVal *civ = (CondIndexVal *)region_alloc(r, sizeof(CondIndexVal));
00430 civ->condExp = condExp;
00431 civ->params = params;
00432 civ->valIndex = groupHashtable;
00433 return civ;
00434 }