Changeset: 2a66752740e2 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=2a66752740e2
Modified Files:
        MonetDB5/src/mal/mal_interpreter.mx
        sql/src/common/sql_types.mx
Branch: Oct2010
Log Message:

make sure we use digits from the input type for substring operations

the dataflow interpreter spends lots of time in DFLOWeligible. This
is mostly caused by the variable dependency checking (which are nested loops).
For now this is reduced by keeping the initial assignment statement.
Still src/tests/rdf q3_v.sql runs in 3.5 s, while without dataflow in .5sec.


diffs (198 lines):

diff -r 24132d3b2ff1 -r 2a66752740e2 MonetDB5/src/mal/mal_interpreter.mx
--- a/MonetDB5/src/mal/mal_interpreter.mx       Wed Oct 06 11:15:27 2010 +0200
+++ b/MonetDB5/src/mal/mal_interpreter.mx       Wed Oct 06 16:26:16 2010 +0200
@@ -595,9 +595,10 @@
        MalBlkPtr mb;           /* carry the context */
        MalStkPtr stk;
        int start, stop;        /* guarded block under consideration*/
-       char *status;   /* statements can be blocked on other statements */
+       char *status;           /* statements can be blocked on other 
statements */
        char *blocked;          /* blocked, should be created first */
-       int *inuse;                     /* inuse in parallel threads reference 
count */
+       int *assign;            /* first assignment of variable */ 
+       int *inuse;             /* inuse in parallel threads reference count */
        queue *done;            /* work finished */
        queue *todo;            /* pending actions for this client */
        int    nway;            /* number of workers */
@@ -1170,7 +1171,6 @@
 DFLOWinit(DataFlow flow, FlowStep fs)
 {
        int i, n;
-       char *assign= (char*) GDKzalloc(sizeof(char) * flow->mb->vtop);
 
        PARDEBUG
                printf("Initialize dflow block\n");
@@ -1191,8 +1191,11 @@
                for (j=0; j<p->argc; j++){
                        a = getArg(p, j);
 
-                       if (j<p->retc && assign[a] == 0 && flow->inuse[a] == 0) 
{
-                               assign[a] = i;
+                       if (j<p->retc && flow->assign[a] != 0) 
+                               assert(0);
+
+                       if (j<p->retc && flow->assign[a] == 0 && flow->inuse[a] 
== 0) {
+                               flow->assign[a] = i;
                                flow->blocked[a] = isNotUsedIn(p,p->retc,a)?1:0;
                        }
 
@@ -1205,13 +1208,12 @@
                flow->inuse[i] = 0;
        PARDEBUG
        for (i=0; i < flow->mb->vtop; i++) 
-       if ( flow->blocked[i] || flow->inuse[i] || assign[i] ){
+       if ( flow->blocked[i] || flow->inuse[i] || flow->assign[i] ){
                printf("%s %d %d [ %1d %2d ]\n", getVarName(flow->mb,i), 
                        getEndOfLife(flow->mb,i), i,
                        flow->blocked[i],
                        flow->inuse[i]);
        }
-       GDKfree(assign);
 }
 @-
 The liberal use of MAL to construct programs complicate proper dataflow
@@ -1237,28 +1239,29 @@
        (void) pc;
 
        for(j=0; j<p->argc && !blocked; j++) {
-               if ( j >= p->retc && flow->blocked[getArg(p,j)] )
+               int var = getArg(p,j);
+               if ( j >= p->retc && flow->blocked[var] )
                        blocked++;
-               if (j < p->retc && flow->inuse[getArg(p,j)] )
+               if (j < p->retc && flow->inuse[var] )
                        blocked++;
                else
-               if ( getEndOfLife(flow->mb,getArg(p,j))  == fs[i].pc ) {
+               if ( getEndOfLife(flow->mb,var)  == fs[i].pc ) {
                        /* make sure all instructions interested have already 
been executed */
                        /* and the eoscope variables are not used anymore */
 
-                       blocked += flow->inuse[getArg(p,j)] != 0;
+                       blocked += flow->inuse[var] != 0;
                        for ( k=0; k < i && !blocked; k++)
                        if (fs[k].status != DFLOWwrapup && fs[k].pc >= 0 ) /* 
pc = -1 could be the case before wrapup is set*/
-                               blocked += !isNotUsedIn(getInstrPtr(flow->mb, 
fs[k].pc), 0, getArg(p,j));
+                               blocked += !isNotUsedIn(getInstrPtr(flow->mb, 
fs[k].pc), 0, var);
                } else {
                        /* handle the dependencies sketched above */
                        /* search the statement that assigns a value to the 
argument or target */
                        /* it should have been finished already */
-                       for (l = i-1 ; l >= 0 && !blocked; l--)
+                       for (l = i-1 ; l >= flow->assign[var] && !blocked; l--)
                        if ( fs[l].status != DFLOWwrapup && fs[l].pc >= 0){
                                q= getInstrPtr(flow->mb, fs[l].pc);
                                for ( k=0; k < q->retc && !blocked; k++)
-                               if ( getArg(q,k) == getArg(p,j) )
+                               if ( getArg(q,k) == var )
                                        blocked = 1;
                        }
                }
@@ -1483,12 +1486,14 @@
 
        flow->status = (char*) GDKzalloc((stoppc-startpc+1));
        flow->blocked = (char*) GDKzalloc(sizeof(char)*mb->vtop);
+       flow->assign = (int*) GDKzalloc(sizeof(int)*mb->vtop);
        flow->inuse = (int*) GDKzalloc(sizeof(int)*mb->vtop);
        mal_unset_lock(mal_contextLock, "runMALdataflow");
 
        ret = DFLOWscheduler(flow);
        GDKfree(flow->status);
        GDKfree(flow->blocked);
+       GDKfree(flow->assign);
        GDKfree(flow->inuse);
        mal_set_lock(mal_contextLock, "runMALdataflow");
        flow->free = flows;
diff -r 24132d3b2ff1 -r 2a66752740e2 sql/src/common/sql_types.mx
--- a/sql/src/common/sql_types.mx       Wed Oct 06 11:15:27 2010 +0200
+++ b/sql/src/common/sql_types.mx       Wed Oct 06 16:26:16 2010 +0200
@@ -497,16 +497,16 @@
 }
 
 int
-is_subtype(sql_subtype *t1, sql_subtype *t2)
-/* returns true if t1 is a sub type of t2 */
+is_subtype(sql_subtype *sub, sql_subtype *super)
+/* returns true if sub is a sub type of super */
 {
-       if (!t1 || !t2)
+       if (!sub || !super)
                return 0;
-       if (t2->digits > 0 && t1->digits > t2->digits) 
+       if (super->digits > 0 && sub->digits > super->digits) 
                return 0;
        /* subtypes are only equal iff
           they map onto the same systemtype */
-       return (type_cmp(t1->type, t2->type) == 0);
+       return (type_cmp(sub->type, super->type) == 0);
 }
 
 char *
@@ -783,7 +783,7 @@
                if (strcmp(f->base.name, sqlfname) == 0) {
                        if (list_length(f->ops) == nrargs && is_subtype(tp, 
&((sql_arg *) f->ops->h->data)->type)) {
 
-                               unsigned int scale = 0;
+                               unsigned int scale = 0, digits;
                                sql_subfunc *fres = ZNEW(sql_subfunc);
 
                                sql_ref_init(&(fres->ref));
@@ -791,7 +791,10 @@
                                /* same scale as the input */
                                if (tp && tp->scale > scale)
                                        scale = tp->scale;
-                               sql_init_subtype(&fres->res, f->res.type, 
f->res.digits, scale);
+                               digits = f->res.digits;
+                               if (tp && f->fix_scale == INOUT)
+                                       digits = tp->digits;
+                               sql_init_subtype(&fres->res, f->res.type, 
digits, scale);
                                return fres;
                        }
                }
@@ -854,12 +857,13 @@
                        continue;
                if (strcmp(f->base.name, sqlfname) == 0) {
                        if (list_cmp(f->ops, ops, (fcmp) &arg_subtype_cmp) == 
0) {
-                               unsigned int scale = 0;
+                               unsigned int scale = 0, digits;
                                sql_subfunc *fres = ZNEW(sql_subfunc);
 
                                sql_ref_init(&(fres->ref));
                                fres->func = f;
                                /* fix the scale */
+                               digits = f->res.digits;
                                if (f->fix_scale > SCALE_NONE) {
                                        for (n = ops->h; n; n = n->next) {
                                                sql_subtype *a = n->data;
@@ -867,6 +871,8 @@
                                                /* same scale as the input */
                                                if (a && a->scale > scale)
                                                        scale = a->scale;
+                                               if (a && f->fix_scale == INOUT)
+                                                       digits = a->digits;
                                        }
                                } else if (f->res.scale) 
                                        scale = f->res.scale;
@@ -880,9 +886,9 @@
                                                        a = n->data;
                                                }
                                        }
-                                       sql_init_subtype(&fres->res, a->type, 
f->res.digits, scale);
+                                       sql_init_subtype(&fres->res, a->type, 
digits, scale);
                                } else {
-                                       sql_init_subtype(&fres->res, 
f->res.type, f->res.digits, scale);
+                                       sql_init_subtype(&fres->res, 
f->res.type, digits, scale);
                                }
                                return fres;
                        }
@@ -1627,8 +1633,8 @@
        for (t = strings; t < numerical; t++) {
                sql_create_func("locate", "str", "locate", *t, *t, INT, 
SCALE_NONE);
                sql_create_func3("locate", "str", "locate", *t, *t, INT, INT, 
SCALE_NONE);
-               sql_create_func("substring", "str", "substring", *t, INT, *t, 
SCALE_NONE);
-               sql_create_func3("substring", "str", "substring", *t, INT, INT, 
*t, SCALE_NONE);
+               sql_create_func("substring", "str", "substring", *t, INT, *t, 
INOUT);
+               sql_create_func3("substring", "str", "substring", *t, INT, INT, 
*t, INOUT);
                sql_create_func("like", "str", "like", *t, *t, BIT, SCALE_NONE);
                sql_create_func3("like", "str", "like", *t, *t, *t, BIT, 
SCALE_NONE);
                sql_create_func("ilike", "str", "ilike", *t, *t, BIT, 
SCALE_NONE);
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to