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]