Changeset: 7fc3f0db80f5 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=7fc3f0db80f5
Modified Files:
monetdb5/modules/mal/manifold.c
monetdb5/modules/mal/manifold.h
Branch: default
Log Message:
Fixing the way string manifolds are handled.
[check for leakage to be done]
diffs (242 lines):
diff --git a/monetdb5/modules/mal/manifold.c b/monetdb5/modules/mal/manifold.c
--- a/monetdb5/modules/mal/manifold.c
+++ b/monetdb5/modules/mal/manifold.c
@@ -46,6 +46,7 @@ typedef struct{
int type;
BATiter bi;
BUN o;
+ BUN q;
str *s;
} MULTIarg;
@@ -59,12 +60,15 @@ typedef struct{
} MULTItask;
+// Loop through the first BAT
+// keep the last error message received
#define ManifoldLoop(Type, ...) \
-{ Type *v = (Type*) mut->args[0].first;\
- for( ; p< q && msg == MAL_SUCCEED; p += mut->args[mut->fvar].size){\
+{ Type *v = (Type*) mut->args[0].first; \
+ for( ; p< q ; p += mut->args[mut->fvar].size){\
msg = (*mut->pci->fcn)(v, __VA_ARGS__);\
+ if( lastmsg) GDKfree(msg); lastmsg = msg;\
for( i = mut->fvar; i<= mut->lvar; i++)\
- if( mut->args[i].type < TYPE_str){\
+ if( ATOMstorage(mut->args[i].type) != TYPE_str){\
args[i] += mut->args[i].size;\
} else {\
mut->args[i].o++;\
@@ -75,6 +79,7 @@ typedef struct{
}\
}
+// The target BAT tail type determines the result variable
#define Manifoldbody(...) \
switch(ATOMstorage(mut->args[0].b->ttype)){\
case TYPE_bit: ManifoldLoop(bit,__VA_ARGS__); break;\
@@ -85,19 +90,18 @@ case TYPE_oid: ManifoldLoop(oid,__VA_ARG
case TYPE_flt: ManifoldLoop(flt,__VA_ARGS__); break;\
case TYPE_dbl: ManifoldLoop(dbl,__VA_ARGS__); break;\
case TYPE_str: { \
- for( ; p< q && msg == MAL_SUCCEED; p += mut->args[mut->fvar].size){\
- h = BUNhead(mut->args[0].bi, mut->args[0].o);\
+ for( ; p< q ; p += mut->args[mut->fvar].size){\
msg = (*mut->pci->fcn)(&y, __VA_ARGS__);\
- bunfastins(mut->args[0].b, (void*) h, (void*) y);\
+ bunfastins(mut->args[0].b, (void*) 0, (void*) y);\
+ if( lastmsg) GDKfree(msg); lastmsg = msg; \
for( i = mut->fvar; i<= mut->lvar; i++)\
- if( mut->args[i].type < TYPE_str){\
+ if( ATOMstorage(mut->args[i].type) != TYPE_str){\
args[i] += mut->args[i].size;\
} else {\
mut->args[i].s = (str*) BUNtail(mut->args[i].bi,
mut->args[i].o);\
args[i] = (void*) & mut->args[i].s; \
mut->args[i].o++;\
}\
- mut->args[0].o++;\
}\
break;}\
default:\
@@ -105,21 +109,23 @@ default:\
}
// single argument is preparatory step for GDK_mapreduce
+// Only the last error message is returned, the value of
+// an erroneous call depends on the operator itself.
static str
-MANIFOLDjob(const MULTItask *mut)
+MANIFOLDjob(MULTItask *mut)
{ int i;
char *p, *q;
char **args;
- str y, msg= MAL_SUCCEED;
- ptr h;
+ str y, lastmsg = MAL_SUCCEED, msg= MAL_SUCCEED;
args = (char**) GDKzalloc(sizeof(char*) * mut->pci->argc);
if( args == NULL)
throw(MAL,"mal.manifold",MAL_MALLOC_FAIL);
+ // the mod.fcn arguments are ignored from the call
for( i = mut->pci->retc+2; i< mut->pci->argc; i++)
if ( mut->args[i].b ){
- if (mut->args[i].type < TYPE_str)
+ if ( ATOMstorage(mut->args[i].type) != TYPE_str)
args[i] = (char*) mut->args[i].first;
else {
mut->args[i].s = (str*) BUNtail(mut->args[i].bi,
mut->args[i].o);
@@ -128,8 +134,12 @@ MANIFOLDjob(const MULTItask *mut)
} else
args[i] = (char*) getArgReference(mut->stk,mut->pci,i);
+#ifdef _DEBUG_MANIFOLD_
+ mnstr_printf(mut->cntxt->fdout,"#MANIFOLDjob fvar %d lvar %d type
%d\n",mut->fvar,mut->lvar, ATOMstorage(mut->args[mut->fvar].b->ttype));
+#endif
p = (char*) mut->args[mut->fvar].first;
q = (char*) mut->args[mut->fvar].last;
+ // use limited argument list expansion.
switch(mut->pci->argc){
case 4: Manifoldbody(args[3]); break;
case 5: Manifoldbody(args[3],args[4]); break;
@@ -141,20 +151,21 @@ MANIFOLDjob(const MULTItask *mut)
}
bunins_failed:
GDKfree(args);
- return msg;
+ return lastmsg;
}
/* The manifold optimizer should check for the possibility
* to use this implementation instead of the MAL loop.
*/
MALfcn
-MANIFOLDtypecheck(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci){
+MANIFOLDtypecheck(Client cntxt, MalBlkPtr mb, InstrPtr pci){
int i, k, tpe= 0;
InstrPtr q=0;
MalBlkPtr nmb;
MALfcn fcn;
- (void) stk;
+ if ( pci > 8) // limitation on MANIFOLDjob
+ return NULL;
// We need a private MAL context to resolve the function call
nmb = newMalBlk(MAXVARS, STMT_INCREMENT);
if( nmb == NULL)
@@ -183,18 +194,19 @@ MANIFOLDtypecheck(Client cntxt, MalBlkPt
#ifdef _DEBUG_MANIFOLD_
mnstr_printf(cntxt->fdout,"#MANIFOLD operation\n");
- printInstruction(cntxt->fdout,mb,stk,pci,LIST_MAL_ALL);
- printInstruction(cntxt->fdout,nmb,stk,q,LIST_MAL_ALL);
+ printInstruction(cntxt->fdout,mb,0,pci,LIST_MAL_ALL);
+ printInstruction(cntxt->fdout,nmb,0,q,LIST_MAL_ALL);
#endif
// Localize the underlying opertor
typeChecker(cntxt->fdout, cntxt->nspace, nmb, q, TRUE);
-#ifdef _DEBUG_MANIFOLD_
- printInstruction(cntxt->fdout,nmb,stk,q,LIST_MAL_ALL);
-#endif
if ( nmb->errors || q->fcn == NULL || q->token != CMDcall)
fcn = NULL;
else
fcn = q->fcn;
+#ifdef _DEBUG_MANIFOLD_
+ mnstr_printf(cntxt->fdout,"success? %s\n",(fcn == NULL? "no":"yes"));
+ printInstruction(cntxt->fdout,nmb,0,q,LIST_MAL_ALL);
+#endif
freeMalBlk(nmb);
return fcn;
}
@@ -208,7 +220,7 @@ MANIFOLDevaluate(Client cntxt, MalBlkPtr
str msg = MAL_SUCCEED;
MALfcn fcn;
- fcn= MANIFOLDtypecheck(cntxt,mb,stk,pci);
+ fcn= MANIFOLDtypecheck(cntxt,mb,pci);
if( fcn == NULL)
throw(MAL, "mal.manifold", "Illegal manifold function call");
@@ -232,7 +244,7 @@ MANIFOLDevaluate(Client cntxt, MalBlkPtr
msg = createException(MAL,"mal.manifold",
MAL_MALLOC_FAIL);
goto wrapup;
}
- mat[i].type = tpe = mat[i].b->ttype;
+ mat[i].type = tpe = getTailType(getArgType(mb,pci,i));
if ( mut.fvar == 0){
mut.fvar = i;
cnt = BATcount(mat[i].b);
@@ -242,7 +254,7 @@ MANIFOLDevaluate(Client cntxt, MalBlkPtr
goto wrapup;
}
mut.lvar = i;
- if ( tpe == TYPE_str)
+ if ( ATOMstorage(tpe) == TYPE_str)
mat[i].size = Tsize(mat[i].b);
else
mat[i].size = BATatoms[ ATOMstorage(tpe)].size;
@@ -250,6 +262,7 @@ MANIFOLDevaluate(Client cntxt, MalBlkPtr
mat[i].last = (void*) Tloc(mat[i].b,
BUNlast(mat[i].b));
mat[i].bi = bat_iterator(mat[i].b);
mat[i].o = BUNfirst(mat[i].b);
+ mat[i].q = BUNlast(mat[i].b);
} else {
mat[i].last = mat[i].first = (void*)
getArgReference(stk,pci,i);
}
@@ -261,29 +274,32 @@ MANIFOLDevaluate(Client cntxt, MalBlkPtr
msg= createException(MAL,"mal.manifold",MAL_MALLOC_FAIL);
goto wrapup;
}
+ BATseqbase(mat[0].b, 0);
+ mat[0].b->hsorted= 0;
+ mat[0].b->hrevsorted= 0;
+ mat[0].b->T->nonil=0;
+ mat[0].b->tsorted=0;
+ mat[0].b->trevsorted=0;
mat[0].bi = bat_iterator(mat[0].b);
mat[0].first = (void *) Tloc(mat[0].b, BUNfirst(mat[0].b));
mat[0].last = (void *) Tloc(mat[0].b, BUNlast(mat[0].b));
- BATseqbase(mat[0].b, mat[mut.fvar].b->hseqbase);
- if( ATOMstorage(mat[0].b->ttype) != TYPE_str)
- BATsetcount(mat[0].b,cnt);
- mat[0].b->hsorted= mat[mut.fvar].b->hsorted;
- mat[0].b->hrevsorted= mat[mut.fvar].b->hrevsorted;
- mat[0].b->tsorted=0;
- mat[0].b->trevsorted=0;
- pci->fcn = fcn;
-
// Then iterator over all BATs
if( mut.fvar ==0){
msg= createException(MAL,"mal.manifold","At least one column
required");
goto wrapup;
}
+ mut.pci = copyInstruction(pci);
+ mut.pci->fcn = fcn;
msg = MANIFOLDjob(&mut);
+ freeInstruction(mut.pci);
// consolidate the properties
+ if ( ATOMstorage(mat[0].b->ttype) != TYPE_str)
+ BATsetcount(mat[0].b,cnt);
+ BATsettrivprop(mat[0].b);
BATderiveProps(mat[0].b, TRUE);
BBPkeepref(*(int*) getArgReference(stk,pci,0)=mat[0].b->batCacheid);
wrapup:
diff --git a/monetdb5/modules/mal/manifold.h b/monetdb5/modules/mal/manifold.h
--- a/monetdb5/modules/mal/manifold.h
+++ b/monetdb5/modules/mal/manifold.h
@@ -42,7 +42,7 @@
#define manifoldplex_export extern
#endif
-manifoldplex_export MALfcn MANIFOLDtypecheck(Client cntxt, MalBlkPtr mb,
MalStkPtr stk, InstrPtr pci);
+manifoldplex_export MALfcn MANIFOLDtypecheck(Client cntxt, MalBlkPtr mb,
InstrPtr pci);
manifoldplex_export str MANIFOLDevaluate(Client cntxt, MalBlkPtr mb, MalStkPtr
stk, InstrPtr pci);
manifoldplex_export str MANIFOLDremapMultiplex(Client cntxt, MalBlkPtr mb,
MalStkPtr stk, InstrPtr p);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list