Changeset: eea65160b08c for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=eea65160b08c
Modified Files:
        gdk/gdk_analytic_func.c
Branch: window-tunning
Log Message:

Updated avg returning dbl function. Now all window aggregates execpt 
str_group_concat (too complex to implement) use a segment tree for the general 
scenario


diffs (truncated from 358 to 300 lines):

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
@@ -2211,15 +2211,19 @@ nosupport:
 }
 
 #ifdef HAVE_HGE
-#define LNG_HGE hge
+#define LNG_HGE         hge
+#define GDK_LNG_HGE_max GDK_hge_max
+#define LNG_HGE_nil     hge_nil
 #else
-#define LNG_HGE lng
+#define LNG_HGE         lng
+#define GDK_LNG_HGE_max GDK_lng_max
+#define LNG_HGE_nil     lng_nil
 #endif
 
 /* average on integers */
-#define ANALYTICAL_AVERAGE_CALC_NUM_STEP1(TPE, IMP, PART, LNG_HGE, ARG) \
+#define ANALYTICAL_AVERAGE_CALC_NUM_STEP1(TPE, IMP, PART, ARG) \
        if (!is_##TPE##_nil(ARG)) {             \
-               ADD_WITH_CHECK(ARG, sum, LNG_HGE, sum, GDK_##LNG_HGE##_max, 
goto avg_overflow##TPE##IMP##PART); \
+               ADD_WITH_CHECK(ARG, sum, LNG_HGE, sum, GDK_LNG_HGE_max, goto 
avg_overflow##TPE##IMP##PART); \
                /* count only when no overflow occurs */ \
                n++;                            \
        }
@@ -2241,14 +2245,14 @@ avg_overflow##TPE##IMP##PART:                           
                        \
                                        }                               \
                                }
 
-#define ANALYTICAL_AVG_IMP_NUM_UNBOUNDED_TILL_CURRENT_ROW(TPE, IMP, PART, 
LNG_HGE) \
+#define ANALYTICAL_AVG_IMP_NUM_UNBOUNDED_TILL_CURRENT_ROW(TPE, IMP, PART) \
        do { \
                TPE a = 0; \
                dbl curval = dbl_nil;   \
                for (; k < i;) { \
                        j = k; \
                        do {    \
-                               ANALYTICAL_AVERAGE_CALC_NUM_STEP1(TPE, IMP, 
PART, LNG_HGE, bp[k]) \
+                               ANALYTICAL_AVERAGE_CALC_NUM_STEP1(TPE, IMP, 
PART, bp[k]) \
                                ANALYTICAL_AVERAGE_CALC_NUM_STEP2(TPE, IMP, 
PART) \
                                        while (k < i && !op[k]) { \
                                                TPE v = bp[k++];                
        \
@@ -2271,13 +2275,13 @@ calc_done##TPE##IMP##PART: \
                sum = 0;                        \
        } while (0)
 
-#define ANALYTICAL_AVG_IMP_NUM_CURRENT_ROW_TILL_UNBOUNDED(TPE, IMP, PART, 
LNG_HGE) \
+#define ANALYTICAL_AVG_IMP_NUM_CURRENT_ROW_TILL_UNBOUNDED(TPE, IMP, PART) \
        do { \
                TPE a = 0; \
                dbl curval = dbl_nil;   \
                l = i - 1; \
                for (j = l; ; j--) { \
-                       ANALYTICAL_AVERAGE_CALC_NUM_STEP1(TPE, IMP, PART, 
LNG_HGE, bp[j]) \
+                       ANALYTICAL_AVERAGE_CALC_NUM_STEP1(TPE, IMP, PART, 
bp[j]) \
                        ANALYTICAL_AVERAGE_CALC_NUM_STEP2(TPE, IMP, PART) \
                                while (!(op[j] || j == k)) { \
                                        TPE v = bp[j--];                        
\
@@ -2307,12 +2311,12 @@ calc_done##TPE##IMP##PART: \
                k = i; \
        } while (0)
 
-#define ANALYTICAL_AVG_IMP_NUM_ALL_ROWS(TPE, IMP, PART, LNG_HGE)       \
+#define ANALYTICAL_AVG_IMP_NUM_ALL_ROWS(TPE, IMP, PART)        \
        do { \
                TPE a = 0; \
                for (; j < i; j++) { \
                        TPE v = bp[j]; \
-                       ANALYTICAL_AVERAGE_CALC_NUM_STEP1(TPE, IMP, PART, 
LNG_HGE, v) \
+                       ANALYTICAL_AVERAGE_CALC_NUM_STEP1(TPE, IMP, PART, v) \
                        ANALYTICAL_AVERAGE_CALC_NUM_STEP2(TPE, IMP, PART) \
                                for (; j < i; j++) { \
                                        v = bp[j];                      \
@@ -2333,7 +2337,7 @@ calc_done##TPE##IMP##PART: \
                sum = 0;                        \
        } while (0)
 
-#define ANALYTICAL_AVG_IMP_NUM_CURRENT_ROW(TPE, IMP, PART, LNG_HGE)    \
+#define ANALYTICAL_AVG_IMP_NUM_CURRENT_ROW(TPE, IMP, PART)     \
        do { \
                for (; k < i; k++) { \
                        TPE v = bp[k]; \
@@ -2346,37 +2350,46 @@ calc_done##TPE##IMP##PART: \
                } \
        } while (0)
 
-#define ANALYTICAL_AVG_IMP_NUM_OTHERS(TPE, IMP, PART, LNG_HGE) \
-       do {                                                            \
-               TPE *be = 0, *bs = 0, a = 0;     \
-               for (; k < i; k++) {                            \
-                       bs = bp + start[k];                             \
-                       be = bp + end[k];                               \
-                       for (; bs < be; bs++) {                         \
-                               TPE v = *bs;                            \
-                               ANALYTICAL_AVERAGE_CALC_NUM_STEP1(TPE, IMP, 
PART, LNG_HGE, v) \
-                       }                                               \
-                       ANALYTICAL_AVERAGE_CALC_NUM_STEP2(TPE, IMP, PART) \
-                               for (; bs < be; bs++) {                 \
-                                       TPE v = *bs;                    \
-                                       if (is_##TPE##_nil(v))          \
-                                               continue;               \
-                                       AVERAGE_ITER(TPE, v, a, rr, n); \
-                               }                                       \
-                               curval = a + (dbl) rr / n;              \
-                               goto calc_done##TPE##IMP##PART;                 
\
-                       }       \
-                       curval = n > 0 ? (dbl) sum / n : dbl_nil;       \
-calc_done##TPE##IMP##PART: \
-                       rb[k] = curval;                                 \
-                       has_nils |= (n == 0);           \
-                       n = 0;                          \
-                       sum = 0;                        \
-               }                                                       \
+typedef struct avg_num_deltas {lng n; LNG_HGE sum;} avg_num_deltas; /* TODO 
add overflow check */
+
+#define INIT_AGGREGATE_AVG_NUM(TPE, NOTHING1, NOTHING2) \
+       do { \
+               computed = (avg_num_deltas) {.n = 0, .sum = 0}; \
+       } while (0)
+#define COMPUTE_LEVEL0_AVG_NUM(X, TPE, NOTHING1, NOTHING2) \
+       do { \
+               TPE v = bp[j + X]; \
+               computed = is_##TPE##_nil(v) ? (avg_num_deltas) {.n = 0, .sum = 
0} : (avg_num_deltas) {.n = 1, .sum = (LNG_HGE)v}; \
+       } while (0)
+#define COMPUTE_LEVELN_AVG_NUM(VAL, TPE, NOTHING1, NOTHING2) \
+       do { \
+               if (VAL.n > 0) { \
+                       ADD_WITH_CHECK(VAL.sum, computed.sum, LNG_HGE, 
computed.sum, GDK_LNG_HGE_max, goto calc_overflow); \
+                       computed.n++; \
+               }               \
+       } while (0)
+#define FINALIZE_AGGREGATE_AVG_NUM(TPE, NOTHING1, NOTHING2) \
+       do { \
+               if (computed.n == 0) {  \
+                       rb[k] = dbl_nil;        \
+                       has_nils = true; \
+               } else { \
+                       rb[k] = ((dbl) computed.sum) / computed.n;      \
+               } \
+       } while (0)
+#define ANALYTICAL_AVG_IMP_NUM_OTHERS(TPE, IMP, PART)  \
+       do { \
+               oid ncount = i - k; \
+               if ((res = GDKrebuild_segment_tree(ncount, 
sizeof(avg_num_deltas), &segment_tree, &tree_capacity, &levels_offset, 
&levels_capacity, &nlevels)) != GDK_SUCCEED) \
+                       goto cleanup; \
+               populate_segment_tree(avg_num_deltas, ncount, 
INIT_AGGREGATE_AVG_NUM, COMPUTE_LEVEL0_AVG_NUM, COMPUTE_LEVELN_AVG_NUM, TPE, 
NOTHING, NOTHING); \
+               for (; k < i; k++) \
+                       compute_on_segment_tree(avg_num_deltas, start[k] - j, 
end[k] - j, INIT_AGGREGATE_AVG_NUM, COMPUTE_LEVELN_AVG_NUM, 
FINALIZE_AGGREGATE_AVG_NUM, TPE, NOTHING, NOTHING); \
+               j = k; \
        } while (0)
 
 /* average on floating-points */
-#define ANALYTICAL_AVG_IMP_FP_UNBOUNDED_TILL_CURRENT_ROW(TPE, IMP, PART, 
LNG_HGE) \
+#define ANALYTICAL_AVG_IMP_FP_UNBOUNDED_TILL_CURRENT_ROW(TPE, IMP, PART) \
        do { \
                TPE a = 0; \
                dbl curval = dbl_nil;   \
@@ -2397,7 +2410,7 @@ calc_done##TPE##IMP##PART: \
                n = 0;                  \
        } while (0)
 
-#define ANALYTICAL_AVG_IMP_FP_CURRENT_ROW_TILL_UNBOUNDED(TPE, IMP, PART, 
LNG_HGE) \
+#define ANALYTICAL_AVG_IMP_FP_CURRENT_ROW_TILL_UNBOUNDED(TPE, IMP, PART) \
        do { \
                TPE a = 0; \
                dbl curval = dbl_nil;   \
@@ -2421,7 +2434,7 @@ calc_done##TPE##IMP##PART: \
                k = i; \
        } while (0)
 
-#define ANALYTICAL_AVG_IMP_FP_ALL_ROWS(TPE, IMP, PART, LNG_HGE)        \
+#define ANALYTICAL_AVG_IMP_FP_ALL_ROWS(TPE, IMP, PART) \
        do { \
                TPE a = 0; \
                dbl curval = dbl_nil;   \
@@ -2439,69 +2452,89 @@ calc_done##TPE##IMP##PART: \
                n = 0;          \
        } while (0)
 
-#define ANALYTICAL_AVG_IMP_FP_CURRENT_ROW(TPE, IMP, PART, LNG_HGE)      
ANALYTICAL_AVG_IMP_NUM_CURRENT_ROW(TPE, IMP, PART, LNG_HGE)
+#define ANALYTICAL_AVG_IMP_FP_CURRENT_ROW(TPE, IMP, PART)       
ANALYTICAL_AVG_IMP_NUM_CURRENT_ROW(TPE, IMP, PART)
+
+#define avg_fp_deltas(TPE) typedef struct avg_fp_deltas_##TPE {TPE a; lng n;} 
avg_fp_deltas_##TPE;
+avg_fp_deltas(flt)
+avg_fp_deltas(dbl)
 
-#define ANALYTICAL_AVG_IMP_FP_OTHERS(TPE, IMP, PART, LNG_HGE)                  
\
-       do {                                                            \
-               TPE a = 0; \
-               for (; k < i; k++) {                            \
-                       TPE *bs = bp + start[k];                                
\
-                       TPE *be = bp + end[k];                          \
-                       for (; bs < be; bs++) {                         \
-                               TPE v = *bs;                            \
-                               if (!is_##TPE##_nil(v))                 \
-                                       AVERAGE_ITER_FLOAT(TPE, v, a, n); \
-                       }                                               \
-                       curval = (n > 0) ? a : dbl_nil;                 \
-                       rb[k] = curval;                                 \
-                       has_nils |= (n == 0);           \
-                       n = 0;                  \
-               }                                                       \
+#define INIT_AGGREGATE_AVG_FP(TPE, NOTHING1, NOTHING2) \
+       do { \
+               computed = (avg_fp_deltas_##TPE) {.n = 0, .a = 0}; \
+       } while (0)
+#define COMPUTE_LEVEL0_AVG_FP(X, TPE, NOTHING1, NOTHING2) \
+       do { \
+               TPE v = bp[j + X]; \
+               computed = is_##TPE##_nil(v) ? (avg_fp_deltas_##TPE) {.n = 0, 
.a = 0} : (avg_fp_deltas_##TPE) {.n = 1, .a = v}; \
+       } while (0)
+#define COMPUTE_LEVELN_AVG_FP(VAL, TPE, NOTHING1, NOTHING2) \
+       do { \
+               if (VAL.n > 0) \
+                       AVERAGE_ITER_FLOAT(TPE, VAL.a, computed.a, computed.n); 
\
+       } while (0)
+#define FINALIZE_AGGREGATE_AVG_FP(TPE, NOTHING1, NOTHING2) \
+       do { \
+               if (computed.n == 0) {  \
+                       rb[k] = dbl_nil;        \
+                       has_nils = true; \
+               } else { \
+                       rb[k] = computed.a;     \
+               } \
+       } while (0)
+#define ANALYTICAL_AVG_IMP_FP_OTHERS(TPE, IMP, PART)   \
+       do { \
+               oid ncount = i - k; \
+               if ((res = GDKrebuild_segment_tree(ncount, 
sizeof(avg_fp_deltas_##TPE), &segment_tree, &tree_capacity, &levels_offset, 
&levels_capacity, &nlevels)) != GDK_SUCCEED) \
+                       goto cleanup; \
+               populate_segment_tree(avg_fp_deltas_##TPE, ncount, 
INIT_AGGREGATE_AVG_FP, COMPUTE_LEVEL0_AVG_FP, COMPUTE_LEVELN_AVG_FP, TPE, 
NOTHING, NOTHING); \
+               for (; k < i; k++) \
+                       compute_on_segment_tree(avg_fp_deltas_##TPE, start[k] - 
j, end[k] - j, INIT_AGGREGATE_AVG_FP, COMPUTE_LEVELN_AVG_FP, 
FINALIZE_AGGREGATE_AVG_FP, TPE, NOTHING, NOTHING); \
+               j = k; \
        } while (0)
 
-#define ANALYTICAL_AVG_PARTITIONS(TPE, IMP, LNG_HGE, REAL_IMP)         \
+#define ANALYTICAL_AVG_PARTITIONS(TPE, IMP, REAL_IMP)          \
        do {                                            \
                TPE *bp = (TPE*)Tloc(b, 0); \
                if (p) {                                        \
                        for (; i < cnt; i++) {          \
                                if (np[i])                      \
-                                       REAL_IMP(TPE, IMP, P1, LNG_HGE);        
\
+                                       REAL_IMP(TPE, IMP, P1); \
                        }                                               \
                }                       \
                i = cnt;                                        \
-               REAL_IMP(TPE, IMP, P3, LNG_HGE);        \
+               REAL_IMP(TPE, IMP, P3); \
        } while (0)
 
 #ifdef HAVE_HGE
-#define ANALYTICAL_AVG_LIMIT(IMP, LNG_HGE) \
+#define ANALYTICAL_AVG_LIMIT(IMP) \
        case TYPE_hge: \
-               ANALYTICAL_AVG_PARTITIONS(hge, IMP, LNG_HGE, 
ANALYTICAL_AVG_IMP_NUM_##IMP); \
+               ANALYTICAL_AVG_PARTITIONS(hge, IMP, 
ANALYTICAL_AVG_IMP_NUM_##IMP); \
                break;
 #else
-#define ANALYTICAL_AVG_LIMIT(IMP, LNG_HGE)
+#define ANALYTICAL_AVG_LIMIT(IMP)
 #endif
 
-#define ANALYTICAL_AVG_BRANCHES(IMP, LNG_HGE)          \
+#define ANALYTICAL_AVG_BRANCHES(IMP)           \
        do { \
                switch (tpe) {  \
                case TYPE_bte:  \
-                       ANALYTICAL_AVG_PARTITIONS(bte, IMP, LNG_HGE, 
ANALYTICAL_AVG_IMP_NUM_##IMP);     \
+                       ANALYTICAL_AVG_PARTITIONS(bte, IMP, 
ANALYTICAL_AVG_IMP_NUM_##IMP);      \
                        break;  \
                case TYPE_sht:  \
-                       ANALYTICAL_AVG_PARTITIONS(sht, IMP, LNG_HGE, 
ANALYTICAL_AVG_IMP_NUM_##IMP);     \
+                       ANALYTICAL_AVG_PARTITIONS(sht, IMP, 
ANALYTICAL_AVG_IMP_NUM_##IMP);      \
                        break;  \
                case TYPE_int:  \
-                       ANALYTICAL_AVG_PARTITIONS(int, IMP, LNG_HGE, 
ANALYTICAL_AVG_IMP_NUM_##IMP);     \
+                       ANALYTICAL_AVG_PARTITIONS(int, IMP, 
ANALYTICAL_AVG_IMP_NUM_##IMP);      \
                        break;  \
                case TYPE_lng:  \
-                       ANALYTICAL_AVG_PARTITIONS(lng, IMP, LNG_HGE, 
ANALYTICAL_AVG_IMP_NUM_##IMP);     \
+                       ANALYTICAL_AVG_PARTITIONS(lng, IMP, 
ANALYTICAL_AVG_IMP_NUM_##IMP);      \
                        break;  \
-               ANALYTICAL_AVG_LIMIT(IMP, LNG_HGE)      \
+               ANALYTICAL_AVG_LIMIT(IMP)       \
                case TYPE_flt:  \
-                       ANALYTICAL_AVG_PARTITIONS(flt, IMP, LNG_HGE, 
ANALYTICAL_AVG_IMP_FP_##IMP);      \
+                       ANALYTICAL_AVG_PARTITIONS(flt, IMP, 
ANALYTICAL_AVG_IMP_FP_##IMP);       \
                        break;  \
                case TYPE_dbl:  \
-                       ANALYTICAL_AVG_PARTITIONS(dbl, IMP, LNG_HGE, 
ANALYTICAL_AVG_IMP_FP_##IMP);      \
+                       ANALYTICAL_AVG_PARTITIONS(dbl, IMP, 
ANALYTICAL_AVG_IMP_FP_##IMP);       \
                        break;  \
                default:        \
                        goto nosupport; \
@@ -2512,12 +2545,15 @@ gdk_return
 GDKanalyticalavg(BAT *r, BAT *p, BAT *o, BAT *b, BAT *s, BAT *e, int tpe, int 
frame_type)
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to