/* If there are multiple selection predicates associated with each of ** the RCG node, then we need to merge them and create a single selection ** predicate by and'ing. This merged selection predicate then is called ** decorated selection predicate. */ void generate_decorated_RCG(RCG *graph) { ListElement *cursor, *tree_cursor; RCG_node *node; syntree *node_tree, *and_tree; ASSERT (graph); for (node = (RCG_node *)List_getFirst(graph->nodes, &cursor); node; node = (RCG_node *)List_getNext(&cursor)) { for (node_tree = (syntree *)List_getFirst(node->selection_predicates_list, &tree_cursor); node_tree; node_tree = (syntree *)List_getNext(&tree_cursor)) { if (node->decorated_selection_predicate != NULL) { /* create a new AND node, with decorated_selection_predicate ** as left tree and node_tree as right tree. */ and_tree = and_new (node->decorated_selection_predicate, node_tree); node->decorated_selection_predicate = and_tree; } else { node->decorated_selection_predicate = node_tree; } } } }
T Set_union (T set1, T set2) { T newSet; List_t p; Assert_ASSERT(set1); Assert_ASSERT(set2); newSet = Set_new (set1->equals); p = List_getFirst (set1->list); while (p){ Set_insert (newSet, p->data); p = p->next; } p = List_getFirst (set2->list); while (p){ Poly_t v = (Poly_t)p->data; if (!List_exists (set1->list, v, set1->equals)) Set_insert (newSet, v); else; p = p->next; } return newSet; }
/* Function to create a complete RCG including the TRUE join conditions for the nodes which are isolated and without any join condition */ void build_complete_RCG (RCG *graph) { syntree *temp_tree, *TRUE_syntree = NULL; List *null_join_list; ListElement *cursor, *cursor1; RCG_node *rcg_node, *ref_rcg_node; ASSERT (graph); // Initialise the list to hold the null join list nodes null_join_list = List_new(); ref_rcg_node = NULL; /* Find all the RCG nodes hanging around without any join predicates and find the reference RCG node */ rcg_node = (RCG_node *)List_getFirst(graph->nodes, &cursor); while (rcg_node != NULL) { temp_tree = (syntree *)List_getFirst(rcg_node->join_predicates_list, &cursor1); if (temp_tree == NULL) { /* Insert into the list all the RCG nodes with null join predicates */ List_insertElement(null_join_list, rcg_node); } else { /* Choose this node as the root reference node for the TRUE join condition */ ref_rcg_node = rcg_node; } rcg_node = (RCG_node *)List_getNext(&cursor); } if (ref_rcg_node == NULL) { List_deleteHead(null_join_list); ref_rcg_node = (RCG_node *)List_getFirst(graph->nodes, &cursor); } /* Initialise the TRUE join condition syntax tree if there are isolated RCG nodes*/ if (!List_isEmpty(null_join_list)) { TRUE_syntree = (syntree *)tman_malloc(sizeof(syntree)); memset(TRUE_syntree, '\0', sizeof(syntree)); TRUE_syntree->type = TRUE_ORDINARY_PRED_TYPE; TRUE_syntree->datum = chars_new("TRUE"); } /* Create the TRUE join connection for all those nodes without any join condition */ rcg_node = (RCG_node *)List_getFirst(null_join_list, &cursor); while (rcg_node != NULL) { // Insert the TRUE condition to the null join condition node */ List_insertElement(rcg_node->join_predicates_list, TRUE_syntree); rcg_node->reference_tuple_variable_name = ref_rcg_node->tuple_variable_name; // Insert the TRUE condition to the reference node also */ List_insertElement(ref_rcg_node->join_predicates_list, TRUE_syntree); rcg_node = (RCG_node *)List_getNext(&cursor); } List_deleteBackbone(null_join_list); }
// Creates a new RULE CONDITION GRAPH - it creates a RCG node for every tuple variable // Takes the tuple variable and the data source list along with the number of tuple variables // as the input RCG *RCG_new(int num_tuple_var, List *tuple_var_list, List *datasrc_list) { RCG *graph; int i; ListElement *cursor1, *cursor2; RCG_node *node; void *tuple_var_name, *datasrc_name; ASSERT(tuple_var_list); ASSERT(datasrc_list); graph = (RCG *)tman_malloc(sizeof(RCG)); memset(graph, '\0', sizeof(RCG)); graph->type = RCG_TYPE; graph->num_tuple_variables = num_tuple_var; graph->nodes = List_new(); graph->catch_all = List_new(); if (!num_tuple_var) { /* The RCG does not have any tuple variables. For ex. ** when 1 = 1. */ return graph; } /* create the individual nodes -- one for each tuple variable*/ node = RCG_node_new(); tuple_var_name = (char *)List_getFirst(tuple_var_list, &cursor1); datasrc_name = (char *)List_getFirst(datasrc_list, &cursor2); node->tuple_variable_name = get_chars(tuple_var_name); node->datasrc_name = get_chars(datasrc_name); /* Insert the node into the RCG */ List_insertElement(graph->nodes, node); for (i = 1; i < num_tuple_var; i++) { /* create the individual nodes */ node = RCG_node_new(); tuple_var_name = (char *)List_getNext(&cursor1); datasrc_name = (char *)List_getNext(&cursor2); node->tuple_variable_name = get_chars(tuple_var_name); node->datasrc_name = get_chars(datasrc_name); /* Insert the node into the RCG */ List_insertElement(graph->nodes, node); } return graph; }
// Converts the when clause to CNF. Set the variable when_clause_modified // to TRUE if the when clause is modified. void convert_when_clause_to_CNF(syntree *when_clause, int *when_clause_modified) { int tree_modified = TRUE; List *del_node_list, *temp_list; ListElement *cursor1, *cursor2; syntree *node_to_be_del, *possible_duplicate; // Create a list to store all the syntax tree nodes that have to be deleted // after the when clause has been converted to CNF. del_node_list = List_new(); if (when_clause) { while(tree_modified) { tree_modified = FALSE; convert_to_CNF (when_clause, &tree_modified, del_node_list); if (tree_modified == TRUE) { *when_clause_modified = TRUE; } } } // Delete the syntax tree nodes in the delete node list. As the list may contain duplicate // copies of one or more nodes, delete the nodes only once but remove the list element for // the duplicates too. node_to_be_del = List_getFirst(del_node_list, &cursor1); while (node_to_be_del != NULL) { // Delete the list element but not the contents. node_to_be_del = List_deleteElement(del_node_list, &cursor1); // Assign this to a temporary list to search for duplicate copies of this node. temp_list = del_node_list; // Go through the remaining list to delete the list elements for the duplicate copies. possible_duplicate = List_getFirst(temp_list, &cursor2); while (possible_duplicate != NULL) { // Check for the duplicate. if (node_to_be_del == possible_duplicate) { // Delete the duplicate list element. Ignore the contents returned. List_deleteElement(temp_list, &cursor2); // Start traversing the list again. possible_duplicate = List_getFirst(temp_list, &cursor2); } else { possible_duplicate = List_getNext(&cursor2); } } // Delete the contents of the original syntax tree node. syntree_delete_root_node(node_to_be_del); node_to_be_del = List_getFirst(del_node_list, &cursor1); } tman_free(del_node_list); }
/* Similar to generate_decorated_RCG Instead of taking a RCG graph as the input, it takes a list of syntax trees as the input, ANDs them and creates a single syntax tree */ syntree *generate_decorated_syntree(List *syntreeList) { ListElement *cursor; syntree *node_tree, *and_tree, *decoratedSyntree; ASSERT (syntreeList); decoratedSyntree = NULL; // AND the list of syntax trees for (node_tree = (syntree *)List_getFirst(syntreeList, &cursor); node_tree; node_tree = (syntree *)List_getNext(&cursor)) { if (decoratedSyntree != NULL) { /* create a new AND node, with decorated_selection_predicate ** as left tree and node_tree as right tree. */ and_tree = and_new(decoratedSyntree, node_tree); decoratedSyntree = and_tree; } else { decoratedSyntree = node_tree; } } return decoratedSyntree; }
/* Searches and deletes the constant node from the list of constant nodes for the signature */ static void delete_const_node_from_sig_list(constant_node *const_node_to_delete, List *const_list) { constant_node *const_node; ListElement *cursor; ASSERT(const_node_to_delete); ASSERT (const_list); // Search the constant node to be deleted in the constant list const_node = (constant_node *)List_getFirst(const_list, &cursor); while (const_node != NULL) { // If the constant node from the list matches the // constant node to be deleted -- a match is found if (const_node == const_node_to_delete) { // Delete the constant node from the constant list const_node_to_delete = (constant_node *)List_deleteElement(const_list, &cursor); break; } else { const_node = (constant_node *)List_getNext(&cursor); } } // The constant node cannot be NULL ASSERT(const_node_to_delete); // Delete the contents of the constant node tman_delete(const_node_to_delete); }
int search_negated_elements (ft_doc_index *doc_idx, List *negated_elements) { ListElement *cursor; void *element; ft_word_info word_info; ASSERT (negated_elements); for (element = List_getFirst (negated_elements, &cursor); element; element = List_getNext (&cursor)) { if (*(int *)element == FT_WORD_TYPE) { if (search_word (doc_idx, element, &word_info) == TMAN_FOUND) { return TMAN_FOUND; } } else if (*(int *)element == FT_PHRASE_TYPE) { if (search_phrase (doc_idx, element) == TMAN_FOUND) { return TMAN_FOUND; } } } return TMAN_NOT_FOUND; }
static double match_score_or_basic_pred (ft_doc_index *doc_idx, ft_basic_pred *ft_pred) { int num_non_negated_words, i; double result; ft_word_info *non_negated_words_info; ft_word_info non_neg_words_info_static[10] = {'\0'}; word_syntree *word; ft_phrase_info *phrase_info = NULL; ListElement *cursor; ASSERT (ft_pred); // There should be no negated word in this basic predicate. ASSERT (ft_pred->negated_query_elements == NULL); num_non_negated_words = va_get_size (ft_pred->non_negated_words); if (num_non_negated_words <= 10) { non_negated_words_info = non_neg_words_info_static; } else { non_negated_words_info = (ft_word_info *) tman_malloc (num_non_negated_words * sizeof(ft_word_info)); memset (non_negated_words_info, '\0', num_non_negated_words * sizeof(ft_word_info)); } for (i = 0; i < num_non_negated_words; i++) { word = (word_syntree *)va_get_element (ft_pred->non_negated_words, i); search_word (doc_idx, word, &(non_negated_words_info[i])); } // Do phrase matching. if (ft_pred->phrases_words_info) { for (phrase_info = List_getFirst (ft_pred->phrases_words_info, &cursor); phrase_info; phrase_info = List_getNext (&cursor)) { phrase_pos_match (doc_idx, phrase_info, non_negated_words_info, num_non_negated_words); } } // Score the basic predicate. result = calculate_score (non_negated_words_info, num_non_negated_words); if (num_non_negated_words > 10) { tman_free (non_negated_words_info); } return result; }
void HashSet_unionVoidSet (T set1, Set_t set2) { List_t p; Assert_ASSERT(set1); Assert_ASSERT(set2); p = List_getFirst (Set_toList (set2)); while (p){ HashSet_insert (set1, p->data); p = p->next; } return; }
int Set_exists (T set, Poly_t x) { List_t p; Assert_ASSERT(set); p = List_getFirst (set->list); while (p){ if (set->equals (x, p->data)) return 1; p = p->next; } return 0; }
void print_RCG(RCG *graph) { ListElement *node_cursor, *tree_cursor; RCG_node *node; syntree *tree; ASSERT(graph); for (node = List_getFirst(graph->nodes, &node_cursor); node; node = List_getNext(&node_cursor)) { logwrite("Node is %s\n", node->tuple_variable_name); logwrite("data source is %s\n", node->datasrc_name); logwrite("The selection predicates in the node are "); for (tree = List_getFirst(node->selection_predicates_list, &tree_cursor); tree; tree = List_getNext(&tree_cursor)) { print_tree(tree, 0); logwrite (""); } logwrite ("The decorated selction predicate for the node is"); print_tree(node->decorated_selection_predicate, 0); logwrite ("The join predicates in the node are"); for (tree = List_getFirst(node->join_predicates_list, &tree_cursor); tree; tree = List_getNext(&tree_cursor)) { print_tree(tree, 0); logwrite (""); } } }
int main(int argc, char **argv) { List_t l = List_new(); fprintf(stdout, "test List...\n"); int i; for (i = 0; i < 100; i++) { List_addFirst(l, i); } fprintf(stdout, "List_getFirst\n"); int r = (int) List_getFirst(l); assert(r == 99); fprintf(stdout, "List_getIndexOf\n"); for (i = 0; i < 100; i++) { r = (int) List_getIndexOf(l, i); assert(r == (99 - i)); } fprintf(stdout, "List_addLast\n"); List_addLast(l, 200); r = (int) List_getIndexOf(l, 100); assert(r == 200); fprintf(stdout, "List_size\n"); r = List_size(l); assert(r == 101); fprintf(stdout, "List_isEmpty\n"); r = List_isEmpty(l); assert(r == 0); List_t l2 = List_new(); r = List_isEmpty(l2); assert(r == 1); fprintf(stdout, "List_remove\n"); for (i = 0; i < 100; i++) { r = (int) List_removeFirst(l); assert(r == (99 - i)); } r = (int) List_removeFirst(l); assert(r == 200); r = List_isEmpty(l); assert(r == 1); return 0; }
void ft_basic_pred_print_tree (ft_basic_pred *node, int level) { syntree *query_element_node; ListElement *cursor; indent (level, "[Basic Predicate Type - %d]", node->basic_pred_type); if (node->non_negated_words) { indent (level, "[Non negated words]"); print_tree (node->non_negated_words, level); } if (node->negated_query_elements) { indent (level, "[Negated query-words]"); for (query_element_node = List_getFirst (node->negated_query_elements, &cursor); query_element_node; query_element_node = List_getNext (&cursor)) { print_tree (query_element_node, level); } } if (node->phrases_words_info) { int index = 1; ft_phrase_info *temp_phrase_info; for (temp_phrase_info = List_getFirst (node->phrases_words_info, &cursor); temp_phrase_info; temp_phrase_info = List_getNext (&cursor), index++) { indent (level, "[Phrase %d]", index); print_tree (temp_phrase_info, level); } } }
void reset(RCG *graph) { ListElement *cursor; RCG_node *node; ASSERT (graph); for (node = (RCG_node *)List_getFirst(graph->nodes, &cursor); node; node = (RCG_node *)List_getNext(&cursor)) { node->already_inserted = 0; } }
static List_t transBlocks (List_t blocks) { List_t tmp, result = List_new (); Assert_ASSERT(blocks); tmp = List_getFirst (blocks); while (tmp){ Ssa_Block_t b = (Ssa_Block_t)tmp->data; if (Property_get (visited, b)) List_insertLast (result, b); tmp = tmp->next; } return result; }
// Function that deletes the TRUE join nodes // Should be never called if all the nodes in the RCG are naturally connected // Should be called only once when there are one or more isolated RCG nodes int del_TRUE_join_node(RCG_node *rcg_node) { ListElement *cursor; syntree *join_tree; ASSERT(rcg_node); join_tree = (syntree *)List_getFirst(rcg_node->join_predicates_list, &cursor); while (join_tree != NULL) { if (join_tree->type == TRUE_ORDINARY_PRED_TYPE) { join_tree = List_deleteElement(rcg_node->join_predicates_list, &cursor); tman_delete(join_tree); return TRUE; } join_tree = (syntree *)List_getNext(&cursor); } return FALSE; }
void Set_unionVoid (T set1, T set2) { List_t p; Assert_ASSERT(set1); Assert_ASSERT(set2); p = List_getFirst (set2->list); while (p){ Poly_t v = (Poly_t)p->data; // this may be further enhanced if (!List_exists (set1->list, v, set1->equals)) Set_insert (set1, v); else; p = p->next; } return; }
RCG_node *get_node_from_RCG(char *name, RCG *graph) { ListElement *cursor; RCG_node *node; ASSERT (name); ASSERT (graph); for (node = (RCG_node *)List_getFirst(graph->nodes, &cursor); node; node = (RCG_node *)List_getNext(&cursor)) { if (strcmp(node->tuple_variable_name, name) == 0) return node; } logwrite ("Internal error: tuple variable %s not found in rule condition graph (RCG).", name); TMAN_HALT; return NULL; }
// Destructor for the whole RCG void RCG_delete(RCG *arg) { int already_processed; RCG_node *rcgNode; ListElement *cursor; // RCG graph for a trigger cannot be NULL ASSERT (arg); already_processed = FALSE; // Delete the RCG nodes for this RCG // Get the first gator node from the RCG graph rcgNode = (RCG_node*)List_getFirst(arg->nodes, &cursor); while (rcgNode != NULL) { // Isolated RCG nodes with no edges are connected to the root // node(selected while constructing the RCG) by TRUE edges. // More than one RCG node may share this TRUE syntax tree as the connecting edge. // It can be deleted only once. if (already_processed == FALSE) { already_processed = del_TRUE_join_node(rcgNode); } tman_delete(rcgNode); /* Get the next rcg node */ rcgNode = (RCG_node *)List_getNext(&cursor); } // Delete the backbone of the list of gator nodes List_deleteBackbone(arg->nodes); // Delete the backbone of the catch all list List_deleteBackbone(arg->catch_all); // Delete the gator network tman_free(arg); }
// This function inserts an element iff it doesn't already exist in the list. // Do not use it to compare values of contents. It just does the dumb checking for // pointers of the objects to be same. void List_insert_uniqueElement (List *theList, void *theContents, int *exist) { ListElement *cursor; void *element; ASSERT (theList); ASSERT (theContents); for (element = List_getFirst (theList, &cursor); element; element = List_getNext (&cursor)) { if (element == theContents) { *exist = TRUE; return; } } // The element does not exist in the list, append the element here. *exist = FALSE; List_insertElement (theList, theContents); }
File_t X86_Mask_print (File_t file, M m) { List_t p; Assert_ASSERT(m); fprintf (file, "%s", Id_toString (m->name)); fprintf (file, ":\n\t.int "); fprintf (file, "%s", Int_toString (m->size)); if (List_isEmpty (m->index)){ fprintf (file, "\n"); return file; } fprintf (file, ", "); p = List_getFirst (m->index); while (p){ fprintf (file, "%s", Int_toString ((int)p->data)); if (p->next) fprintf (file, ", "); p = p->next; } fprintf (file, "\n"); return file; }
int Set_equals (T set1, T set2) { T newSet; List_t p; Assert_ASSERT(set1); Assert_ASSERT(set1); if (List_size (set1->list) != List_size (set2->list)) return 0; p = List_getFirst (set1->list); while (p){ Poly_t v = (Poly_t)p->data; if (List_exists (set2->list, v, set1->equals)) ; else return 0; p = p->next; } return 1; }
/*---------------------------------------------------------------------*/ void StringList_init(StringList *stringList) { assert(stringList != NULL); List_init(stringList); } void StringList_done(StringList *stringList) { assert(stringList != NULL); List_done(stringList,(ListNodeFreeFunction)freeStringNode,NULL); } StringList *StringList_new(void) { return (StringList*)List_new(); } StringList *StringList_duplicate(const StringList *stringList) { StringList *newStringList; assert(stringList != NULL); newStringList = StringList_new(); if (newStringList == NULL) { return NULL; } StringList_copy(newStringList,stringList); return newStringList; } void StringList_copy(StringList *stringList, const StringList *fromStringList) { StringNode *stringNode; assert(stringList != NULL); assert(fromStringList != NULL); stringNode = fromStringList->head; while (stringNode != NULL) { StringList_append(stringList,stringNode->string); stringNode = stringNode->next; } } void StringList_delete(StringList *stringList) { assert(stringList != NULL); List_delete(stringList,(ListNodeFreeFunction)freeStringNode,NULL); } void StringList_clear(StringList *stringList) { assert(stringList != NULL); List_clear(stringList,(ListNodeFreeFunction)freeStringNode,NULL); } void StringList_move(StringList *fromStringList, StringList *toStringList) { assert(fromStringList != NULL); assert(toStringList != NULL); List_move(fromStringList,toStringList,NULL,NULL,NULL); } #ifdef NDEBUG void StringList_insert(StringList *stringList, const String string, StringNode *nextStringNode) #else /* not NDEBUG */ void __StringList_insert(const char *__fileName__, ulong __lineNb__, StringList *stringList, const String string, StringNode *nextStringNode) #endif /* NDEBUG */ { #ifdef NDEBUG insertString(stringList,String_duplicate(string),nextStringNode); #else /* not NDEBUG */ insertString(__fileName__,__lineNb__,stringList,__String_duplicate(__fileName__,__lineNb__,string),nextStringNode); #endif /* NDEBUG */ } #ifdef NDEBUG void StringList_insertCString(StringList *stringList, const char *s, StringNode *nextStringNode) #else /* not NDEBUG */ void __StringList_insertCString(const char *__fileName__, ulong __lineNb__, StringList *stringList, const char *s, StringNode *nextStringNode) #endif /* NDEBUG */ { #ifdef NDEBUG insertString(stringList,String_newCString(s),nextStringNode); #else /* not NDEBUG */ insertString(__fileName__,__lineNb__,stringList,__String_newCString(__fileName__,__lineNb__,s),nextStringNode); #endif /* NDEBUG */ } #ifdef NDEBUG void StringList_insertChar(StringList *stringList, char ch, StringNode *nextStringNode) #else /* not NDEBUG */ void __StringList_insertChar(const char *__fileName__, ulong __lineNb__, StringList *stringList, char ch, StringNode *nextStringNode) #endif /* NDEBUG */ { #ifdef NDEBUG insertString(stringList,String_newChar(ch),nextStringNode); #else /* not NDEBUG */ insertString(__fileName__,__lineNb__,stringList,__String_newChar(__fileName__,__lineNb__,ch),nextStringNode); #endif /* NDEBUG */ } #ifdef NDEBUG void StringList_insertBuffer(StringList *stringList, char *buffer, ulong bufferLength, StringNode *nextStringNode) #else /* not NDEBUG */ void __StringList_insertBuffer(const char *__fileName__, ulong __lineNb__, StringList *stringList, char *buffer, ulong bufferLength, StringNode *nextStringNode) #endif /* NDEBUG */ { #ifdef NDEBUG insertString(stringList,String_newBuffer(buffer,bufferLength),nextStringNode); #else /* not NDEBUG */ insertString(__fileName__,__lineNb__,stringList,__String_newBuffer(__fileName__,__lineNb__,buffer,bufferLength),nextStringNode); #endif /* NDEBUG */ } #ifdef NDEBUG void StringList_append(StringList *stringList, const String string) #else /* not NDEBUG */ void __StringList_append(const char *__fileName__, ulong __lineNb__, StringList *stringList, const String string) #endif /* NDEBUG */ { #ifdef NDEBUG insertString(stringList,String_duplicate(string),NULL); #else /* not NDEBUG */ insertString(__fileName__,__lineNb__,stringList,__String_duplicate(__fileName__,__lineNb__,string),NULL); #endif /* NDEBUG */ } #ifdef NDEBUG void StringList_appendCString(StringList *stringList, const char *s) #else /* not NDEBUG */ void __StringList_appendCString(const char *__fileName__, ulong __lineNb__, StringList *stringList, const char *s) #endif /* NDEBUG */ { #ifdef NDEBUG insertString(stringList,String_newCString(s),NULL); #else /* not NDEBUG */ insertString(__fileName__,__lineNb__,stringList,__String_newCString(__fileName__,__lineNb__,s),NULL); #endif /* NDEBUG */ } #ifdef NDEBUG void StringList_appendChar(StringList *stringList, char ch) #else /* not NDEBUG */ void __StringList_appendChar(const char *__fileName__, ulong __lineNb__, StringList *stringList, char ch) #endif /* NDEBUG */ { #ifdef NDEBUG insertString(stringList,String_newChar(ch),NULL); #else /* not NDEBUG */ insertString(__fileName__,__lineNb__,stringList,__String_newChar(__fileName__,__lineNb__,ch),NULL); #endif /* NDEBUG */ } #ifdef NDEBUG void StringList_appendBuffer(StringList *stringList, char *buffer, ulong bufferLength) #else /* not NDEBUG */ void __StringList_appendBuffer(const char *__fileName__, ulong __lineNb__, StringList *stringList, char *buffer, ulong bufferLength) #endif /* NDEBUG */ { #ifdef NDEBUG insertString(stringList,String_newBuffer(buffer,bufferLength),NULL); #else /* not NDEBUG */ insertString(__fileName__,__lineNb__,stringList,__String_newBuffer(__fileName__,__lineNb__,buffer,bufferLength),NULL); #endif /* NDEBUG */ } #ifdef NDEBUG StringNode *StringList_remove(StringList *stringList, StringNode *stringNode) #else /* not NDEBUG */ StringNode *__StringList_remove(const char *__fileName__, ulong __lineNb__, StringList *stringList, StringNode *stringNode) #endif /* NDEBUG */ { StringNode *nextStringNode; assert(stringList != NULL); assert(stringNode != NULL); nextStringNode = (StringNode*)List_remove(stringList,stringNode); String_delete(stringNode->string); #ifdef NDEBUG stringNode = (StringNode*)LIST_DELETE_NODE(stringNode); #else /* not NDEBUG */ stringNode = (StringNode*)__LIST_DELETE_NODE(__fileName__,__lineNb__,stringNode); #endif /* NDEBUG */ return nextStringNode; } #ifdef NDEBUG String StringList_getFirst(StringList *stringList, String string) #else /* not NDEBUG */ String __StringList_getFirst(const char *fileName, ulong lineNb, StringList *stringList, String string) #endif /* NDEBUG */ { StringNode *stringNode; assert(stringList != NULL); stringNode = (StringNode*)List_getFirst(stringList); if (stringNode != NULL) { if (string != NULL) { String_set(string,stringNode->string); String_delete(stringNode->string); } else { string = stringNode->string; } #ifdef NDEBUG LIST_DELETE_NODE(stringNode); #else /* not NDEBUG */ __LIST_DELETE_NODE(fileName,lineNb,stringNode); #endif /* NDEBUG */ return string; } else { if (string != NULL) { String_clear(string); } return NULL; } }
static void delete_trigger_ID_node(RCG_node *arg, int index) { triggerID_node *id_node; ListElement *cursor; ASSERT(arg); id_node = (triggerID_node *)List_getFirst(arg->trigger_ID_list[index], &cursor); while (id_node != NULL) { // Get the trigger ID node for this trigger // If it matches the trigger ID pointer of the rcg_node -- A match is found if (arg->triggerID_for_rcg_node[index] == id_node) { // Delete the trigger ID node from the trigger ID list id_node = (triggerID_node *)List_deleteElement(arg->trigger_ID_list[index], &cursor); break; } else { id_node = (triggerID_node *)List_getNext(&cursor); } } // The trigger ID node cannot be NULL ASSERT(arg->triggerID_for_rcg_node[index]); // If there is a signature tree attached to trig_sig_tree_if_first_in_const_node, the predicate // index in which the trigger is installed might need to save some constant value present in the // syntax tree of this trigger. if (arg->triggerID_for_rcg_node[index]->trig_sig_tree_if_first_in_const_node) { save_const_node_info (arg->triggerID_for_rcg_node[index]->trig_sig_tree_if_first_in_const_node); } // Delete the contents of the trigger ID node tman_delete(arg->triggerID_for_rcg_node[index]); }
// This function populates the fields inside the ft_basic_pred pred from the free text basic predicate's // syntax tree rooted at node. static void form_basic_predicate (ft_basic_pred *pred, syntree **ptr_ft_syntree) { ASSERT (pred); ASSERT (ptr_ft_syntree); ASSERT (*ptr_ft_syntree); // If the node is a word, insert it into the non negated word list of pred. if ((*ptr_ft_syntree)->type == FT_WORD_TYPE) { if (pred->non_negated_words == NULL) { pred->non_negated_words = va_new (); } va_append_element (pred->non_negated_words, *ptr_ft_syntree); // Detach the node from the syntax tree, so that the data is not freed when the syntax tree is // deleted later. *ptr_ft_syntree = NULL; return; } // If the node is a phrase, insert the words inside its word list into the non negated word list of pred. // Also insert in every word a phrase_info node which will contain sequencing information of words in a phrase. // Later the non_negated_words array will be reordered according to the selectivity of the words. The new positions // of words will then be recorded in the phrase_info node, so the matching routine can use that information to // do a phrase match. if ((*ptr_ft_syntree)->type == FT_PHRASE_TYPE) { // initial position is 0. int pos_in_phrase; word_syntree *word_node; ft_phrase_info *phrase_info; ListElement *cursor; if (pred->non_negated_words == NULL) { pred->non_negated_words = va_new (); } if (pred->phrases_words_info == NULL) { pred->phrases_words_info = List_new (); } // This node will contain the information about this particular phrase. phrase_info = ft_phrase_info_new (((phrase_syntree *)(*ptr_ft_syntree))->num_words); List_insertElement (pred->phrases_words_info, phrase_info); pos_in_phrase = 0; for (word_node = List_getFirst (((phrase_syntree *)(*ptr_ft_syntree))->word_list, &cursor); word_node; word_node = List_getNext (&cursor)) { // Change the position from UNDETERMINED to the position in phrase. word_node->pos_in_phrase = pos_in_phrase++; // Save the ptr to phrase info node for the phrase to which the word_node belongs. Later, the index of the word // inside the non negated words array will be stored inside this phrase info node. We do not store the index // here as it is subject to change in case a reorder operation is performed on words for AND/ACCRUE type // basic predicates. This node will be used for phrase matching at a later stage. word_node->phrase_info = phrase_info; // Insert the word in the non negated word array. va_append_element (pred->non_negated_words, word_node); } // Delete the backbone of the word list inside the phrase list, since the // contents of this list have already been inserted inside the non negated word list. List_deleteBackbone (((phrase_syntree *)(*ptr_ft_syntree))->word_list); ((phrase_syntree *)(*ptr_ft_syntree))->word_list = NULL; return; } // If the node is a NOT node, insert its child into the negated query word list of pred. if ((*ptr_ft_syntree)->type == FT_NOT_TYPE) { if (pred->negated_query_elements == NULL) { pred->negated_query_elements = List_new (); } List_insertElement (pred->negated_query_elements, (*ptr_ft_syntree)->left_tree); // Detach the left tree of the NOT node, so that it is not deleted. (*ptr_ft_syntree)->left_tree = NULL; return; } // This code is only applicable to an operator node. ASSERT ((*ptr_ft_syntree)->type == FT_AND_TYPE || (*ptr_ft_syntree)->type == FT_OR_TYPE || (*ptr_ft_syntree)->type == FT_ACCRUE_TYPE); form_basic_predicate (pred, &((*ptr_ft_syntree)->left_tree)); form_basic_predicate (pred, &((*ptr_ft_syntree)->right_tree)); }
/* Mover dispatcher wakes up the movers whenever any data source gets updated. */ DWORD WINAPI mover_dispatcher(LPVOID ptr) { int task_count, i; int num_of_mover; int num_available_mover; int upd_datasrc_count = 0; const char *updated_datasrc_list = "TM_updated_Datasrc_list"; List *upd_datasrc_list; ListElement *cursor; update_queue_node *upd_datasrc; const char *database_taskque_name = "Database_TaskQueue"; taskqueue_type *taskqueue; while (!g_fTerminate) { // Get the handle to the global database token task queue that stores the unprocessed tokens // from database inserts/updates/deletes. tman_lock_memory(database_taskque_name); taskqueue = tman_named_get(database_taskque_name); // Get the number of outstanding unprocessed tasks task_count = taskqueue->counter; tman_unlock_memory(database_taskque_name); // Get the number of active movers EnterCriticalSection(&mover_num_mutex); num_of_mover = num_mover; LeaveCriticalSection(&mover_num_mutex); // Find if any data sources have been updated lately delivered_list_update(); // Retrieve the list of updated data sources from shared memory. tman_lock_memory(updated_datasrc_list); upd_datasrc_list = tman_named_get (updated_datasrc_list); // If there are any new updated data sources and there is available space in the global // task queue, wake up the movers. // A ceiling is imposed on the task queue to apply back pressure on the movers // to stop after the task queue is full. This will prevent the doers from lagging behind // and movers from moving too many tokens at the same time. if ((task_count < MAX_DATABASE_TASK_QUEUE_SIZE) && (!List_isEmpty(upd_datasrc_list))) { // Database task queue is NOT FULL and new database tokens to process // Calculate the number of updated data sources upd_datasrc_count = 0; upd_datasrc = (update_queue_node *)List_getFirst(upd_datasrc_list, &cursor); while (upd_datasrc != NULL) { upd_datasrc_count++; upd_datasrc = (update_queue_node *)List_getNext(&cursor); } // Calculate the number of available movers num_available_mover = MAXMOVER - num_of_mover; tman_unlock_memory(updated_datasrc_list); // If number of available movers > number of updated data sources, // wake up one mover per data source if (upd_datasrc_count < num_available_mover) { for (i = 0; i < upd_datasrc_count; i++) { ReleaseSemaphore(wakeup_mover_by_mover_dispatcher_sem, 1, NULL); } } // If number of available movers < number of updated data sources, // wake up all the available movers else { for (i = 0; i < num_available_mover; i++) { ReleaseSemaphore(wakeup_mover_by_mover_dispatcher_sem, 1, NULL); } } } else { tman_unlock_memory(updated_datasrc_list); } Sleep(SLEEP_DISPATCHER_PERIOD); } // Release the movers. for (i = 0; i < MAXMOVER; i++) { ReleaseSemaphore(wakeup_mover_by_mover_dispatcher_sem, 1, NULL); } return 1; }
static int search_phrase (ft_doc_index *doc_idx, phrase_syntree *phrase) { ft_word_info *words_info; ft_word_info words_info_static[10] = {'\0'}; int words_pos_static[10] = {0}; ListElement *cursor; word_syntree *word; int i; ft_phrase_info phrase_info; int result = TMAN_FOUND; ASSERT (phrase); phrase_info.num_words = phrase->num_words; phrase_info.type = FT_PHRASE_INFO_TYPE; if (phrase->num_words > 10) { words_info = (ft_word_info *)tman_malloc (phrase->num_words * sizeof(ft_word_info)); memset (words_info, '\0', phrase->num_words * sizeof(ft_word_info)); phrase_info.word_positions = (int *)tman_malloc (phrase->num_words * sizeof (int)); memset (phrase_info.word_positions, 0, phrase->num_words * sizeof (int)); } else { words_info = words_info_static; phrase_info.word_positions = words_pos_static; } // First search all the words in the phrase. If there is even one word that is not present in the document, // the search should fail. for (word = List_getFirst (phrase->word_list, &cursor), i = 0; word; word = List_getNext (&cursor), i++) { // Word positions are the same as they appear in the word list in phrase node. phrase_info.word_positions[i] = i; if (search_word (doc_idx, word, &(words_info[i])) == TMAN_NOT_FOUND) { result = TMAN_NOT_FOUND; break; } } if (result == TMAN_NOT_FOUND) { goto cleanup; } else { // If all the words are present in the document, search for their sequencing. if (phrase_pos_match (doc_idx, &phrase_info, words_info, phrase->num_words) == TMAN_NOMATCH) { result = TMAN_NOT_FOUND; } } cleanup: if (phrase->num_words > 10) { tman_free (words_info); tman_free (phrase_info.word_positions); } return (result); }
static double match_score_accrue_basic_pred (ft_doc_index *doc_idx, ft_basic_pred *ft_pred) { int num_non_negated_words = 0, status, i; double result; ft_word_info *non_negated_words_info = NULL; ft_word_info non_neg_words_info_static[10] = {'\0'}; word_syntree *word; ft_phrase_info *phrase_info = NULL; ListElement *cursor; ASSERT (ft_pred); // First check for negated words, if any. if (ft_pred->negated_query_elements != NULL) { status = search_negated_elements (doc_idx, ft_pred->negated_query_elements); // If even one negated element was found, bail out. if (status == TMAN_FOUND) { result = 0.0; goto cleanup; } } num_non_negated_words = va_get_size (ft_pred->non_negated_words); if (num_non_negated_words <= 10) { non_negated_words_info = non_neg_words_info_static; } else { non_negated_words_info = (ft_word_info *) tman_malloc (num_non_negated_words * sizeof(ft_word_info)); memset (non_negated_words_info, '\0', num_non_negated_words * sizeof(ft_word_info)); } for (i = 0; i < num_non_negated_words; i++) { word = (word_syntree *)va_get_element (ft_pred->non_negated_words, i); search_word (doc_idx, word, &(non_negated_words_info[i])); } // Do phrase matching. if (ft_pred->phrases_words_info) { for (phrase_info = List_getFirst (ft_pred->phrases_words_info, &cursor); phrase_info; phrase_info = List_getNext (&cursor)) { phrase_pos_match (doc_idx, phrase_info, non_negated_words_info, num_non_negated_words); } } // Score the basic predicate. result = calculate_score (non_negated_words_info, num_non_negated_words); cleanup: if (num_non_negated_words > 10) { tman_free (non_negated_words_info); } return result; }
// Drop the trigger object and all the related ADTs int delTrigger(trigger *arg) { DATUM *after_clause_datasrc = NULL; char *after_clause_datasrc_name = NULL; RCG *temp_rcg; RCG_node *rcg_node; ListElement *cursor; // create trigger ADT cannot be null ASSERT(arg); // Get the name of the datasrc in the after clause if there is one. if (arg->after_clause == NULL) { after_clause_datasrc = NULL; } else { get_after_clause_datasrc(arg->after_clause, &after_clause_datasrc); after_clause_datasrc_name = get_chars(after_clause_datasrc); } // Extract the RCG pointer temp_rcg = (RCG *)arg->rule_condition_graph; // The RCG graph cannot be NULL ASSERT(temp_rcg); // Delete the trigger ID nodes of this trigger for all the data sources rcg_node = (RCG_node *)List_getFirst(temp_rcg->nodes, &cursor); while (rcg_node != NULL) { // If the after clause is specified, then check whether the tuple variable name of this RCG node matches the // tuple variable name specified in the after clause. If they match, then this rcg node has a corresponding // trigger id node, otherwise it does not have one. if (after_clause_datasrc != NULL) { if (strcmp(rcg_node->tuple_variable_name, after_clause_datasrc_name) != 0) { // The rcg node's tuple variable name does not match with the after clause. // So it does not have a trigger ID node entry in the SPI, so skip this rcg node. rcg_node = (RCG_node *)List_getNext(&cursor); continue; } } // Find the trigger ID nodes for this rcg node and delete them delete_trigger_ID_node(rcg_node, DEFAULT_INDEX); // If the trigger ID list is empty, then delete the constant. if (List_isEmpty(rcg_node->trigger_ID_list[DEFAULT_INDEX])) { // Delete the trigger ID list for this constant set tman_delete(rcg_node->trigger_ID_list[DEFAULT_INDEX]); // Remove the constant node from the expression list remove_constant_node_from_sig(rcg_node, DEFAULT_INDEX); } // Check whether the constant set for the expression signature is empty. // If yes, then delete the expression signature . del_expr_sig_when_const_set_is_empty(rcg_node, DEFAULT_INDEX); /* If the rcg node is for an INSERT/UPDATE trigger, then we have to delete all the data structures from the UPDATE branch.. */ if( rcg_node->opcode == TM_INSERT_UPDATE ) { delete_trigger_ID_node(rcg_node, INS_UPD_INDEX); if (List_isEmpty(rcg_node->trigger_ID_list[INS_UPD_INDEX])) { // Delete the trigger ID list for this constant set tman_delete(rcg_node->trigger_ID_list[INS_UPD_INDEX]); // Remove the constant node from the expression list remove_constant_node_from_sig(rcg_node, INS_UPD_INDEX); } // Check whether the constant set for the expression signature is empty. // If yes, then delete the expression signature . del_expr_sig_when_const_set_is_empty(rcg_node, INS_UPD_INDEX); } rcg_node = (RCG_node *)List_getNext(&cursor); } // Delete the Gator network for this trigger tman_delete(arg->gator); // Delete the RCG network for this trigger tman_delete(arg->rule_condition_graph); // Delete the create trigger data structure for this trigger // This deletes the actual syntax trees when the trigger was first created tman_delete(arg); return TMAN_OK; }