Changeset: e15b73313242 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=e15b73313242
Removed Files:
        monetdb5/modules/kernel/batifthen.c
        monetdb5/modules/kernel/batifthen.h
        monetdb5/modules/kernel/batifthen.mal
Modified Files:
        clients/Tests/exports.stable.out
        gdk/gdk.h
        gdk/gdk_calc.c
        monetdb5/modules/kernel/Makefile.ag
        monetdb5/modules/mal/batcalc.c
        monetdb5/modules/mal/batcalc.mal
        monetdb5/modules/mal/batcalc.mal.sh
        monetdb5/modules/mal/mal_init.mal
Branch: default
Log Message:

Moved batcalc.ifthen(else) implementation into gdk_calc.


diffs (truncated from 1487 to 300 lines):

diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out
--- a/clients/Tests/exports.stable.out
+++ b/clients/Tests/exports.stable.out
@@ -64,6 +64,10 @@ BAT *BATcalcge(BAT *b1, BAT *b2);
 BAT *BATcalcgecst(BAT *b, const ValRecord *v);
 BAT *BATcalcgt(BAT *b1, BAT *b2);
 BAT *BATcalcgtcst(BAT *b, const ValRecord *v);
+BAT *BATcalcifthencstelse(BAT *b, const ValRecord *c1, BAT *b2);
+BAT *BATcalcifthencstelsecst(BAT *b, const ValRecord *c1, const ValRecord *c2);
+BAT *BATcalcifthenelse(BAT *b, BAT *b1, BAT *b2);
+BAT *BATcalcifthenelsecst(BAT *b, BAT *b1, const ValRecord *c2);
 BAT *BATcalcincr(BAT *b, int accum, int abort_on_error);
 BAT *BATcalcisnil(BAT *b);
 BAT *BATcalciszero(BAT *b);
@@ -1322,28 +1326,7 @@ str CMDgetPageSize(int *ret);
 str CMDgetSystemTime(lng *ret);
 str CMDgetTrace(int *res, str *ev);
 str CMDgetUserTime(lng *ret);
-str CMDifThen(int *ret, int *bid, int *tid);
-str CMDifThenCst_bit(int *ret, int *bid, ptr *tid);
-str CMDifThenCst_bte(int *ret, int *bid, ptr *tid);
-str CMDifThenCst_dbl(int *ret, int *bid, ptr *tid);
-str CMDifThenCst_flt(int *ret, int *bid, ptr *tid);
-str CMDifThenCst_int(int *ret, int *bid, ptr *tid);
-str CMDifThenCst_lng(int *ret, int *bid, ptr *tid);
-str CMDifThenCst_oid(int *ret, int *bid, ptr *tid);
-str CMDifThenCst_sht(int *ret, int *bid, ptr *tid);
-str CMDifThenCst_str(int *ret, int *bid, ptr *tid);
-str CMDifThenElse(int *ret, int *bid, int *tid, int *eid);
-str CMDifThenElseCst1(int *ret, int *bid, ptr *val, int *eid);
-str CMDifThenElseCst2(int *ret, int *bid, int *tid, ptr *val);
-str CMDifThenElseCst_bit(int *ret, int *bid, ptr *tid, ptr *eid);
-str CMDifThenElseCst_bte(int *ret, int *bid, ptr *tid, ptr *eid);
-str CMDifThenElseCst_dbl(int *ret, int *bid, ptr *tid, ptr *eid);
-str CMDifThenElseCst_flt(int *ret, int *bid, ptr *tid, ptr *eid);
-str CMDifThenElseCst_int(int *ret, int *bid, ptr *tid, ptr *eid);
-str CMDifThenElseCst_lng(int *ret, int *bid, ptr *tid, ptr *eid);
-str CMDifThenElseCst_oid(int *ret, int *bid, ptr *tid, ptr *eid);
-str CMDifThenElseCst_sht(int *ret, int *bid, ptr *tid, ptr *eid);
-str CMDifThenElseCst_str(int *ret, int *bid, ptr *tid, ptr *eid);
+str CMDifthen(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
 str CMDincludeFile(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
 str CMDmodules(int *bid);
 str CMDnoopProfiler(int *res);
diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -3244,6 +3244,10 @@ gdk_export BAT *BATcalcbetweencstcst(BAT
 gdk_export BAT *BATcalcbetweenbatcst(BAT *b, BAT *lo, const ValRecord *hi);
 gdk_export BAT *BATcalcbetweencstbat(BAT *b, const ValRecord *lo, BAT *hi);
 gdk_export int VARcalcbetween(ValPtr ret, const ValRecord *v, const ValRecord 
*lo, const ValRecord *hi);
+gdk_export BAT *BATcalcifthenelse(BAT *b, BAT *b1, BAT *b2);
+gdk_export BAT *BATcalcifthenelsecst(BAT *b, BAT *b1, const ValRecord *c2);
+gdk_export BAT *BATcalcifthencstelse(BAT *b, const ValRecord *c1, BAT *b2);
+gdk_export BAT *BATcalcifthencstelsecst(BAT *b, const ValRecord *c1, const 
ValRecord *c2);
 
 gdk_export BAT *BATconvert(BAT *b, int tp, int abort_on_error);
 gdk_export int VARconvert(ValPtr ret, const ValRecord *v, int abort_on_error);
diff --git a/gdk/gdk_calc.c b/gdk/gdk_calc.c
--- a/gdk/gdk_calc.c
+++ b/gdk/gdk_calc.c
@@ -32,6 +32,11 @@
 static int
 checkbats(BAT *b1, BAT *b2, const char *func)
 {
+       if ((b1->H->type != TYPE_void && b1->H->type != TYPE_oid) ||
+           (b2 != NULL && b2->H->type != TYPE_void && b2->H->type != 
TYPE_oid)) {
+               GDKerror("%s: inputs must have (V)OID head.\n", func);
+               return GDK_FAIL;
+       }
        if (b2 != NULL) {
                if (b1->U->count != b2->U->count) {
                        GDKerror("%s: inputs not the same size.\n", func);
@@ -12380,6 +12385,242 @@ VARcalcbetween(ValPtr ret, const ValReco
        return GDK_SUCCEED;
 }
 
+#define IFTHENELSELOOP(TYPE)                                           \
+       do {                                                            \
+               for (i = 0; i < cnt; i++) {                             \
+                       if (src[i] == bit_nil) {                        \
+                               if (hd)                                 \
+                                       *hd++ = (oid) i + off;          \
+                               ((TYPE *) dst)[j++] = * (TYPE *) nil;   \
+                               nils++;                                 \
+                       } else if (src[i]) {                            \
+                               if (hd)                                 \
+                                       *hd++ = (oid) i + off;          \
+                               ((TYPE *) dst)[j++] = ((TYPE *) col1)[k]; \
+                       } else if (col2) {                              \
+                               ((TYPE *) dst)[j++] = ((TYPE *) col2)[l]; \
+                       }                                               \
+                       k += incr1;                                     \
+                       l += incr2;                                     \
+               }                                                       \
+       } while (0)
+
+static BAT *
+BATcalcifthenelse_intern(BAT *b,
+                        const void *col1, int incr1, const char *heap1, int 
width1, int nonil1,
+                        const void *col2, int incr2, const char *heap2, int 
width2, int nonil2,
+                        int tpe)
+{
+       BAT *bn;
+       void *dst;
+       oid *hd;
+       BUN i, j, k, l;
+       BUN nils = 0;
+       const void *nil;
+       const void *p;
+       const bit *src;
+       oid off = BAThdense(b) ? b->H->seq : 0;
+       BUN cnt = b->U->count;
+
+       assert(col2 != NULL || incr2 == 0);
+
+       bn = BATnew(col2 || off == oid_nil ? TYPE_void : TYPE_oid, tpe, cnt);
+       if (bn == NULL)
+               return NULL;
+
+       src = (const bit *) Tloc(b, b->U->first);
+
+       nil = ATOMnilptr(tpe);
+       dst = (void *) Tloc(bn, bn->U->first);
+       hd = col2 || off == oid_nil ? NULL : (oid *) Hloc(bn, bn->U->first);
+       j = k = l = 0;
+       if (bn->T->varsized) {
+               assert((heap1 != NULL && width1 > 0) || (width1 == 0 && incr1 
== 0));
+               assert((heap2 != NULL && width2 > 0) || (width2 == 0 && incr2 
== 0));
+               for (i = 0; i < cnt; i++) {
+                       if (src[i] == bit_nil) {
+                               p = nil;
+                               nils++;
+                       } else if (src[i]) {
+                               if (heap1)
+                                       p = heap1 + VarHeapVal(col1, k, width1);
+                               else
+                                       p = col1;
+                       } else if (col2) {
+                               if (heap2)
+                                       p = heap2 + VarHeapVal(col2, l, width2);
+                               else
+                                       p = col2;
+                       } else {
+                               p = NULL;
+                       }
+                       if (p) {
+                               tfastins_nocheck(bn, j, p, Tsize(bn));
+                               if (hd)
+                                       *hd++ = (oid) i + off;
+                               j++;
+                       }
+                       k += incr1;
+                       l += incr2;
+               }
+       } else {
+               assert(heap1 == NULL);
+               assert(heap2 == NULL);
+               switch (bn->T->width) {
+               case 1:
+                       IFTHENELSELOOP(bte);
+                       break;
+               case 2:
+                       IFTHENELSELOOP(sht);
+                       break;
+               case 4:
+                       IFTHENELSELOOP(int);
+                       break;
+               case 8:
+                       IFTHENELSELOOP(lng);
+                       break;
+               default:
+                       for (i = 0; i < cnt; i++) {
+                               if (src[i] == bit_nil) {
+                                       p = nil;
+                                       nils++;
+                               } else if (src[i]) {
+                                       p = ((const char *) col1) + k * width1;
+                               } else if (col2) {
+                                       p = ((const char *) col2) + l * width2;
+                               } else {
+                                       p = NULL;
+                               }
+                               if (p) {
+                                       memcpy(dst, p, bn->T->width);
+                                       if (hd)
+                                               *hd++ = (oid) i + off;
+                                       j++;
+                                       dst = (void *) ((char *) dst + 
bn->T->width);
+                               }
+                               k += incr1;
+                               l += incr2;
+                       }
+               }
+       }
+
+       BATsetcount(bn, j);
+       bn = BATseqbase(bn, b->H->seq);
+
+       bn->T->sorted = bn->U->count <= 1 || nils == bn->U->count;
+       bn->T->revsorted = bn->U->count <= 1 || nils == bn->U->count;
+       bn->T->key = bn->U->count <= 1;
+       bn->T->nil = nils != 0;
+       bn->T->nonil = nils == 0 && nonil1 && (col2 == NULL || nonil2);
+
+       if (hd) {
+               bn->H->sorted = 1;
+               bn->H->revsorted = bn->U->count <= 1;
+               bn->H->key = 1;
+               bn->H->nil = 0;
+               bn->H->nonil = 1;
+       }
+
+       if (b->H->type != bn->H->type && bn->U->count == b->U->count) {
+               BAT *bnn = VIEWcreate(b, bn);
+               BBPunfix(bn->batCacheid);
+               bn = bnn;
+       } else if (bn->U->count < b->U->count && !BAThdense(b)) {
+               const oid *oids = (const oid *) Hloc(b, b->U->first);
+               cnt = bn->U->count;
+               hd = (oid *) Hloc(bn, bn->U->first);
+               for (i = 0; i < cnt; i++) {
+                       *hd = oids[*hd];
+                       hd++;
+               }
+       }
+
+       return bn;
+  bunins_failed:
+       BBPreclaim(bn);
+       return NULL;
+}
+
+BAT *
+BATcalcifthenelse(BAT *b, BAT *b1, BAT *b2)
+{
+       BATcheck(b, "BATcalcifthenelse");
+       BATcheck(b1, "BATcalcifthenelse");
+       /* b2 may be NULL */
+
+       if (checkbats(b, b1, "BATcalcifthenelse") == GDK_FAIL)
+               return NULL;
+       if (b2 && checkbats(b, b2, "BATcalcifthenelse") == GDK_FAIL)
+               return NULL;
+       if (b->T->type != TYPE_bit ||
+           (b2 != NULL && b1->T->type != b2->T->type)) {
+               GDKerror("BATcalcifthenelse: \"then\" and \"else\" BATs have 
different types.\n");
+               return NULL;
+       }
+       return BATcalcifthenelse_intern(b,
+                                       Tloc(b1, b1->U->first), 1, b1->T->vheap 
? b1->T->vheap->base : NULL, b1->T->width, b1->T->nonil,
+                                       b2 ? Tloc(b2, b2->U->first) : NULL, b2 
!= NULL, b2 && b2->T->vheap ? b2->T->vheap->base : NULL, b2 ? b2->T->width : 0, 
b2 && b2->T->nonil,
+                                       b1->T->type);
+}
+
+BAT *
+BATcalcifthenelsecst(BAT *b, BAT *b1, const ValRecord *c2)
+{
+       BATcheck(b, "BATcalcifthenelsecst");
+       BATcheck(b1, "BATcalcifthenelsecst");
+       BATcheck(c2, "BATcalcifthenelsecst");
+
+       if (checkbats(b, b1, "BATcalcifthenelse") == GDK_FAIL)
+               return NULL;
+       if (b->T->type != TYPE_bit || b1->T->type != c2->vtype) {
+               GDKerror("BATcalcifthenelsecst: \"then\" and \"else\" BATs have 
different types.\n");
+               return NULL;
+       }
+       return BATcalcifthenelse_intern(b,
+                                       Tloc(b1, b1->U->first), 1, b1->T->vheap 
? b1->T->vheap->base : NULL, b1->T->width, b1->T->nonil,
+                                       VALptr(c2), 0, NULL, 0, !VALisnil(c2),
+                                       b1->T->type);
+}
+
+BAT *
+BATcalcifthencstelse(BAT *b, const ValRecord *c1, BAT *b2)
+{
+       BATcheck(b, "BATcalcifthenelsecst");
+       BATcheck(c1, "BATcalcifthenelsecst");
+       /* b2 may be NULL */
+
+       if (checkbats(b, b2, "BATcalcifthenelse") == GDK_FAIL)
+               return NULL;
+       if (b->T->type != TYPE_bit ||
+           (b2 != NULL && b2->T->type != c1->vtype)) {
+               GDKerror("BATcalcifthencstelse: \"then\" and \"else\" BATs have 
different types.\n");
+               return NULL;
+       }
+       return BATcalcifthenelse_intern(b,
+                                       VALptr(c1), 0, NULL, 0, !VALisnil(c1),
+                                       b2 ? Tloc(b2, b2->U->first) : NULL, b2 
!= NULL, b2 && b2->T->vheap ? b2->T->vheap->base : NULL, b2 ? b2->T->width : 0, 
b2 && b2->T->nonil,
+                                       c1->vtype);
+}
+
+BAT *
+BATcalcifthencstelsecst(BAT *b, const ValRecord *c1, const ValRecord *c2)
+{
+       BATcheck(b, "BATcalcifthenelsecst");
+       BATcheck(c1, "BATcalcifthenelsecst");
+       BATcheck(c2, "BATcalcifthenelsecst");
_______________________________________________
Checkin-list mailing list
Checkin-list@monetdb.org
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to