Changeset: ce328afb2eb5 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ce328afb2eb5
Modified Files:
        gdk/gdk_calc.c
Branch: default
Log Message:

Implementing call free versions of batcalc min and max functions for trivial 
types


diffs (222 lines):

diff --git a/gdk/gdk_calc.c b/gdk/gdk_calc.c
--- a/gdk/gdk_calc.c
+++ b/gdk/gdk_calc.c
@@ -1178,17 +1178,29 @@ VARcalcisnotnil(ValPtr ret, const ValRec
        return GDK_SUCCEED;
 }
 
+#define MINMAX_TYPE(TYPE, OP)                                  \
+       do {                                                            \
+               TYPE *tb1 = Tloc(b1, 0), *tb2 = Tloc(b2, 0), *restrict tbn = 
Tloc(bn, 0); \
+               for (BUN i = 0; i < ncand; i++) { \
+                       oid x1 = canditer_next(&ci1) - b1->hseqbase; \
+                       oid x2 = canditer_next(&ci2) - b2->hseqbase; \
+                       TYPE p1 = tb1[x1], p2 = tb2[x2]; \
+                       if (is_##TYPE##_nil(p1) || is_##TYPE##_nil(p2)) { \
+                               nils++; \
+                               tbn[i] = TYPE##_nil; \
+                       } else {        \
+                               tbn[i] = p1 OP p2 ? p1 : p2; \
+                       }       \
+               } \
+       } while (0)
+
 BAT *
 BATcalcmin(BAT *b1, BAT *b2, BAT *s1, BAT *s2)
 {
        lng t0 = 0;
        BAT *bn;
-       BUN nils = 0;
-       BUN ncand;
+       BUN nils = 0, ncand;
        struct canditer ci1, ci2;
-       const void *restrict nil;
-       BATiter b1i, b2i;
-       int (*cmp)(const void *, const void *);
 
        TRC_DEBUG_IF(ALGO) t0 = GDKusec();
 
@@ -1201,37 +1213,64 @@ BATcalcmin(BAT *b1, BAT *b2, BAT *s1, BA
        }
 
        ncand = canditer_init(&ci1, b1, s1);
-       if (canditer_init(&ci2, b2, s2) != ncand ||
-           ci1.hseq != ci2.hseq) {
+       if (canditer_init(&ci2, b2, s2) != ncand || ci1.hseq != ci2.hseq) {
                GDKerror("inputs not the same size.\n");
                return NULL;
        }
 
-       nil = ATOMnilptr(b1->ttype);
        bn = COLnew(ci1.hseq, ATOMtype(b1->ttype), ncand, TRANSIENT);
        if (bn == NULL)
                return NULL;
-       cmp = ATOMcompare(b1->ttype);
-       b1i = bat_iterator(b1);
-       b2i = bat_iterator(b2);
-
-       for (BUN i = 0; i < ncand; i++) {
-               oid x1 = canditer_next(&ci1) - b1->hseqbase;
-               oid x2 = canditer_next(&ci2) - b2->hseqbase;
-               const void *p1 = BUNtail(b1i, x1);
-               const void *p2 = BUNtail(b2i, x2);
-               if (cmp(p1, nil) == 0 || cmp(p2, nil) == 0) {
-                       nils++;
-                       p1 = nil;
-               } else if (cmp(p1, p2) > 0) {
-                       p1 = p2;
-               }
-               if (bunfastapp(bn, p1) != GDK_SUCCEED)
-                       goto bunins_failed;
+
+       switch (ATOMbasetype(b1->ttype)) {
+       case TYPE_bte:
+               MINMAX_TYPE(bte, <);
+               break;
+       case TYPE_sht:
+               MINMAX_TYPE(sht, <);
+               break;
+       case TYPE_int:
+               MINMAX_TYPE(int, <);
+               break;
+       case TYPE_lng:
+               MINMAX_TYPE(lng, <);
+               break;
+#ifdef HAVE_HGE
+       case TYPE_hge:
+               MINMAX_TYPE(hge, <);
+               break;
+#endif
+       case TYPE_flt:
+               MINMAX_TYPE(flt, <);
+               break;
+       case TYPE_dbl:
+               MINMAX_TYPE(dbl, <);
+               break;
+       default: {
+               const void *restrict nil = ATOMnilptr(b1->ttype);
+               BATiter b1i = bat_iterator(b1), b2i = bat_iterator(b2);
+               int (*cmp)(const void *, const void *) = ATOMcompare(b1->ttype);
+
+               for (BUN i = 0; i < ncand; i++) {
+                       oid x1 = canditer_next(&ci1) - b1->hseqbase;
+                       oid x2 = canditer_next(&ci2) - b2->hseqbase;
+                       const void *p1 = BUNtail(b1i, x1);
+                       const void *p2 = BUNtail(b2i, x2);
+                       if (cmp(p1, nil) == 0 || cmp(p2, nil) == 0) {
+                               nils++;
+                               p1 = nil;
+                       } else {
+                               p1 = cmp(p1, p2) < 0 ? p1 : p2;
+                       }
+                       if (bunfastapp(bn, p1) != GDK_SUCCEED)
+                               goto bunins_failed;
+               }
+       }
        }
 
        bn->tnil = nils > 0;
        bn->tnonil = nils == 0;
+       BATsetcount(bn, ncand);
        if (ncand <= 1) {
                bn->tsorted = true;
                bn->trevsorted = true;
@@ -1521,12 +1560,8 @@ BATcalcmax(BAT *b1, BAT *b2, BAT *s1, BA
 {
        lng t0 = 0;
        BAT *bn;
-       BUN nils = 0;
-       BUN ncand;
+       BUN nils = 0, ncand;
        struct canditer ci1, ci2;
-       const void *restrict nil;
-       BATiter b1i, b2i;
-       int (*cmp)(const void *, const void *);
 
        TRC_DEBUG_IF(ALGO) t0 = GDKusec();
 
@@ -1539,37 +1574,64 @@ BATcalcmax(BAT *b1, BAT *b2, BAT *s1, BA
        }
 
        ncand = canditer_init(&ci1, b1, s1);
-       if (canditer_init(&ci2, b2, s2) != ncand ||
-           ci1.hseq != ci2.hseq) {
+       if (canditer_init(&ci2, b2, s2) != ncand || ci1.hseq != ci2.hseq) {
                GDKerror("inputs not the same size.\n");
                return NULL;
        }
 
-       nil = ATOMnilptr(b1->ttype);
        bn = COLnew(ci1.hseq, ATOMtype(b1->ttype), ncand, TRANSIENT);
        if (bn == NULL)
                return NULL;
-       cmp = ATOMcompare(b1->ttype);
-       b1i = bat_iterator(b1);
-       b2i = bat_iterator(b2);
-
-       for (BUN i = 0; i < ncand; i++) {
-               oid x1 = canditer_next(&ci1) - b1->hseqbase;
-               oid x2 = canditer_next(&ci2) - b2->hseqbase;
-               const void *p1 = BUNtail(b1i, x1);
-               const void *p2 = BUNtail(b2i, x2);
-               if (cmp(p1, nil) == 0 || cmp(p2, nil) == 0) {
-                       nils++;
-                       p1 = nil;
-               } else if (cmp(p1, p2) < 0) {
-                       p1 = p2;
-               }
-               if (bunfastapp(bn, p1) != GDK_SUCCEED)
-                       goto bunins_failed;
+
+       switch (ATOMbasetype(b1->ttype)) {
+       case TYPE_bte:
+               MINMAX_TYPE(bte, >);
+               break;
+       case TYPE_sht:
+               MINMAX_TYPE(sht, >);
+               break;
+       case TYPE_int:
+               MINMAX_TYPE(int, >);
+               break;
+       case TYPE_lng:
+               MINMAX_TYPE(lng, >);
+               break;
+#ifdef HAVE_HGE
+       case TYPE_hge:
+               MINMAX_TYPE(hge, >);
+               break;
+#endif
+       case TYPE_flt:
+               MINMAX_TYPE(flt, >);
+               break;
+       case TYPE_dbl:
+               MINMAX_TYPE(dbl, >);
+               break;
+       default: {
+               const void *restrict nil = ATOMnilptr(b1->ttype);
+               BATiter b1i = bat_iterator(b1), b2i = bat_iterator(b2);
+               int (*cmp)(const void *, const void *) = ATOMcompare(b1->ttype);
+
+               for (BUN i = 0; i < ncand; i++) {
+                       oid x1 = canditer_next(&ci1) - b1->hseqbase;
+                       oid x2 = canditer_next(&ci2) - b2->hseqbase;
+                       const void *p1 = BUNtail(b1i, x1);
+                       const void *p2 = BUNtail(b2i, x2);
+                       if (cmp(p1, nil) == 0 || cmp(p2, nil) == 0) {
+                               nils++;
+                               p1 = nil;
+                       } else {
+                               p1 = cmp(p1, p2) > 0 ? p1 : p2;
+                       }
+                       if (bunfastapp(bn, p1) != GDK_SUCCEED)
+                               goto bunins_failed;
+               }
+       }
        }
 
        bn->tnil = nils > 0;
        bn->tnonil = nils == 0;
+       BATsetcount(bn, ncand);
        if (ncand <= 1) {
                bn->tsorted = true;
                bn->trevsorted = true;
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to