Changeset: ca8523f3a99c for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ca8523f3a99c Modified Files: gdk/gdk_analytic.h gdk/gdk_analytic_bounds.c gdk/gdk_analytic_func.c sql/backends/monet5/sql.c sql/backends/monet5/sql_rank.c sql/backends/monet5/sql_rank.h sql/test/analytics/Tests/analytics03.stable.err Branch: window-tunning Log Message:
first_value and last_value with proper frame support. This was needed to pair with the aggregate implementations. Also fixed small issues, both partition and order array may point to the same memory region, so they can overlap diffs (truncated from 736 to 300 lines): diff --git a/gdk/gdk_analytic.h b/gdk/gdk_analytic.h --- a/gdk/gdk_analytic.h +++ b/gdk/gdk_analytic.h @@ -25,8 +25,8 @@ gdk_export gdk_return GDKanalyticalwindo int tp1, int tp2, int unit, bool preceding, lng first_half); -gdk_export gdk_return GDKanalyticalfirst(BAT *r, BAT *b, BAT *s, BAT *e, int tpe); -gdk_export gdk_return GDKanalyticallast(BAT *r, BAT *b, BAT *s, BAT *e, int tpe); +gdk_export gdk_return GDKanalyticalfirst(BAT *r, BAT *p, BAT *o, BAT *b, BAT *s, BAT *e, int tpe, int frame_type); +gdk_export gdk_return GDKanalyticallast(BAT *r, BAT *p, BAT *o, BAT *b, BAT *s, BAT *e, int tpe, int frame_type); gdk_export gdk_return GDKanalyticalnthvalue(BAT *r, BAT *b, BAT *s, BAT *e, BAT *l, const void *restrict bound, int tp1, int tp2); gdk_export gdk_return GDKanalyticalmin(BAT *r, BAT *p, BAT *o, BAT *b, BAT *s, BAT *e, int tpe, int frame_type); diff --git a/gdk/gdk_analytic_bounds.c b/gdk/gdk_analytic_bounds.c --- a/gdk/gdk_analytic_bounds.c +++ b/gdk/gdk_analytic_bounds.c @@ -183,8 +183,6 @@ GDKanalyticaldiff(BAT *r, BAT *b, BAT *p if (is_##TPE##_nil(olimit) || olimit < 0) \ goto invalid_bound; \ rlimit = UPCAST; \ - if (is_lng_nil(rlimit) || rlimit < 0) \ - goto invalid_bound; \ for (j = k; ; j--) { \ if (j == m) { \ j++; \ @@ -552,7 +550,7 @@ GDKanalyticalallbounds(BAT *r, BAT *b, B rb[k] = i; } - BATsetcount(r, cnt); + BATsetcount(r, (BUN) cnt); r->tnonil = false; r->tnil = false; return GDK_SUCCEED; @@ -655,7 +653,7 @@ GDKanalyticalrowbounds(BAT *r, BAT *b, B } } - BATsetcount(r, cnt); + BATsetcount(r, (BUN) cnt); r->tnonil = (nils == 0); r->tnil = (nils > 0); return GDK_SUCCEED; @@ -674,7 +672,7 @@ static gdk_return GDKanalyticalrangebounds(BAT *r, BAT *b, BAT *p, BAT *l, const void *restrict bound, int tp1, int tp2, bool preceding) { lng cnt = (lng) BATcount(b), nils = 0, *restrict rb = (lng *) Tloc(r, 0), i = 0, k = 0, j = 0; - bit *np = p ? (bit *) Tloc(p, 0) : NULL; + bit *restrict np = p ? (bit *) Tloc(p, 0) : NULL; BATiter bpi = bat_iterator(b); int (*atomcmp) (const void *, const void *) = ATOMcompare(tp1); const void *nil = ATOMnilptr(tp1); @@ -849,7 +847,7 @@ GDKanalyticalrangebounds(BAT *r, BAT *b, goto bound_not_supported; } } - BATsetcount(r, cnt); + BATsetcount(r, (BUN) cnt); r->tnonil = (nils == 0); r->tnil = (nils > 0); return GDK_SUCCEED; @@ -967,7 +965,7 @@ GDKanalyticalgroupsbounds(BAT *r, BAT *b ANALYTICAL_WINDOW_BOUNDS_BRANCHES_GROUPS(_FOLLOWING, lng, limit, olimit); } } - BATsetcount(r, cnt); + BATsetcount(r, (BUN) cnt); return GDK_SUCCEED; bound_not_supported: GDKerror("42000!groups frame bound type %s not supported.\n", ATOMname(tp2)); diff --git a/gdk/gdk_analytic_func.c b/gdk/gdk_analytic_func.c --- a/gdk/gdk_analytic_func.c +++ b/gdk/gdk_analytic_func.c @@ -152,139 +152,219 @@ nosupport: return GDK_FAIL; } -#define ANALYTICAL_FIRST_IMP(TPE) \ +#define ANALYTICAL_FIRST_LAST_PARTITIONS(TPE, IMP) \ + do { \ + TPE *bp = (TPE*)Tloc(b, 0), *restrict rb = (TPE*)Tloc(r, 0); \ + if (p) { \ + for (; i < cnt; i++) { \ + if (np[i]) \ + ANALYTICAL_FIRST_LAST_FIXED_##IMP(TPE); \ + } \ + } \ + i = cnt; \ + ANALYTICAL_FIRST_LAST_FIXED_##IMP(TPE); \ + } while (0) + +#ifdef HAVE_HGE +#define ANALYTICAL_FIRST_LAST_LIMIT(IMP) \ + case TYPE_hge: \ + ANALYTICAL_FIRST_LAST_PARTITIONS(hge, IMP); \ + break; +#else +#define ANALYTICAL_FIRST_LAST_LIMIT(IMP) +#endif + +#define ANALYTICAL_FIRST_LAST_BRANCHES(IMP) \ + do { \ + switch (ATOMbasetype(tpe)) { \ + case TYPE_bte: \ + ANALYTICAL_FIRST_LAST_PARTITIONS(bte, IMP); \ + break; \ + case TYPE_sht: \ + ANALYTICAL_FIRST_LAST_PARTITIONS(sht, IMP); \ + break; \ + case TYPE_int: \ + ANALYTICAL_FIRST_LAST_PARTITIONS(int, IMP); \ + break; \ + case TYPE_lng: \ + ANALYTICAL_FIRST_LAST_PARTITIONS(lng, IMP); \ + break; \ + ANALYTICAL_FIRST_LAST_LIMIT(IMP) \ + case TYPE_flt: \ + ANALYTICAL_FIRST_LAST_PARTITIONS(flt, IMP); \ + break; \ + case TYPE_dbl: \ + ANALYTICAL_FIRST_LAST_PARTITIONS(dbl, IMP); \ + break; \ + default: { \ + if (p) { \ + for (; i < cnt; i++) { \ + if (np[i]) \ + ANALYTICAL_FIRST_LAST_VARSIZED_##IMP; \ + } \ + } \ + i = cnt; \ + ANALYTICAL_FIRST_LAST_VARSIZED_##IMP; \ + } \ + } \ + } while (0) + +#define ANALYTICAL_FIRST_LAST_FIXED_F_TRIVIAL(TPE) \ + do { \ + TPE curval = bp[k]; \ + for (; k < i; k++) \ + rb[k] = curval; \ + has_nils |= is_##TPE##_nil(curval); \ + } while (0) + +#define ANALYTICAL_FIRST_LAST_FIXED_F_CURRENT_ROW(TPE) \ + do { \ + for (; k < i; k++) { \ + TPE v = bp[k]; \ + rb[k] = v; \ + has_nils |= is_##TPE##_nil(v); \ + } \ + } while (0) + +#define ANALYTICAL_FIRST_LAST_FIXED_F_OTHERS(TPE) \ do { \ - TPE *bp, *bs, *be, curval, *restrict rb; \ - bp = (TPE*)Tloc(b, 0); \ - rb = (TPE*)Tloc(r, 0); \ - for (; i < cnt; i++, rb++) { \ - bs = bp + start[i]; \ - be = bp + end[i]; \ - curval = (be > bs) ? *bs : TPE##_nil; \ - *rb = curval; \ + for (; k < i; k++) { \ + TPE *bs = bp + start[k], *be = bp + end[k]; \ + TPE curval = (be > bs) ? *bs : TPE##_nil; \ + rb[k] = curval; \ has_nils |= is_##TPE##_nil(curval); \ } \ } while (0) -gdk_return -GDKanalyticalfirst(BAT *r, BAT *b, BAT *s, BAT *e, int tpe) -{ - BUN i = 0, cnt = BATcount(b); - lng *restrict start, *restrict end; - bool has_nils = false; +#define ANALYTICAL_FIRST_LAST_VARSIZED_F_TRIVIAL \ + do { \ + const void *curval = BUNtail(bpi, k); \ + for (; k < i; k++) \ + if (tfastins_nocheckVAR(r, k, curval, Tsize(r)) != GDK_SUCCEED) \ + return GDK_FAIL; \ + has_nils |= atomcmp(curval, nil) == 0; \ + } while (0) - assert(s && e); - start = (lng *) Tloc(s, 0); - end = (lng *) Tloc(e, 0); +#define ANALYTICAL_FIRST_LAST_VARSIZED_F_CURRENT_ROW \ + do { \ + for (; k < i; k++) { \ + const void *curval = BUNtail(bpi, k); \ + if (tfastins_nocheckVAR(r, k, curval, Tsize(r)) != GDK_SUCCEED) \ + return GDK_FAIL; \ + has_nils |= atomcmp(curval, nil) == 0; \ + } \ + } while (0) - switch (ATOMbasetype(tpe)) { - case TYPE_bte: - ANALYTICAL_FIRST_IMP(bte); - break; - case TYPE_sht: - ANALYTICAL_FIRST_IMP(sht); - break; - case TYPE_int: - ANALYTICAL_FIRST_IMP(int); - break; - case TYPE_lng: - ANALYTICAL_FIRST_IMP(lng); - break; -#ifdef HAVE_HGE - case TYPE_hge: - ANALYTICAL_FIRST_IMP(hge); - break; -#endif - case TYPE_flt: - ANALYTICAL_FIRST_IMP(flt); - break; - case TYPE_dbl: - ANALYTICAL_FIRST_IMP(dbl); - break; - default:{ - const void *restrict nil = ATOMnilptr(tpe); - int (*atomcmp) (const void *, const void *) = ATOMcompare(tpe); - BATiter bpi = bat_iterator(b); - void *curval; +#define ANALYTICAL_FIRST_LAST_VARSIZED_F_OTHERS \ + do { \ + for (; k < i; k++) { \ + const void *curval = (end[k] > start[k]) ? BUNtail(bpi, start[k]) : nil; \ + if (tfastins_nocheckVAR(r, k, curval, Tsize(r)) != GDK_SUCCEED) \ + return GDK_FAIL; \ + has_nils |= atomcmp(curval, nil) == 0; \ + } \ + } while (0) - for (; i < cnt; i++) { - curval = (end[i] > start[i]) ? BUNtail(bpi, (BUN) start[i]) : (void *) nil; - if (BUNappend(r, curval, false) != GDK_SUCCEED) - return GDK_FAIL; - has_nils |= atomcmp(curval, nil) == 0; - } +gdk_return +GDKanalyticalfirst(BAT *r, BAT *p, BAT *o, BAT *b, BAT *s, BAT *e, int tpe, int frame_type) +{ + bool has_nils = false; + lng i = 0, k = 0, cnt = (lng) BATcount(b); + lng *restrict start = s ? (lng*)Tloc(s, 0) : NULL, *restrict end = e ? (lng*)Tloc(e, 0) : NULL; + bit *restrict np = p ? Tloc(p, 0) : NULL; + BATiter bpi = bat_iterator(b); + const void *nil = ATOMnilptr(tpe); + int (*atomcmp)(const void *, const void *) = ATOMcompare(tpe); + + (void) o; + switch (frame_type) { + case 3: + case 4: + case 5: { + ANALYTICAL_FIRST_LAST_BRANCHES(F_TRIVIAL); + } break; + case 6: /* current row */ { + ANALYTICAL_FIRST_LAST_BRANCHES(F_CURRENT_ROW); + } break; + default: { + ANALYTICAL_FIRST_LAST_BRANCHES(F_OTHERS); } } - BATsetcount(r, cnt); + + BATsetcount(r, (BUN) cnt); r->tnonil = !has_nils; r->tnil = has_nils; return GDK_SUCCEED; } -#define ANALYTICAL_LAST_IMP(TPE) \ - do { \ - TPE *bp, *bs, *be, curval, *restrict rb; \ - bp = (TPE*)Tloc(b, 0); \ - rb = (TPE*)Tloc(r, 0); \ - for (; i<cnt; i++, rb++) { \ - bs = bp + start[i]; \ - be = bp + end[i]; \ - curval = (be > bs) ? *(be - 1) : TPE##_nil; \ - *rb = curval; \ - has_nils |= is_##TPE##_nil(curval); \ - } \ +#define ANALYTICAL_FIRST_LAST_FIXED_L_TRIVIAL(TPE) \ + do { \ + TPE curval = bp[i - 1]; \ + for (; k < i; k++) \ + rb[k] = curval; \ + has_nils |= is_##TPE##_nil(curval); \ + } while (0) + +#define ANALYTICAL_FIRST_LAST_FIXED_L_CURRENT_ROW(TPE) ANALYTICAL_FIRST_LAST_FIXED_F_CURRENT_ROW(TPE) + +#define ANALYTICAL_FIRST_LAST_FIXED_L_OTHERS(TPE) \ _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list