Changeset: d1561eb79570 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/d1561eb79570
Modified Files:
        clients/Tests/exports.stable.out
        gdk/gdk.h
        gdk/gdk_aggr.c
        gdk/gdk_firstn.c
        gdk/gdk_string.c
        gdk/gdk_subquery.c
        geom/monetdb5/geom.c
        monetdb5/modules/atoms/batxml.c
        monetdb5/modules/atoms/json.c
Branch: default
Log Message:

BATgroupaggrinit now optionally initialized a BAT iterator.
There is an extra argument at the end which, if not NULL, points to a
BATiter structure which is then initialized and also used to initialize
the candidate iterator.


diffs (truncated from 1277 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
@@ -127,7 +127,7 @@ restrict_t BATgetaccess(BAT *b);
 ValPtr BATgetprop(BAT *b, enum prop_t idx);
 ValPtr BATgetprop_nolock(BAT *b, enum prop_t idx);
 gdk_return BATgroup(BAT **groups, BAT **extents, BAT **histo, BAT *b, BAT *s, 
BAT *g, BAT *e, BAT *h);
-const char *BATgroupaggrinit(BAT *b, BAT *g, BAT *e, BAT *s, oid *minp, oid 
*maxp, BUN *ngrpp, struct canditer *ci);
+const char *BATgroupaggrinit(BAT *b, BAT *g, BAT *e, BAT *s, oid *minp, oid 
*maxp, BUN *ngrpp, struct canditer *ci, BATiter *bi);
 gdk_return BATgroupavg(BAT **bnp, BAT **cntsp, BAT *b, BAT *g, BAT *e, BAT *s, 
int tp, bool skip_nils, int scale);
 gdk_return BATgroupavg2(BAT **bnp, BAT **cntsp, BAT *b, BAT *g, BAT *e, BAT 
*s, int tp, BUN ngrp, bool skip_nils, int scale);
 gdk_return BATgroupavg3(BAT **avgp, BAT **remp, BAT **cntp, BAT *b, BAT *g, 
BAT *e, BAT *s, bool skip_nils, bool inout);
diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -4734,11 +4734,19 @@ gdk_export BAT *BATgroupquantile_avg(BAT
                                     double quantile, bool skip_nils);
 
 /* helper function for grouped aggregates */
-gdk_export const char *BATgroupaggrinit(
-       BAT *b, BAT *g, BAT *e, BAT *s,
-       /* outputs: */
-       oid *minp, oid *maxp, BUN *ngrpp,
-       struct canditer *ci);
+gdk_export const char *BATgroupaggrinit(BAT *b, BAT *g, BAT *e, BAT *s,
+                                       /* outputs: */
+                                       oid *minp, oid *maxp, BUN *ngrpp,
+                                       struct canditer *ci, BATiter *bi)
+       ATTR_NONNULL(5)
+       ATTR_NONNULL(6)
+       ATTR_NONNULL(7)
+       ATTR_NONNULL(8)
+       ATTR_ACCESS(write_only, 5)
+       ATTR_ACCESS(write_only, 6)
+       ATTR_ACCESS(write_only, 7)
+       ATTR_ACCESS(write_only, 8)
+       ATTR_ACCESS(write_only, 9);
 
 gdk_export gdk_return BATsum(void *res, int tp, BAT *b, BAT *s, bool skip_nils,
                             bool nil_if_empty, bool inout);
diff --git a/gdk/gdk_aggr.c b/gdk/gdk_aggr.c
--- a/gdk/gdk_aggr.c
+++ b/gdk/gdk_aggr.c
@@ -19,18 +19,16 @@
  * single output BAT.
  *
  * The input BATs are
- * - b, a dense-headed BAT with the values to work on in the tail;
- * - g, a dense-headed BAT, aligned with b, with group ids (OID) in
- *   the tail;
- * - e, optional but recommended, a dense-headed BAT with the list of
- *   group ids in the head(!) (the tail is completely ignored);
- * - s, optional, a dense-headed bat with a list of candidate ids in
- *   the tail.
+ * - b, a BAT with the values to work;
+ * - g, a BAT, aligned with b, with group ids (OID);
+ * - e, optional but recommended, a BAT with the list of group ids, only
+ *   the hseqbase and batCount are used;
+ * - s, optional, the candidate list.
  *
- * The tail values of s refer to the head of b and g.  Only entries at
- * the specified ids are taken into account for the grouped
- * aggregates.  All other values are ignored.  s is compatible with
- * the result of BATselect().
+ * The values of s refer to the row id of b and g.  Only entries at the
+ * specified ids are taken into account for the grouped aggregates.  All
+ * other values are ignored.  s is compatible with the result of
+ * BATselect().
  *
  * If e is not specified, we need to do an extra scan over g to find
  * out the range of the group ids that are used.  e is defined in such
@@ -47,8 +45,8 @@
  * If there is overflow during the calculation of an aggregate, the
  * whole operation fails.
  *
- * If skip_nils is non-zero, a nil value in b is ignored, otherwise a
- * nil in b results in a nil result for the group.
+ * If skip_nils is true, a nil value in b is ignored, otherwise a nil in
+ * b results in a nil result for the group.
  */
 
 /* helper function
@@ -59,12 +57,21 @@
  *
  * In case of error, returns an error message.
  */
+ATTR_NONNULL(6)
+ATTR_NONNULL(7)
+ATTR_NONNULL(8)
+ATTR_NONNULL(9)
+ATTR_ACCESS(write_only, 6)
+ATTR_ACCESS(write_only, 7)
+ATTR_ACCESS(write_only, 8)
+ATTR_ACCESS(write_only, 9)
+ATTR_ACCESS(write_only, 10)
 static const char *
 BATgroupaggrinit2(bool pipeline,
                  BAT *b, BAT *g, BAT *e, BAT *s,
                  /* outputs: */
                  oid *minp, oid *maxp, BUN *ngrpp,
-                 struct canditer *ci)
+                 struct canditer *ci, BATiter *bi)
 {
        oid min, max;
        BUN i, ngrp;
@@ -72,11 +79,19 @@ BATgroupaggrinit2(bool pipeline,
 
        if (b == NULL)
                return "b must exist";
-       canditer_init(ci, b, s);
+       if (bi) {
+               *bi = bat_iterator(b);
+               canditer_init_bi(ci, bi, s);
+       } else {
+               canditer_init(ci, b, s);
+       }
        if (g) {
                if ((pipeline ? ci->ncand > BATcount(g) : ci->ncand != 
BATcount(g)) ||
-                   (ci->ncand != 0 && ci->seq != g->hseqbase))
+                   (ci->ncand != 0 && ci->seq != g->hseqbase)) {
+                       if (bi)
+                               bat_iterator_end(bi);
                        return "b with s and g must be aligned";
+               }
                assert(BATttype(g) == TYPE_oid);
        }
        if (g == NULL) {
@@ -146,11 +161,11 @@ BATgroupaggrinit2(bool pipeline,
 
 const char *
 BATgroupaggrinit(BAT *b, BAT *g, BAT *e, BAT *s,
-               /* outputs: */
-               oid *minp, oid *maxp, BUN *ngrpp,
-               struct canditer *ci)
+                /* outputs: */
+                oid *minp, oid *maxp, BUN *ngrpp,
+                struct canditer *ci, BATiter *bi)
 {
-       return BATgroupaggrinit2(false, b, g, e, s, minp, maxp, ngrpp, ci);
+       return BATgroupaggrinit2(false, b, g, e, s, minp, maxp, ngrpp, ci, bi);
 }
 
 /* ---------------------------------------------------------------------- */
@@ -912,14 +927,16 @@ BATgroupsum(BAT *b, BAT *g, BAT *e, BAT 
        const char *err;
        const char *algo = NULL;
        lng t0 = 0;
+       BATiter bi;
 
        TRC_DEBUG_IF(ALGO) t0 = GDKusec();
 
-       if ((err = BATgroupaggrinit(b, g, e, s, &min, &max, &ngrp, &ci)) != 
NULL) {
+       if ((err = BATgroupaggrinit(b, g, e, s, &min, &max, &ngrp, &ci, &bi)) 
!= NULL) {
                GDKerror("%s\n", err);
                return NULL;
        }
        if (g == NULL) {
+               bat_iterator_end(&bi);
                GDKerror("b and g must be aligned\n");
                return NULL;
        }
@@ -927,6 +944,7 @@ BATgroupsum(BAT *b, BAT *g, BAT *e, BAT 
        if (ci.ncand == 0 || ngrp == 0) {
                /* trivial: no sums, so return bat aligned with g with
                 * nil in the tail */
+               bat_iterator_end(&bi);
                return BATconstant(ngrp == 0 ? 0 : min, tp, ATOMnilptr(tp), 
ngrp, TRANSIENT);
        }
 
@@ -935,11 +953,13 @@ BATgroupsum(BAT *b, BAT *g, BAT *e, BAT 
            (BATtdense(g) || (g->tkey && g->tnonil))) {
                /* trivial: singleton groups, so all results are equal
                 * to the inputs (but possibly a different type) */
+               bat_iterator_end(&bi);
                return BATconvert(b, s, tp, 0, 0, 0);
        }
 
        bn = BATconstant(min, tp, ATOMnilptr(tp), ngrp, TRANSIENT);
        if (bn == NULL) {
+               bat_iterator_end(&bi);
                return NULL;
        }
 
@@ -948,7 +968,6 @@ BATgroupsum(BAT *b, BAT *g, BAT *e, BAT 
        else
                gids = (const oid *) Tloc(g, 0);
 
-       BATiter bi = bat_iterator(b);
        nils = dosum(bi.base, bi.nonil, b->hseqbase, &ci,
                     Tloc(bn, 0), ngrp, bi.type, tp, gids, min, max,
                     skip_nils, true, __func__, &algo);
@@ -978,22 +997,20 @@ BATgroupsum(BAT *b, BAT *g, BAT *e, BAT 
 }
 
 static BUN
-mskCountOnes(BAT *b, struct canditer *ci)
+mskCountOnes(BATiter *bi, struct canditer *ci)
 {
        BUN cnt = 0, ncand = ci->ncand;
 
-       if (ci->s == NULL && mask_cand(b))
-               return BATcount(b);
-       if (ci->tpe == cand_dense && ncand > 0 && !mask_cand(b)) {
-               BATiter bi = bat_iterator(b);
-               const uint32_t *restrict src = (const uint32_t *) bi.base + 
(ci->seq - b->hseqbase) / 32;
-               int bits = (ci->seq - b->hseqbase) % 32;
+       if (ci->s == NULL && mask_cand(bi->b))
+               return bi->count;
+       if (ci->tpe == cand_dense && ncand > 0 && !mask_cand(bi->b)) {
+               const uint32_t *restrict src = (const uint32_t *) bi->base + 
(ci->seq - bi->hseq) / 32;
+               int bits = (ci->seq - bi->hseq) % 32;
                if (bits + ncand <= 32) {
                        if (ncand == 32)
                                cnt = candmask_pop(src[0]);
                        else
                                cnt = candmask_pop(src[0] & (((1U << ncand) - 
1) << bits));
-                       bat_iterator_end(&bi);
                        return cnt;
                }
                if (bits != 0) {
@@ -1008,12 +1025,11 @@ mskCountOnes(BAT *b, struct canditer *ci
                }
                if (ncand > 0)
                        cnt += candmask_pop(*src & ((1U << ncand) - 1));
-               bat_iterator_end(&bi);
                return cnt;
        }
        for (BUN i = 0; i < ncand; i++) {
-               BUN x = canditer_next(ci) - b->hseqbase;
-               cnt += mskGetVal(b, x);
+               BUN x = canditer_next(ci) - bi->hseq;
+               cnt += mskGetVal(bi->b, x);
        }
        return cnt;
 }
@@ -1033,17 +1049,19 @@ BATsum(void *resout, int tp, BAT *b, BAT
        lng result = 0;
 #endif
        void *res = &result;
+       BATiter bi;
 
        if (!inout)
                res = resout;
        TRC_DEBUG_IF(ALGO) t0 = GDKusec();
 
-       if ((err = BATgroupaggrinit(b, NULL, NULL, s, &min, &max, &ngrp, &ci)) 
!= NULL) {
+       if ((err = BATgroupaggrinit(b, NULL, NULL, s, &min, &max, &ngrp, &ci, 
&bi)) != NULL) {
                GDKerror("%s\n", err);
                return GDK_FAIL;
        }
        if (ATOMstorage(b->ttype) == TYPE_msk || mask_cand(b)) {
-               BUN n = mskCountOnes(b, &ci);
+               BUN n = mskCountOnes(&bi, &ci);
+               bat_iterator_end(&bi);
                switch (tp) {
                case TYPE_bte:
                        if (n > GDK_bte_max) {
@@ -1133,6 +1151,7 @@ BATsum(void *resout, int tp, BAT *b, BAT
                        dbl avg;
                        BUN cnt;
 
+                       bat_iterator_end(&bi); /* not used here */
                        if (BATcalcavg(b, s, &avg, &cnt, 0, false) != 
GDK_SUCCEED)
                                return GDK_FAIL;
                        if (cnt == 0) {
@@ -1174,13 +1193,15 @@ BATsum(void *resout, int tp, BAT *b, BAT
                        * (flt *) res = nil_if_empty ? flt_nil : 0;
                break;
        default:
+               bat_iterator_end(&bi);
                GDKerror("type combination (sum(%s)->%s) not supported.\n",
                         ATOMname(b->ttype), ATOMname(tp));
                return GDK_FAIL;
        }
-       if (ci.ncand == 0)
+       if (ci.ncand == 0) {
+               bat_iterator_end(&bi);
                return GDK_SUCCEED;
-       BATiter bi = bat_iterator(b);
+       }
        BUN nils = dosum(bi.base, bi.nonil, b->hseqbase, &ci,
                         res, true, bi.type, tp, &min, min, max,
                         skip_nils, nil_if_empty, __func__, &algo);
@@ -1646,14 +1667,16 @@ BATgroupprod(BAT *b, BAT *g, BAT *e, BAT
        struct canditer ci;
        const char *err;
        lng t0 = 0;
+       BATiter bi;
 
        TRC_DEBUG_IF(ALGO) t0 = GDKusec();
 
-       if ((err = BATgroupaggrinit(b, g, e, s, &min, &max, &ngrp, &ci)) != 
NULL) {
+       if ((err = BATgroupaggrinit(b, g, e, s, &min, &max, &ngrp, &ci, &bi)) 
!= NULL) {
                GDKerror("%s\n", err);
                return NULL;
        }
        if (g == NULL) {
+               bat_iterator_end(&bi);
                GDKerror("b and g must be aligned\n");
                return NULL;
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to