Changeset: 6a8da8246b43 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=6a8da8246b43
Modified Files:
monetdb5/optimizer/opt_projectionpath.c
Branch: default
Log Message:
Prepare for improved quadratic search
diffs (229 lines):
diff --git a/monetdb5/optimizer/opt_projectionpath.c
b/monetdb5/optimizer/opt_projectionpath.c
--- a/monetdb5/optimizer/opt_projectionpath.c
+++ b/monetdb5/optimizer/opt_projectionpath.c
@@ -9,7 +9,6 @@
/* author: M Kersten
* Post-optimization of projection lists.
* The algorithm is quadratic in the number of paths considered.
- * This should be massaged out with a skip list structure.
*/
#include "monetdb_config.h"
#include "opt_projectionpath.h"
@@ -17,42 +16,60 @@
//#undef OPTDEBUGprojectionpath
//#define OPTDEBUGprojectionpath if(1)
-/* locate common prefixes */
+/* locate common prefixes in projection lists */
static int
OPTprojectionPrefix(Client cntxt, MalBlkPtr mb, int prefixlength)
{
- int i, j, jj, k, match, actions=0;
- InstrPtr p,q,r,*old;
- int limit;
+ int i, j, k, match, actions=0;
+ InstrPtr p,q,r,*old, *projections;
+ int limit, ptop = 0, pidx=0 ;
+
+ projections = (InstrPtr *) GDKzalloc(sizeof(InstrPtr) * mb->stop);
+ if( projections == 0)
+ return 0;
old= mb->stmt;
limit= mb->stop;
- if ( newMalBlkStmt(mb,mb->ssize) < 0)
+ if ( newMalBlkStmt(mb,mb->ssize) < 0){
+ GDKfree(projections);
return 0;
- OPTDEBUGprojectionpath
- mnstr_printf(cntxt->fdout,"#projectionpath find common prefix
prefixlength %d \n", prefixlength);
+ }
+ // Collect all candidate projections
for( i = 0; i < limit; i++){
- match = 0;
p= old[i];
assert(p);
- if ( getFunctionId(p) != projectionpathRef || p->argc - p->retc
< prefixlength) {
+ if ( getFunctionId(p) != projectionpathRef || p->argc <
prefixlength) {
pushInstruction(mb,p);
continue;
}
+ projections[ptop++] = p;
+ }
+ OPTDEBUGprojectionpath
+ mnstr_printf(cntxt->fdout,"#projectionpath find common prefix
prefixlength %d candidates %d \n", prefixlength, ptop);
+
+ for( i = 0; i < limit; i++){
+ p= old[i];
+ assert(p);
+ if ( getFunctionId(p) != projectionpathRef || p->argc <
prefixlength) {
+ pushInstruction(mb,p);
+ continue;
+ }
+ (void)pidx++; // next entry in candidate list
/* we fixed a projection path of the target prefixlength
* Search now the remainder for at least one case where it
* has a common prefix of prefixlength
*/
- for( j= i+1; j < limit; j++) {
+ for(match = 0, j= i+1; j < limit; j++) {
q= old[j];
- if ( getFunctionId(q) != projectionpathRef || q->argc -
q->retc < prefixlength)
+ if ( getFunctionId(q) != projectionpathRef || q->argc <
prefixlength)
continue;
- for( match =0, k = q->retc; k < q->retc +
prefixlength; k++)
+ for( match =0, k = q->retc; k < prefixlength; k++)
match += getArg(q,k) == getArg(p,k);
- if ( match == prefixlength )
+ if ( match == prefixlength - q->retc )
break;
+ match = 0;
}
- if ( match == prefixlength ){
+ if ( match && match == prefixlength - q->retc ){
/* at least one instruction has been found.
* Inject the prefex projection path and replace all
use cases
*/
@@ -60,26 +77,11 @@ OPTprojectionPrefix(Client cntxt, MalBlk
mnstr_printf(cntxt->fdout,"#projectionpath
found common prefix prefixlength %d \n", match);
printInstruction(cntxt->fdout,mb, 0, p,
LIST_MAL_ALL);
}
+ /* create the factored out prefix projection */
r = copyInstruction(p);
- r->argc= r->retc + prefixlength;
+ r->argc = prefixlength;
getArg(r,0) = newTmpVariable(mb, newBatType( TYPE_oid,
getColumnType(getArgType(mb,r,r->argc-1))));
setVarUDFtype(mb, getArg(r,0));
- if ( r->argc == 3)
- setFunctionId(r, projectionRef);
- /* First check if we already have this operation then
an alias is sufficient */
- for( jj= i-1; jj > 0; jj--) {
- q= old[jj];
- if ( getFunctionId(q) != getFunctionId(r) ||
q->argc != r->argc)
- continue;
- for( match =0, k = q->retc; k < q->argc; k++)
- match += getArg(q,k) == getArg(r,k);
- if ( match == q->argc - q->retc){
- clrFunction(r);
- r->argc = r->retc +1;
- getArg(r,r->retc) = getArg(q,0);
- break;
- }
- }
pushInstruction(mb,r);
OPTDEBUGprojectionpath {
mnstr_printf(cntxt->fdout,"#projectionpath
prefix instruction\n");
@@ -89,26 +91,24 @@ OPTprojectionPrefix(Client cntxt, MalBlk
/* patch all instructions with same prefix. */
for( ; j < limit; j++) {
q= old[j];
- if ( getFunctionId(q) != projectionpathRef ||
q->argc - q->retc < prefixlength)
+ if ( getFunctionId(q) != projectionpathRef ||
q->argc < prefixlength)
continue;
- for( match =0, k = q->retc; k < q->retc +
prefixlength; k++)
- match += getArg(q,k) == getArg(p,k);
- if ( match == prefixlength ){
+ for( match =0, k = r->retc; k < r->argc; k++)
+ match += getArg(q,k) == getArg(r,k);
+ if (match && match == prefixlength - r->retc ){
actions++;
OPTDEBUGprojectionpath {
mnstr_printf(cntxt->fdout,"#projectionpath before:");
printInstruction(cntxt->fdout,mb, 0, q, LIST_MAL_ALL);
}
- if( prefixlength == q->argc - q->retc){
+ if( q->argc == r->argc ){
clrFunction(q);
getArg(q,q->retc) = getArg(r,0);
q->argc = q->retc + 1;
} else {
getArg(q,q->retc) = getArg(r,0);
- for( k= 1; k < prefixlength;
k++)
+ for( k= q->retc +1 ; k <
prefixlength; k++)
delArgument(q, q->retc
+ 1);
- if ( q->argc == 3)
- setFunctionId(q,
projectionRef);
}
OPTDEBUGprojectionpath {
mnstr_printf(cntxt->fdout,"#projectionpath after :");
@@ -116,25 +116,43 @@ OPTprojectionPrefix(Client cntxt, MalBlk
}
}
}
- /* patch instruction p */
- if( prefixlength == p->argc - p->retc){
+ /* patch instruction p by deletion of common prefix */
+ if( r->argc == p->argc ){
clrFunction(p);
getArg(p,p->retc) = getArg(r,0);
p->argc = p->retc + 1;
} else {
getArg(p,p->retc) = getArg(r,0);
- for( k= 1; k < prefixlength; k++)
- delArgument(q, q->retc + 1);
- if ( p->argc == 3)
- setFunctionId(p, projectionRef);
+ for( k= p->retc + 1; k < prefixlength; k++)
+ delArgument(p, p->retc + 1);
}
+ /* Finally check if we already have this prefix
operation then an alias is sufficient
+ for( jj= i-1; jj > 0; jj--) {
+ q= old[jj];
+ if ( getFunctionId(q) != getFunctionId(r) ||
q->argc != r->argc)
+ continue;
+ for( match =0, k = q->retc; k < q->argc; k++)
+ match += getArg(q,k) == getArg(r,k);
+ if ( match && match == q->argc - q->retc){
+ clrFunction(r);
+ r->argc = r->retc +1;
+ getArg(r,r->retc) = getArg(q,0);
+ break;
+ }
+ }
+ */
+
OPTDEBUGprojectionpath
printInstruction(cntxt->fdout,mb, 0, p,
LIST_MAL_ALL);
}
pushInstruction(mb,p);
}
- OPTDEBUGprojectionpath
+ OPTDEBUGprojectionpath {
+ chkProgram(cntxt->fdout, cntxt->nspace, mb);
mnstr_printf(cntxt->fdout,"#projectionpath prefix actions
%d\n",actions);
+ if(actions) printFunction(cntxt->fdout,mb, 0, LIST_MAL_ALL);
+ }
+ GDKfree(projections);
return actions;
}
@@ -166,7 +184,7 @@ OPTprojectionpathImplementation(Client c
/* beware, new variables and instructions are introduced */
pc= (int*) GDKzalloc(sizeof(int)* mb->vtop * 2); /* to find last
assignment */
varcnt= (int*) GDKzalloc(sizeof(int)* mb->vtop * 2);
- if (pc == NULL || varcnt == NULL){
+ if (pc == NULL || varcnt == NULL ){
if (pc ) GDKfree(pc);
if (varcnt ) GDKfree(varcnt);
return 0;
@@ -177,8 +195,8 @@ OPTprojectionpathImplementation(Client c
*/
for (i = 0; i<limit; i++){
p= old[i];
- for(j=p->retc; j<p->argc; j++)
- varcnt[getArg(p,j)]++;
+ for(j=p->retc; j<p->argc; j++)
+ varcnt[getArg(p,j)]++;
}
/* assume a single pass over the plan, and only consider projection
sequences
@@ -276,8 +294,7 @@ OPTprojectionpathImplementation(Client c
* There may be cases where there is a common prefix used multiple
times.
* There are located and removed in a few scans over the plan
*/
- if(0)
- for( ; maxprefixlength >= 2; maxprefixlength--)
+ for( ; maxprefixlength > 2; maxprefixlength--)
actions += OPTprojectionPrefix(cntxt, mb, maxprefixlength);
OPTDEBUGprojectionpath {
mnstr_printf(cntxt->fdout,"#projectionpath optimizer result
\n");
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list