Changeset: 974248a51b36 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=974248a51b36
Removed Files:
        monetdb5/modules/kernel/aggr_be_minmax.mx
        monetdb5/modules/kernel/aggr_bge_minmax.mx
Modified Files:
        clients/Tests/exports.stable.out
        gdk/gdk_calc.c
        gdk/gdk_calc.h
        monetdb5/modules/kernel/Makefile.ag
        monetdb5/modules/kernel/aggr.mx
Branch: default
Log Message:

Reimplemented grouped min/max aggregates.


diffs (truncated from 1880 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
@@ -118,6 +118,8 @@ PROPrec *BATgetprop(BAT *b, int idx);
 gdk_return BATgroup(BAT **groups, BAT **extents, BAT **histo, BAT *b, BAT *g, 
BAT *e, BAT *h);
 BAT *BATgroupavg(BAT *b, BAT *g, BAT *e, BAT *s, int tp, int skip_nils, int 
abort_on_error);
 BAT *BATgroupcount(BAT *b, BAT *g, BAT *e, BAT *s, int tp, int skip_nils, int 
abort_on_error);
+BAT *BATgroupmax(BAT *b, BAT *g, BAT *e, BAT *s, int tp, int skip_nils, int 
abort_on_error);
+BAT *BATgroupmin(BAT *b, BAT *g, BAT *e, BAT *s, int tp, int skip_nils, int 
abort_on_error);
 BAT *BATgroupprod(BAT *b, BAT *g, BAT *e, BAT *s, int tp, int skip_nils, int 
abort_on_error);
 BAT *BATgroupsize(BAT *b, BAT *g, BAT *e, BAT *s, int tp, int skip_nils, int 
abort_on_error);
 BAT *BATgroupsum(BAT *b, BAT *g, BAT *e, BAT *s, int tp, int skip_nils, int 
abort_on_error);
@@ -591,6 +593,10 @@ str AGGRcount2nonils(bat *retval, bat *b
 str AGGRcount3(bat *retval, bat *bid, bat *gid, bat *eid, bit *ignorenils);
 str AGGRcount3nils(bat *retval, bat *bid, bat *gid, bat *eid);
 str AGGRcount3nonils(bat *retval, bat *bid, bat *gid, bat *eid);
+str AGGRmax2(bat *retval, bat *bid, bat *eid);
+str AGGRmax3(bat *retval, bat *bid, bat *gid, bat *eid);
+str AGGRmin2(bat *retval, bat *bid, bat *eid);
+str AGGRmin3(bat *retval, bat *bid, bat *gid, bat *eid);
 str AGGRprod2_bte(bat *retval, bat *bid, bat *eid);
 str AGGRprod2_dbl(bat *retval, bat *bid, bat *eid);
 str AGGRprod2_flt(bat *retval, bat *bid, bat *eid);
@@ -608,8 +614,12 @@ str AGGRprod3_wrd(bat *retval, bat *bid,
 str AGGRsize2(bat *retval, bat *bid, bat *eid);
 str AGGRsubavg_dbl(bat *retval, bat *bid, bat *gid, bat *eid, int *skip_nils, 
int *abort_on_error);
 str AGGRsubavgcand_dbl(bat *retval, bat *bid, bat *gid, bat *eid, bat *sid, 
int *skip_nils, int *abort_on_error);
-str AGGRsubcount(bat *retval, bat *bid, bat *gid, bat *eid, int *skip_nils, 
int *abort_on_error);
-str AGGRsubcountcand(bat *retval, bat *bid, bat *gid, bat *eid, bat *sid, int 
*skip_nils, int *abort_on_error);
+str AGGRsubcount(bat *retval, bat *bid, bat *gid, bat *eid, int *skip_nils);
+str AGGRsubcountcand(bat *retval, bat *bid, bat *gid, bat *eid, bat *sid, int 
*skip_nils);
+str AGGRsubmax(bat *retval, bat *bid, bat *gid, bat *eid, int *skip_nils);
+str AGGRsubmaxcand(bat *retval, bat *bid, bat *gid, bat *eid, bat *sid, int 
*skip_nils);
+str AGGRsubmin(bat *retval, bat *bid, bat *gid, bat *eid, int *skip_nils);
+str AGGRsubmincand(bat *retval, bat *bid, bat *gid, bat *eid, bat *sid, int 
*skip_nils);
 str AGGRsubprod_bte(bat *retval, bat *bid, bat *gid, bat *eid, int *skip_nils, 
int *abort_on_error);
 str AGGRsubprod_dbl(bat *retval, bat *bid, bat *gid, bat *eid, int *skip_nils, 
int *abort_on_error);
 str AGGRsubprod_flt(bat *retval, bat *bid, bat *gid, bat *eid, int *skip_nils, 
int *abort_on_error);
@@ -878,10 +888,6 @@ str AUTHrequireAdminOrUser(Client *c, st
 str AUTHresolveUser(str *ret, oid *uid);
 str AUTHsetPassword(Client *c, str *username, str *passwd);
 str AUTHunlockVault(str *password);
-str AX3aggrX3_max(int *ret, int *bid, int *eid);
-str AX3aggrX3_max3(int *ret, int *bid, int *gid, int *eid);
-str AX3aggrX3_min(int *ret, int *bid, int *eid);
-str AX3aggrX3_min3(int *ret, int *bid, int *gid, int *eid);
 str BATPCREilike(int *ret, int *b, str *pat, str *esc);
 str BATPCREilike2(int *ret, int *b, str *pat);
 str BATPCRElike(int *ret, int *b, str *pat, str *esc);
diff --git a/gdk/gdk_calc.c b/gdk/gdk_calc.c
--- a/gdk/gdk_calc.c
+++ b/gdk/gdk_calc.c
@@ -11068,3 +11068,293 @@ BATgroupsize(BAT *b, BAT *g, BAT *e, BAT
        bn->T->nonil = 1;
        return bn;
 }
+
+#define AGGR_CMP(TYPE, OP)                                             \
+       do {                                                            \
+               const TYPE *vals = (const TYPE *) Tloc(b, BUNfirst(b)); \
+               for (i = start; i < end; i++) {                         \
+                       if (cand) {                                     \
+                               if (i < *cand - b->hseqbase) {          \
+                                       if (gids)                       \
+                                               gids++;                 \
+                                       continue;                       \
+                               }                                       \
+                               assert(i == *cand - b->hseqbase);       \
+                               if (++cand == candend)                  \
+                                       end = i + 1;                    \
+                       }                                               \
+                       if (gids == NULL ||                             \
+                           (*gids >= min && *gids <= max)) {           \
+                               gid = gids ? *gids - min : (oid) i;     \
+                               if (!skip_nils || vals[i] != TYPE##_nil) { \
+                                       if (oids[gid] == oid_nil) {     \
+                                               oids[gid] = i + b->hseqbase; \
+                                               nils--;                 \
+                                       } else if (vals[oids[gid] - 
b->hseqbase] != TYPE##_nil && \
+                                                  (vals[i] == TYPE##_nil || \
+                                                   OP(vals[i], vals[oids[gid] 
- b->hseqbase]))) \
+                                               oids[gid] = i + b->hseqbase; \
+                               }                                       \
+                       }                                               \
+                       if (gids)                                       \
+                               gids++;                                 \
+               }                                                       \
+       } while (0)
+
+/* calculate group minimums with optional candidates list */
+BAT *
+BATgroupmin(BAT *b, BAT *g, BAT *e, BAT *s, int tp, int skip_nils, int 
abort_on_error)
+{
+       const oid *gids;
+       oid gid;
+       oid min, max;
+       BUN i, ngrp;
+       oid *oids;
+       BAT *bn = NULL;
+       BUN nils;
+       int t;
+       const void *nil;
+       int (*atomcmp)(const void *, const void *);
+       BATiter bi;
+       BUN start, end, cnt;
+       const oid *cand = NULL, *candend = NULL;
+
+       assert(tp == TYPE_oid);
+       (void) tp;              /* compatibility (with other BATgroup* */
+       (void) abort_on_error;  /* functions) argument */
+
+       if (!ATOMlinear(b->ttype)) {
+               GDKerror("BATgroupmin: cannot determine minimum on "
+                        "non-linear type %s\n", ATOMname(b->ttype));
+               return NULL;
+       }
+
+       if (initgroupaggr(b, g, e, s, &min, &max, &ngrp,
+                         &start, &end, &cnt, &cand, &candend) == GDK_FAIL)
+               return NULL;
+
+       if (BATcount(b) == 0 || ngrp == 0) {
+               /* trivial: no products, so return bat aligned with g
+                * with nil in the tail */
+               bn = BATconstant(TYPE_oid, &oid_nil, ngrp);
+               BATseqbase(bn, ngrp == 0 ? 0 : min);
+               return bn;
+       }
+
+       bn = BATnew(TYPE_void, TYPE_oid, ngrp);
+       if (bn == NULL)
+               return NULL;
+       oids = (oid *) Tloc(bn, BUNfirst(bn));
+       nils = ngrp;
+       for (i = 0; i < ngrp; i++)
+               oids[i] = oid_nil;
+
+       if (BATtdense(g))
+               gids = NULL;
+       else
+               gids = (const oid *) Tloc(g, BUNfirst(g) + start);
+
+       t = b->T->type;
+       nil = ATOMnilptr(t);
+       atomcmp = BATatoms[t].atomCmp;
+       if (t != ATOMstorage(t) &&
+           ATOMnilptr(ATOMstorage(t)) == nil &&
+           BATatoms[ATOMstorage(t)].atomCmp == atomcmp)
+               t = ATOMstorage(t);
+       switch (t) {
+       case TYPE_bte:
+               AGGR_CMP(bte, LT);
+               break;
+       case TYPE_sht:
+               AGGR_CMP(sht, LT);
+               break;
+       case TYPE_int:
+               AGGR_CMP(int, LT);
+               break;
+       case TYPE_oid:
+               AGGR_CMP(oid, LT);
+               break;
+       case TYPE_lng:
+               AGGR_CMP(lng, LT);
+               break;
+       case TYPE_flt:
+               AGGR_CMP(flt, LT);
+               break;
+       case TYPE_dbl:
+               AGGR_CMP(dbl, LT);
+               break;
+       default:
+               bi = bat_iterator(b);
+
+               for (i = start; i < end; i++) {
+                       if (cand) {
+                               if (i < *cand - b->hseqbase) {
+                                       if (gids)
+                                               gids++;
+                                       continue;
+                               }
+                               assert(i == *cand - b->hseqbase);
+                               if (++cand == candend)
+                                       end = i + 1;
+                       }
+                       if (gids == NULL ||
+                           (*gids >= min && *gids <= max)) {
+                               const void *v = BUNtail(bi, i + BUNfirst(b));
+                               gid = gids ? *gids - min : (oid) i;
+                               if (!skip_nils || (*atomcmp)(v, nil) != 0) {
+                                       if (oids[gid] == oid_nil) {
+                                               oids[gid] = i + b->hseqbase;
+                                               nils--;
+                                       } else {
+                                               const void *g = BUNtail(bi, 
(BUN) (oids[gid] - b->hseqbase) + BUNfirst(b));
+                                               if ((*atomcmp)(g, nil) != 0 &&
+                                                  ((*atomcmp)(v, nil) == 0 ||
+                                                   LT((*atomcmp)(v, g), 0)))
+                                                       oids[gid] = i + 
b->hseqbase;
+                                       }
+                               }
+                       }
+                       if (gids)
+                               gids++;
+               }
+               break;
+       }
+       BATsetcount(bn, ngrp);
+
+       BATseqbase(bn, min);
+       bn->tkey = BATcount(bn) <= 1;
+       bn->tsorted = BATcount(bn) <= 1;
+       bn->trevsorted = BATcount(bn) <= 1;
+       bn->T->nil = nils != 0;
+       bn->T->nonil = nils == 0;
+       return bn;
+}
+
+/* calculate group maximums with optional candidates list */
+BAT *
+BATgroupmax(BAT *b, BAT *g, BAT *e, BAT *s, int tp, int skip_nils, int 
abort_on_error)
+{
+       const oid *gids;
+       oid gid;
+       oid min, max;
+       BUN i, ngrp;
+       oid *oids;
+       BAT *bn = NULL;
+       BUN nils;
+       int t;
+       const void *nil;
+       int (*atomcmp)(const void *, const void *);
+       BATiter bi;
+       BUN start, end, cnt;
+       const oid *cand = NULL, *candend = NULL;
+
+       assert(tp == TYPE_oid);
+       (void) tp;              /* compatibility (with other BATgroup* */
+       (void) abort_on_error;  /* functions) argument */
+
+       if (!ATOMlinear(b->ttype)) {
+               GDKerror("BATgroupmax: cannot determine maximum on "
+                        "non-linear type %s\n", ATOMname(b->ttype));
+               return NULL;
+       }
+
+       if (initgroupaggr(b, g, e, s, &min, &max, &ngrp,
+                         &start, &end, &cnt, &cand, &candend) == GDK_FAIL)
+               return NULL;
+
+       if (BATcount(b) == 0 || ngrp == 0) {
+               /* trivial: no products, so return bat aligned with g
+                * with nil in the tail */
+               bn = BATconstant(TYPE_oid, &oid_nil, ngrp);
+               BATseqbase(bn, ngrp == 0 ? 0 : min);
+               return bn;
+       }
+
+       bn = BATnew(TYPE_void, TYPE_oid, ngrp);
+       if (bn == NULL)
+               return NULL;
+       oids = (oid *) Tloc(bn, BUNfirst(bn));
+       nils = ngrp;
+       for (i = 0; i < ngrp; i++)
+               oids[i] = oid_nil;
+
+       if (BATtdense(g))
+               gids = NULL;
+       else
+               gids = (const oid *) Tloc(g, BUNfirst(g) + start);
+
+       t = b->T->type;
+       nil = ATOMnilptr(t);
+       atomcmp = BATatoms[t].atomCmp;
+       if (t != ATOMstorage(t) &&
+           ATOMnilptr(ATOMstorage(t)) == nil &&
+           BATatoms[ATOMstorage(t)].atomCmp == atomcmp)
+               t = ATOMstorage(t);
+       switch (t) {
+       case TYPE_bte:
+               AGGR_CMP(bte, GT);
+               break;
+       case TYPE_sht:
+               AGGR_CMP(sht, GT);
+               break;
+       case TYPE_int:
+               AGGR_CMP(int, GT);
+               break;
+       case TYPE_oid:
+               AGGR_CMP(oid, GT);
+               break;
+       case TYPE_lng:
+               AGGR_CMP(lng, GT);
+               break;
+       case TYPE_flt:
+               AGGR_CMP(flt, GT);
+               break;
+       case TYPE_dbl:
+               AGGR_CMP(dbl, GT);
+               break;
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to