/** * This is the main routine of "MonoCrosser", and implements a monotonic strategy on multiple curves. * Finds crossings between two sets of paths, yielding a CrossingSet. [0, a.size()) of the return correspond * to the sorted crossings of a with paths of b. The rest of the return, [a.size(), a.size() + b.size()], * corresponds to the sorted crossings of b with paths of a. * * This function does two sweeps, one on the bounds of each path, and after that cull, one on the curves within. * This leads to a certain amount of code complexity, however, most of that is factored into the above functions */ CrossingSet MonoCrosser::crossings(std::vector<Path> const &a, std::vector<Path> const &b) { if(b.empty()) return CrossingSet(a.size(), Crossings()); CrossingSet results(a.size() + b.size(), Crossings()); if(a.empty()) return results; std::vector<std::vector<double> > splits_a = paths_mono_splits(a), splits_b = paths_mono_splits(b); std::vector<std::vector<Rect> > bounds_a = split_bounds(a, splits_a), bounds_b = split_bounds(b, splits_b); std::vector<Rect> bounds_a_union, bounds_b_union; for(unsigned i = 0; i < bounds_a.size(); i++) bounds_a_union.push_back(union_list(bounds_a[i])); for(unsigned i = 0; i < bounds_b.size(); i++) bounds_b_union.push_back(union_list(bounds_b[i])); std::vector<std::vector<unsigned> > cull = sweep_bounds(bounds_a_union, bounds_b_union); Crossings n; for(unsigned i = 0; i < cull.size(); i++) { for(unsigned jx = 0; jx < cull[i].size(); jx++) { unsigned j = cull[i][jx]; unsigned jc = j + a.size(); Crossings res; //Sweep of the monotonic portions std::vector<std::vector<unsigned> > cull2 = sweep_bounds(bounds_a[i], bounds_b[j]); for(unsigned k = 0; k < cull2.size(); k++) { for(unsigned lx = 0; lx < cull2[k].size(); lx++) { unsigned l = cull2[k][lx]; mono_pair(a[i], splits_a[i][k-1], splits_a[i][k], b[j], splits_b[j][l-1], splits_b[j][l], res, .1); } } for(unsigned k = 0; k < res.size(); k++) { res[k].a = i; res[k].b = jc; } merge_crossings(results[i], res, i); merge_crossings(results[i], res, jc); } } return results; }
bool my_walker(Node *node, context_walker_set_constraint *context){ if (node == NULL) return false; /* elog(LOG,"tag : %d\n",nodeTag(node)); */ if(IsA(node,BoolExpr)){ BoolExpr * bExpr =(BoolExpr *) node; bool retour = false; List * l_true_save = NULL; List * l_false_save = NULL; List * l_true = NULL; List * l_false = NULL; int nb_arg = bExpr->args->length; switch(bExpr->boolop){ case NOT_EXPR: /*(Unicité des valeur) Setisation sur le true*/ /*Pre Traitement*/ l_true_save = context->list_of_not_null_to_be_true; l_false_save = context->list_of_not_null_to_be_false; context->list_of_not_null_to_be_true = NULL; context->list_of_not_null_to_be_false = NULL; /*Traitement*/ retour = expression_tree_walker(node, my_walker, (void *) context); /*Post Traitement*/ /* elog(LOG,"\n List_false_before : %s\n",nodeToString(context->list_of_not_null_to_be_false)); */ /* elog(LOG,"\n List_true_before : %s\n",nodeToString(context->list_of_not_null_to_be_true)); */ l_true = context->list_of_not_null_to_be_true; l_false = context->list_of_not_null_to_be_false; context->list_of_not_null_to_be_true = list_concat(l_true_save,l_false); context->list_of_not_null_to_be_false = list_concat(l_false_save,l_true); /* elog(LOG,"\n List_false : %s\n",nodeToString(context->list_of_not_null_to_be_false)); */ /* elog(LOG,"\n List_true : %s\n",nodeToString(context->list_of_not_null_to_be_true)); */ return retour; break; case AND_EXPR: /*(Unicité des valeur) Setisation sur le true*/ /*Pre Traitement*/ l_true_save = context->list_of_not_null_to_be_true; l_false_save = context->list_of_not_null_to_be_false; context->list_of_not_null_to_be_true = NULL; context->list_of_not_null_to_be_false = NULL; /*Traitement*/ retour = expression_tree_walker(node, my_walker, (void *) context); /*Post traitement*/ /* elog(LOG,"\n List_false_before : %s\n",nodeToString(context->list_of_not_null_to_be_false)); */ /* elog(LOG,"\n List_true_before : %s\n",nodeToString(context->list_of_not_null_to_be_true)); */ l_true = union_list(context->list_of_not_null_to_be_true); l_false = inter_list(context->list_of_not_null_to_be_false,nb_arg); context->list_list_true = lappend(context->list_list_true,l_true); context->list_list_false = lappend(context->list_list_false,l_false); context->list_of_not_null_to_be_true = list_concat(l_true_save,l_true); context->list_of_not_null_to_be_false = list_concat(l_false_save,l_false); /* elog(LOG,"\n nb_arg : %d\n",nb_arg); */ /* elog(LOG,"\n List_false : %s\n",nodeToString(context->list_of_not_null_to_be_false)); */ /* elog(LOG,"\n List_true : %s\n",nodeToString(context->list_of_not_null_to_be_true)); */ return retour; break; case OR_EXPR: /*(Unicité des valeur) Setisation sur le true*/ /*Pre Traitement*/ l_true_save = context->list_of_not_null_to_be_true; l_false_save = context->list_of_not_null_to_be_false; context->list_of_not_null_to_be_true = NULL; context->list_of_not_null_to_be_false = NULL; /*Traitement*/ retour = expression_tree_walker(node, my_walker, (void *) context); /*Post traitement*/ /* elog(LOG,"\n List_false_before : %s\n",nodeToString(context->list_of_not_null_to_be_false)); */ /* elog(LOG,"\n List_true_before : %s\n",nodeToString(context->list_of_not_null_to_be_true)); */ l_true = inter_list(context->list_of_not_null_to_be_true,nb_arg); l_false = union_list(context->list_of_not_null_to_be_false); context->list_list_true = lappend(context->list_list_true,l_true); context->list_list_false = lappend(context->list_list_false,l_false); context->list_of_not_null_to_be_true = list_concat(l_true_save,l_true); context->list_of_not_null_to_be_false = list_concat(l_false_save,l_false); /* elog(LOG,"\n nb_arg : %d\n",nb_arg); */ /* elog(LOG,"\n List_false : %s\n",nodeToString(context->list_of_not_null_to_be_false)); */ /* elog(LOG,"\n List_true : %s\n",nodeToString(context->list_of_not_null_to_be_true)); */ return retour; break; } } if(context->ready && IsA(node,Var)){ /* elog(LOG," \n HERE1 \n"); */ Var * v = getTrueVar(context->current_trueVar,(Var *)node); /* elog(LOG," \n HERE2 \n"); */ if(!isInListTrueVar(context->list_of_not_null_in_op,v)){ context->list_of_not_null_in_op = lappend(context->list_of_not_null_in_op,v); } return expression_tree_walker(node, my_walker, (void *) context); } if(IsA(node,OpExpr)){ OpExpr * oExpr = (OpExpr *)node; if(oExpr->opno == 518 /*<>*/){ context->ready = true; context->list_of_not_null_in_op = NULL; bool retour = expression_tree_walker(node, my_walker, (void *) context); context->list_of_not_null_to_be_true = list_concat(context->list_of_not_null_to_be_true,context->list_of_not_null_in_op); return retour; } else{ return expression_tree_walker(node, my_walker, (void *) context); } /* elog(LOG,"\n List_op : %s\n",nodeToString(context->list_of_not_null_in_op)); */ } if(IsA(node,Query)){ Query * q = (Query *) node; /*Prétraitement*/ List * save_current_trueVar = context->current_trueVar; context->current_trueVar = NULL; context->current_trueVar = lappend(context->current_trueVar,save_current_trueVar); /*Traitement*/ /*Create trueVars and not_null schema*/ bool result = expression_tree_walker((Node *)q->rtable, my_walker, (void *) context); /* elog(LOG,"\n TRUE ATT :%s\n",nodeToString(context->trueVars)); */ context->trueVars = lappend(context->trueVars,context->current_trueVar); /* elog(LOG,"\nTRUE ATT :%s \n",nodeToString(context->trueVars)); */ /*Propagate*/ result = expression_tree_walker((Node *)q->jointree, my_walker, (void *) context) | result; /* elog(LOG,"\n LIST_LIST_TRUE :%s\n",nodeToString(context->list_list_true)); */ /* elog(LOG,"\n LIST_LIST_FALSE :%s\n",nodeToString(context->list_list_false)); */ /*Post Traitement*/ context->current_trueVar = save_current_trueVar; return result; } if(IsA(node,RangeTblEntry)){ RangeTblEntry * rte = (RangeTblEntry *)node; Oid relid= rte->relid; int number_col = get_relnatts(relid); AttrNumber i = 0; List * relation = NULL; for(i=1;i<=number_col;i++){ /*Create True_var*/ Var * v = makeNode(Var); v->varattno = i; /* v->varattno = context->current_varattno; */ v->vartype = relid; relation = lappend(relation,v); /*Add to not_null if needed*/ if(get_pg_att_not_null(relid,i)){ context->list_of_not_null_att_schem = lappend(context->list_of_not_null_att_schem,v); } } context->current_trueVar = lappend(context->current_trueVar,relation); /* elog(LOG,"\n TEST: %s \n",nodeToString(context->current_trueVar)); */ return false; } return expression_tree_walker(node, my_walker, (void *) context); }