Changeset: aef5ee377e9f for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=aef5ee377e9f
Modified Files:
        gdk/gdk.h
        gdk/gdk_cand.c
        gdk/gdk_cand.h
        gdk/gdk_project.c
        monetdb5/modules/mal/batMask.c
Branch: unlock
Log Message:

Convert msk bat to oid bat in BATprojectchain.
This gives us the possibility to use a msk bat in the chain, and
circumvents the problem where we would have to count set bits in the
msk bat many for each projected value.


diffs (188 lines):

diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -1011,7 +1011,7 @@ BUNtoid(BAT *b, BUN p)
        if (b->ttype == TYPE_oid || b->tvheap == NULL) {
                return o;
        }
-       /* only exceptions allowed on transient BATs */
+       /* exceptions only allowed on transient BATs */
        assert(b->batRole == TRANSIENT);
        /* make sure exception area is a reasonable size */
        assert(b->tvheap->free % SIZEOF_OID == 0);
diff --git a/gdk/gdk_cand.c b/gdk/gdk_cand.c
--- a/gdk/gdk_cand.c
+++ b/gdk/gdk_cand.c
@@ -1285,3 +1285,40 @@ BATnegcands(BAT *dense_cands, BAT *odels
                  ALGOBATPAR(odels));
        return GDK_SUCCEED;
 }
+
+BAT *
+BATunmask(BAT *b)
+{
+       BAT *bn = COLnew(0, TYPE_oid, 1024, TRANSIENT);
+       if (bn == NULL)
+               return NULL;
+
+       BUN cnt = BATcount(b) / 32;
+       const uint32_t *src = (const uint32_t *) Tloc(b, 0);
+       oid *dst = (oid *) Tloc(bn, 0);
+       BUN n = 0;
+
+       for (BUN p = 0; p < cnt; p++) {
+               if (src[p] == 0)
+                       continue;
+               for (uint32_t i = 0; i < 32; i++) {
+                       if (src[p] & (1U << i)) {
+                               if (n == BATcapacity(bn)) {
+                                       if (BATextend(bn, BATgrows(bn)) != 
GDK_SUCCEED) {
+                                               BBPreclaim(bn);
+                                               return NULL;
+                                       }
+                                       dst = (oid *) Tloc(bn, 0);
+                               }
+                               dst[n++] = b->hseqbase + p * 32 + i;
+                       }
+               }
+       }
+       BATsetcount(bn, n);
+       bn->tkey = true;
+       bn->tsorted = true;
+       bn->trevsorted = n <= 1;
+       bn->tnil = false;
+       bn->tnonil = true;
+       return virtualize(bn);
+}
diff --git a/gdk/gdk_cand.h b/gdk/gdk_cand.h
--- a/gdk/gdk_cand.h
+++ b/gdk/gdk_cand.h
@@ -149,5 +149,6 @@ gdk_export BAT *canditer_sliceval(struct
 gdk_export BAT *canditer_slice2(struct canditer *ci, BUN lo1, BUN hi1, BUN 
lo2, BUN hi2);
 gdk_export BAT *canditer_slice2val(struct canditer *ci, oid lo1, oid hi1, oid 
lo2, oid hi2);
 gdk_export gdk_return BATnegcands( BAT *cands, BAT *odels);
+gdk_export BAT *BATunmask(BAT *b);
 
 #endif /* _GDK_CAND_H_ */
diff --git a/gdk/gdk_project.c b/gdk/gdk_project.c
--- a/gdk/gdk_project.c
+++ b/gdk/gdk_project.c
@@ -495,7 +495,7 @@ BATproject(BAT *restrict l, BAT *restric
  * bn = BATproject(bn, bats[n-1]);
  * return bn;
  * where none of the intermediates are actually produced (and bats[n]==NULL).
- * Note that all BATs except the last must have type oid/void.
+ * Note that all BATs except the last must have type oid/void or msk.
  */
 BAT *
 BATprojectchain(BAT **bats)
@@ -507,8 +507,10 @@ BATprojectchain(BAT **bats)
                oid *t;
                struct canditer ci; /* used if .ci.s != NULL */
        } *ba;
+       BAT **tobedeleted = NULL;
+       int ndelete = 0;
        int n;
-       BAT *b = NULL, *bn;
+       BAT *b = NULL, *bn = NULL;
        bool allnil = false;
        bool issorted = true;
        bool nonil = true;
@@ -522,6 +524,7 @@ BATprojectchain(BAT **bats)
         * temporary work space */
        for (n = 0; bats[n]; n++) {
                b = bats[n];
+               ndelete += (b->ttype == TYPE_msk);
                TRC_DEBUG(ALGO, "arg %d: " ALGOBATFMT "\n",
                          n + 1, ALGOBATPAR(b));
        }
@@ -537,12 +540,24 @@ BATprojectchain(BAT **bats)
                return bn;
        }
 
+       if (ndelete > 0 &&
+           (tobedeleted = GDKmalloc(sizeof(BAT *) * ndelete)) == NULL)
+               return NULL;
        ba = GDKmalloc(sizeof(*ba) * n);
-       if (ba == NULL)
+       if (ba == NULL) {
+               GDKfree(tobedeleted);
                return NULL;
+       }
 
+       ndelete = 0;
        for (n = 0; bats[n]; n++) {
                b = bats[n];
+               if (b->ttype == TYPE_msk) {
+                       if ((b = BATunmask(b)) == NULL) {
+                               goto bunins_failed;
+                       }
+                       tobedeleted[ndelete++] = b;
+               }
                ba[n] = (struct ba) {
                        .b = b,
                        .hlo = b->hseqbase,
@@ -564,6 +579,9 @@ BATprojectchain(BAT **bats)
        if (allnil || ba[0].cnt == 0) {
                bn = BATconstant(ba[0].hlo, tpe == TYPE_oid ? TYPE_void : tpe,
                                 nil, ba[0].cnt, TRANSIENT);
+               while (ndelete-- > 0)
+                       BBPreclaim(tobedeleted[ndelete]);
+               GDKfree(tobedeleted);
                GDKfree(ba);
                TRC_DEBUG(ALGO, "with %d bats: nil/empty -> " ALGOOPTBATFMT
                          " " LLFMT " usec\n",
@@ -578,8 +596,7 @@ BATprojectchain(BAT **bats)
 
        bn = COLnew(ba[0].hlo, tpe, ba[0].cnt, TRANSIENT);
        if (bn == NULL) {
-               GDKfree(ba);
-               return NULL;
+               goto bunins_failed;
        }
 
        if (ATOMtype(b->ttype) == TYPE_oid) {
@@ -693,6 +710,9 @@ BATprojectchain(BAT **bats)
                }
                n++;            /* undo for debug print */
        }
+       while (ndelete-- > 0)
+               BBPreclaim(tobedeleted[ndelete]);
+       GDKfree(tobedeleted);
        BATsetcount(bn, ba[0].cnt);
        bn->tsorted = (ba[0].cnt <= 1) | issorted;
        bn->trevsorted = ba[0].cnt <= 1;
@@ -704,6 +724,9 @@ BATprojectchain(BAT **bats)
        return bn;
 
   bunins_failed:
+       while (ndelete-- > 0)
+               BBPreclaim(tobedeleted[ndelete]);
+       GDKfree(tobedeleted);
        GDKfree(ba);
        BBPreclaim(bn);
        TRC_DEBUG(ALGO, "failed " LLFMT "usec\n", GDKusec() - t0);
diff --git a/monetdb5/modules/mal/batMask.c b/monetdb5/modules/mal/batMask.c
--- a/monetdb5/modules/mal/batMask.c
+++ b/monetdb5/modules/mal/batMask.c
@@ -104,19 +104,11 @@ MSKumask(Client cntxt, MalBlkPtr mb, Mal
        bid = getArgReference_bat(stk, pci, 1);
        if ((b = BATdescriptor(*bid)) == NULL)
                throw(SQL, "bat.umask", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
-       dst = COLnew(0, TYPE_oid, BATcount(b), TRANSIENT);
+       dst = BATunmask(b);
        if (dst == NULL) {
                BBPunfix(b->batCacheid);
                throw(MAL, "mask.umask", GDK_EXCEPTION);
        }
-       for (BUN p = 0; p < BATcount(b); p++) {
-               if (mskGetVal(b, p) &&
-                       BUNappend(dst, &(oid){p + b->hseqbase}, false) != 
GDK_SUCCEED) {
-                       BBPunfix(b->batCacheid);
-                       throw(MAL, "mask.umask", GDK_EXCEPTION);
-               }
-       }
-
        *ret=  dst->batCacheid;
        BBPkeepref(*ret);
        return MAL_SUCCEED;
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to