Added quantiling UDAFs
[com/gs-lite.git] / src / lib / gscphftaaux / hfta_udaf.cc
index 0660739..58cd34e 100644 (file)
-/* ------------------------------------------------
-Copyright 2014 AT&T Intellectual Property
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
- ------------------------------------------- */
-
-
-#include "gsconfig.h"
-#include "gstypes.h"
-#include "hfta_udaf.h"
-#include "rts_udaf.h"
-#include <stdio.h>
-#include <limits.h>
-#include <math.h>
-//#include <memory.h>
-#include <string.h>
-#include <sys/time.h>
-#include <iostream>
-
-#include "hfta_runtime_library.h"
-
-
-#define max(a,b) ((a) > (b) ? (a) : (b))
-#define min(x,y) ((x) < (y) ? (x) : (y))
-#define lg(x)    (log(x) / log(2))
-
-using namespace std;
-
-
-// -------------------------------------------------------------------
-//              moving sum over N intervals
-
-struct moving_sum_udaf_str{
-       gs_uint32_t N;
-       gs_uint32_t pos;
-       gs_uint32_t *sums;
-};
-
-void moving_sum_udaf_HFTA_AGGR_INIT_(gs_sp_t buf){
-  struct moving_sum_udaf_str * u = (struct moving_sum_udaf_str *) buf;
-  u->N=0; u->pos=0; u->sums=NULL;
-}
-
-void moving_sum_udaf_HFTA_AGGR_UPDATE_(gs_sp_t buf, gs_uint32_t s, gs_uint32_t N) {
-  struct moving_sum_udaf_str * u = (struct moving_sum_udaf_str *) buf;
-  if(u->sums == NULL){
-       u->sums = (gs_uint32_t *)malloc(N*sizeof(gs_uint32_t));
-       for(gs_int32_t i=0;i<N;i++)
-               u->sums[i] = 0;
-    u->N = N;
-  }
-  u->sums[u->pos] += s;
-}
-
-void super_moving_sum_udaf_HFTA_AGGR_UPDATE_(gs_sp_t  buf, gs_uint64_t sub_sum) {
-  struct moving_sum_udaf_str * u = (struct moving_sum_udaf_str *) buf;
-  gs_uint32_t s = (gs_uint32_t)(sub_sum & 0xffffffff);
-  if(u->sums == NULL){
-    gs_uint32_t N = (gs_uint32_t)((sub_sum & 0xffffffff00000000ull) >> 32);
-       u->sums = (gs_uint32_t *)malloc(N*sizeof(gs_uint32_t));
-       for(gs_int32_t i=0;i<N;i++)
-               u->sums[i] = 0;
-    u->N = N;
-  }
-  u->sums[u->pos] += s;
-}
-
-void moving_sum_udaf_HFTA_AGGR_OUTPUT_(gs_p_t *result, gs_sp_t  buf){
-       *result = (gs_p_t)(buf);
-}
-
-void moving_sum_udaf_HFTA_AGGR_DESTROY_(gs_sp_t  buf){
-  struct moving_sum_udaf_str * u = (struct moving_sum_udaf_str *) buf;
-  if(u->sums != NULL)
-       free(u->sums);
-}
-
-void moving_sum_udaf_HFTA_AGGR_REINIT_( gs_sp_t  buf){
-  struct moving_sum_udaf_str * u = (struct moving_sum_udaf_str *) buf;
-  u->pos++;
-  if(u->pos >= u->N)
-       u->pos = 0;
-  u->sums[u->pos] = 0;
-}
-
-gs_uint32_t moving_sum_extract(gs_p_t result){
-  struct moving_sum_udaf_str * u = (struct moving_sum_udaf_str *) result;
-  gs_uint32_t s=0, i=0;
-  for(i=0; i<u->N;i++){
-    s += u->sums[i];
-  }
-  return s;
-}
-
-gs_float_t moving_sum_extract_exp(gs_p_t result, gs_float_t alpha){
-  struct moving_sum_udaf_str * u = (struct moving_sum_udaf_str *) result;
-  gs_uint32_t p=0, i=0;
-  gs_float_t s=0.0, m=1.0;
-  p=u->pos;
-  for(i=0; i<u->N;i++){
-    s += u->sums[i]*m;
-    if(p==0)
-               p=u->N - 1;
-    else
-               p--;
-       m *= alpha;
-  }
-  return s;
-}
-
-
-// -------------------------------------------------------------------
-//              sum over 3 intervals : test rUDAF
-
-struct sum3_udaf_str{
-  gs_uint32_t s_2;
-  gs_uint32_t s_1;
-  gs_uint32_t s_0;
-};
-
-void sum3_HFTA_AGGR_INIT_(gs_sp_t  buf) {
-  struct sum3_udaf_str * u = (struct sum3_udaf_str *) buf;
-  u->s_0 = 0; u->s_1 = 0; u->s_2 = 0;
-  return;
-}          
-
-void sum3_HFTA_AGGR_UPDATE_(gs_sp_t  buf, gs_uint32_t s) {
-  struct sum3_udaf_str * u = (struct sum3_udaf_str *) buf;
-  u->s_0 += s;
-  return;
-}
-
-void sum3_HFTA_AGGR_OUTPUT_(gs_uint32_t *result, gs_sp_t  buf) {
-  struct sum3_udaf_str * u = (struct sum3_udaf_str *) buf;
-  *result = u->s_0 + u->s_1 + u->s_2;
-  return; 
-}
-
-void sum3_HFTA_AGGR_DESTROY_(gs_sp_t  buf) {
-  return;
-}
-
-void sum3_HFTA_AGGR_REINIT_( gs_sp_t  buf) {
-  struct sum3_udaf_str * u = (struct sum3_udaf_str *) buf;
-  u->s_2 = u->s_1;
-  u->s_1 = u->s_0;
-  u->s_0 = 0;
-  return;
-}
-
-
-#define HISTORY_LENGTH 1024
-
-/////////////////////////////////////////////////////////////////////////
-/////   Calculate the average of all positive gs_float_t numbers
-
-struct posavg_struct{
-  gs_float_t sum;
-  gs_float_t cnt;
-};
-
-void POSAVG_HFTA_AGGR_INIT_(gs_sp_t  buf) {
-  struct posavg_struct * a = (struct posavg_struct *) buf;
-  a->sum=0;
-  a->cnt=0;
-  return;
-}
-
-void POSAVG_HFTA_AGGR_UPDATE_(gs_sp_t  buf, gs_float_t v) {
-  struct posavg_struct * a = (struct posavg_struct *) buf;
-  if (v>=0) {
-    a->sum=a->sum+v;
-    a->cnt=a->cnt+1;
-  }
-  return;
-}
-
-void POSAVG_HFTA_AGGR_OUTPUT_(gs_float_t * v, gs_sp_t  buf) {
-  struct posavg_struct * a = (struct posavg_struct *) buf;
-  if (a->cnt>0) {
-    *v=(a->sum/a->cnt);
-  } else {
-    *v=-1;
-  }
-  return;
-}
-
-void POSAVG_HFTA_AGGR_DESTROY_(gs_sp_t  buf) {
-  return;
-}
-
-/////////////////////////////////////////////////////////////////////////
-/////                   avg_udaf (simple example)
-
-//              struct received from subaggregate
-struct avg_udaf_lfta_struct_t{
-        gs_int64_t  sum;
-        gs_uint32_t cnt;
-};
-
-//              sctarchpad struct
-struct avg_udaf_hfta_struct_t{
-        gs_int64_t sum;
-        gs_uint32_t cnt;
-};
-
-//                      avg_udaf functions
-void avg_udaf_HFTA_AGGR_INIT_(gs_sp_t b){
-        avg_udaf_hfta_struct_t *s = (avg_udaf_hfta_struct_t *) b;
-        s->sum = 0;
-        s->cnt = 0;
-}
-
-void avg_udaf_HFTA_AGGR_UPDATE_(gs_sp_t b, gs_uint32_t v){
-        avg_udaf_hfta_struct_t *s = (avg_udaf_hfta_struct_t *) b;
-        s->sum += v;
-        s->cnt ++;
-}
-
-void avg_udaf_HFTA_AGGR_OUTPUT_(vstring *r,gs_sp_t b){
-        r->length = 12;
-        r->offset = (gs_p_t)(b);
-        r->reserved = SHALLOW_COPY;
-}
-
-void avg_udaf_HFTA_AGGR_DESTROY_(gs_sp_t b){
-        return;
-}
-
-
-//                      avg_udaf superaggregate functions
-void avg_udaf_hfta_HFTA_AGGR_INIT_(gs_sp_t b){
-        avg_udaf_hfta_struct_t *s = (avg_udaf_hfta_struct_t *) b;
-        s->sum = 0;
-        s->cnt = 0;
-}
-
-void avg_udaf_hfta_HFTA_AGGR_UPDATE_(gs_sp_t b, vstring *v){
-        if(v->length != 12) return;
-        avg_udaf_hfta_struct_t *s = (avg_udaf_hfta_struct_t *) b;
-        avg_udaf_lfta_struct_t *vs = (avg_udaf_lfta_struct_t *)(v->offset);
-        s->sum += vs->sum;
-        s->cnt += vs->cnt;
-}
-
-void avg_udaf_hfta_HFTA_AGGR_OUTPUT_(vstring *r,gs_sp_t b){
-        r->length = 12;
-        r->offset = (gs_p_t)(b);
-        r->reserved = SHALLOW_COPY;
-}
-
-void avg_udaf_hfta_HFTA_AGGR_DESTROY_(gs_sp_t b){
-        return;
-}
-
-//              Extraction function
-gs_float_t extr_avg_fcn(vstring *v){
-        if(v->length != 12) return 0;
-        avg_udaf_hfta_struct_t *vs = (avg_udaf_hfta_struct_t *)(v->offset);
-        gs_float_t r = (gs_float_t)(vs->sum) / vs->cnt;
-    return r;
-}
-
-/////////////////////////////////////////////////////////
-//             FIRST aggregate
-// hfta only
-
-void FIRST_HFTA_AGGR_INIT_(gs_uint32_t* scratch) {
-       *scratch = UINT_MAX;            // we will encode uninitialized value of UINT_MAX
-}
-
-void FIRST_HFTA_AGGR_REINIT_(gs_uint32_t* scratch) { }
-
-void FIRST_HFTA_AGGR_UPDATE_(gs_uint32_t* scratch, gs_uint32_t val) {
-       if (*scratch == UINT_MAX)
-               *scratch = val;
-}
-
-void FIRST_HFTA_AGGR_OUTPUT_(gs_uint32_t* res, gs_uint32_t* scratch) {
-       *res = *scratch;
-}
-
-void FIRST_HFTA_AGGR_DESTROY_(gs_uint32_t* scratch) { }
-
-void FIRST_ULL_HFTA_AGGR_INIT_(gs_uint64_t* scratch) {
-       *scratch = UINT_MAX;            // we will encode uninitialized value of UINT_MAX
-}
-
-void FIRST_ULL_HFTA_AGGR_REINIT_(gs_uint64_t* scratch) { }
-
-void FIRST_ULL_HFTA_AGGR_UPDATE_(gs_uint64_t* scratch, gs_uint64_t val) {
-       if (*scratch == UINT_MAX)
-               *scratch = val;
-}
-
-void FIRST_ULL_HFTA_AGGR_OUTPUT_(gs_uint64_t* res, gs_uint64_t* scratch) {
-       *res = *scratch;
-}
-
-void FIRST_ULL_HFTA_AGGR_DESTROY_(gs_uint64_t* scratch) { }
-
-
-void FIRST_STR_HFTA_AGGR_INIT_(vstring* scratch) {
-       scratch->offset= 0;
-}
-
-void FIRST_STR_HFTA_AGGR_REINIT_(vstring* scratch) { }
-
-void FIRST_STR_HFTA_AGGR_UPDATE_(vstring* scratch, vstring* val) {
-       if (!scratch->offset) {
-    scratch->length = val->length;
-    scratch->offset = val->offset;
-    scratch->reserved = SHALLOW_COPY;
-       }
-}
-
-void FIRST_STR_HFTA_AGGR_OUTPUT_(vstring* res, vstring* scratch) {
-       *res = *scratch;
-}
-
-void FIRST_STR_HFTA_AGGR_DESTROY_(vstring* scratch) { }
-
-// hfta/lfta split
-
-void FIRST_hfta_HFTA_AGGR_INIT_(gs_uint32_t* scratch) {
-       *scratch = UINT_MAX;            // we will encode uninitialized value of UINT_MAX
-}
-
-void FIRST_hfta_HFTA_AGGR_REINIT_(gs_uint32_t* scratch) { }
-
-void FIRST_hfta_HFTA_AGGR_UPDATE_(gs_uint32_t* scratch, gs_uint32_t val) {
-       if (*scratch == UINT_MAX)
-               *scratch = val;
-}
-
-void FIRST_hfta_HFTA_AGGR_OUTPUT_(gs_uint32_t* res, gs_uint32_t* scratch) {
-       *res = *scratch;
-}
-
-void FIRST_hfta_HFTA_AGGR_DESTROY_(gs_uint32_t* scratch) { }
-
-void FIRST_ULL_hfta_HFTA_AGGR_INIT_(gs_uint64_t* scratch) {
-       *scratch = UINT_MAX;            // we will encode uninitialized value of UINT_MAX
-}
-
-void FIRST_ULL_hfta_HFTA_AGGR_REINIT_(gs_uint64_t* scratch) { }
-
-void FIRST_ULL_hfta_HFTA_AGGR_UPDATE_(gs_uint64_t* scratch, gs_uint64_t val) {
-       if (*scratch == UINT_MAX)
-               *scratch = val;
-}
-
-void FIRST_ULL_hfta_HFTA_AGGR_OUTPUT_(gs_uint64_t* res, gs_uint64_t* scratch) {
-       *res = *scratch;
-}
-
-void FIRST_ULL_hfta_HFTA_AGGR_DESTROY_(gs_uint64_t* scratch) { }
-
-
-void FIRST_STR_hfta_HFTA_AGGR_INIT_(vstring* scratch) {
-       scratch->offset= 0;
-}
-
-void FIRST_STR_hfta_HFTA_AGGR_REINIT_(vstring* scratch) { }
-
-void FIRST_STR_hfta_HFTA_AGGR_UPDATE_(vstring* scratch, vstring* val) {
-       if (!scratch->offset) {
-    scratch->length = val->length;
-    scratch->offset = val->offset;
-    scratch->reserved = SHALLOW_COPY;
-       }
-}
-
-void FIRST_STR_hfta_HFTA_AGGR_OUTPUT_(vstring* res, vstring* scratch) {
-       *res = *scratch;
-}
-
-void FIRST_STR_hfta_HFTA_AGGR_DESTROY_(vstring* scratch) { }
-
-
-/////////////////////////////////////////////////////////
-//             LAST aggregate
-
-// hfta only
-
-void LAST_HFTA_AGGR_INIT_(gs_uint32_t* scratch) { }
-
-void LAST_HFTA_AGGR_REINIT_(gs_uint32_t* scratch) { }
-
-void LAST_HFTA_AGGR_UPDATE_(gs_uint32_t* scratch, gs_uint32_t val) {
-       *scratch = val;
-}
-
-void LAST_HFTA_AGGR_OUTPUT_(gs_uint32_t* res, gs_uint32_t* scratch) {
-       *res = *scratch;
-}
-
-void LAST_HFTA_AGGR_DESTROY_(gs_uint32_t* scratch) { }
-
-void LAST_ULLHFTA_AGGR_INIT_(gs_uint64_t* scratch) { }
-
-void LAST_ULL_HFTA_AGGR_REINIT_(gs_uint64_t* scratch) { }
-
-void LAST_ULL_HFTA_AGGR_UPDATE_(gs_uint64_t* scratch, gs_uint64_t val) {
-       *scratch = val;
-}
-
-void LAST_ULL_HFTA_AGGR_OUTPUT_(gs_uint64_t* res, gs_uint64_t* scratch) {
-       *res = *scratch;
-}
-
-void LAST_ULL_HFTA_AGGR_DESTROY_(gs_uint64_t* scratch) { }
-
-
-void LAST_STR_HFTA_AGGR_INIT_(vstring* scratch) {
-       scratch->offset= 0;
-}
-
-void LAST_STR_HFTA_AGGR_REINIT_(vstring* scratch) { }
-
-void LAST_STR_HFTA_AGGR_UPDATE_(vstring* scratch, vstring* val) {
-       scratch->length = val->length;
-  scratch->offset = val->offset;
-  scratch->reserved = SHALLOW_COPY;
-}
-
-void LAST_STR_HFTA_AGGR_OUTPUT_(vstring* res, vstring* scratch) {
-       *res = *scratch;
-}
-
-void LAST_STR_HFTA_AGGR_DESTROY_(vstring* scratch) { }
-
-// hfta/lfta split
-
-void LAST_hfta_HFTA_AGGR_INIT_(gs_uint32_t* scratch) { }
-
-void LAST_hfta_HFTA_AGGR_REINIT_(gs_uint32_t* scratch) { }
-
-void LAST_hfta_HFTA_AGGR_UPDATE_(gs_uint32_t* scratch, gs_uint32_t val) {
-       *scratch = val;
-}
-
-void LAST_hfta_HFTA_AGGR_OUTPUT_(gs_uint32_t* res, gs_uint32_t* scratch) {
-       *res = *scratch;
-}
-
-void LAST_hfta_HFTA_AGGR_DESTROY_(gs_uint32_t* scratch) { }
-
-void LAST_ULL_hfta_HFTA_AGGR_INIT_(gs_uint64_t* scratch) { }
-
-void LAST_ULL_hfta_HFTA_AGGR_REINIT_(gs_uint64_t* scratch) { }
-
-void LAST_ULL_hfta_HFTA_AGGR_UPDATE_(gs_uint64_t* scratch, gs_uint64_t val) {
-       *scratch = val;
-}
-
-void LAST_ULL_hfta_HFTA_AGGR_OUTPUT_(gs_uint64_t* res, gs_uint64_t* scratch) {
-       *res = *scratch;
-}
-
-void LAST_ULL_hfta_HFTA_AGGR_DESTROY_(gs_uint64_t* scratch) { }
-
-
-void LAST_STR_hfta_HFTA_AGGR_INIT_(vstring* scratch) {
-       scratch->offset= 0;
-}
-
-void LAST_STR_hfta_HFTA_AGGR_REINIT_(vstring* scratch) { }
-
-void LAST_STR_hfta_HFTA_AGGR_UPDATE_(vstring* scratch, vstring* val) {
-       scratch->length = val->length;
-  scratch->offset = val->offset;
-  scratch->reserved = SHALLOW_COPY;
-}
-
-void LAST_STR_hfta_HFTA_AGGR_OUTPUT_(vstring* res, vstring* scratch) {
-       *res = *scratch;
-}
-
-void LAST_STR_hfta_HFTA_AGGR_DESTROY_(vstring* scratch) { }
-
-
-/////////////////////////////////////////////////////////
-//             running_array_aggr aggregate
-
-void running_array_aggr_hfta_HFTA_AGGR_INIT_(vstring* scratch) {
-  scratch->offset = NULL;  
-  scratch->length = 0;
-}
-
-void running_array_aggr_hfta_HFTA_AGGR_REINIT_(vstring* scratch) { }
-
-void running_array_aggr_hfta_HFTA_AGGR_UPDATE_(vstring* scratch, vstring* val) {
-  char buffer[100];
-
-  gs_uint32_t* ints = (gs_uint32_t*)val->offset;
-  switch (val->length / sizeof (gs_uint32_t)) {
-    case 4:
-      sprintf(buffer, "%u,%u,%u,%u", ints[0], ints[1], ints[2], ints[3]);
-      break;
-    case 3:
-      sprintf(buffer, "%u,%u,%u", ints[0], ints[1], ints[2]);
-      break;   
-    case 2:
-      sprintf(buffer, "%u,%u", ints[0], ints[1]);
-      break;        
-    case 1:
-      sprintf(buffer, "%u", ints[0]);
-      break;  
-    case 0:
-      return;        
-  }
-  int buf_len = strlen(buffer);
-
-  // append the content of buffer to scratch
-       if (!scratch->offset) {
-    Vstring_Constructor(scratch, buffer);
-       } else {
-    scratch->offset = (gs_p_t)realloc((void*)scratch->offset, scratch->length + buf_len + 1);
-    *((char*)scratch->offset + scratch->length) = ',';
-    memcpy((void*)(scratch->offset + scratch->length + 1), (void*)buffer, buf_len);
-    scratch->length += buf_len + 1;
-    scratch->reserved = INTERNAL;
-  }
-}
-
-void running_array_aggr_hfta_HFTA_AGGR_OUTPUT_(vstring* res, vstring* scratch) {
-       *res = *scratch;
-  res->reserved = SHALLOW_COPY;
-}
-
-void running_array_aggr_hfta_HFTA_AGGR_DESTROY_(vstring* scratch) {
-  hfta_vstr_destroy(scratch);
- }
-
+/* ------------------------------------------------\r
+Copyright 2014 AT&T Intellectual Property\r
+   Licensed under the Apache License, Version 2.0 (the "License");\r
+   you may not use this file except in compliance with the License.\r
+   You may obtain a copy of the License at\r
+\r
+     http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+ ------------------------------------------- */\r
+\r
+\r
+#include "gsconfig.h"\r
+#include "gstypes.h"\r
+#include "hfta_udaf.h"\r
+#include "rts_udaf.h"\r
+#include <stdio.h>\r
+#include <limits.h>\r
+#include <math.h>\r
+//#include <memory.h>\r
+#include <string.h>\r
+#include <sys/time.h>\r
+#include <iostream>\r
+\r
+#include "hfta_runtime_library.h"\r
+\r
+\r
+#define max(a,b) ((a) > (b) ? (a) : (b))\r
+#define min(x,y) ((x) < (y) ? (x) : (y))\r
+#define lg(x)    (log(x) / log(2))\r
+\r
+using namespace std;\r
+\r
+\r
+// -------------------------------------------------------------------\r
+//              moving sum over N intervals\r
+\r
+struct moving_sum_udaf_str{\r
+       gs_uint32_t N;\r
+       gs_uint32_t pos;\r
+       gs_uint32_t *sums;\r
+};\r
+\r
+void moving_sum_udaf_HFTA_AGGR_INIT_(gs_sp_t buf){\r
+  struct moving_sum_udaf_str * u = (struct moving_sum_udaf_str *) buf;\r
+  u->N=0; u->pos=0; u->sums=NULL;\r
+}\r
+\r
+void moving_sum_udaf_HFTA_AGGR_UPDATE_(gs_sp_t buf, gs_uint32_t s, gs_uint32_t N) {\r
+  struct moving_sum_udaf_str * u = (struct moving_sum_udaf_str *) buf;\r
+  if(u->sums == NULL){\r
+       u->sums = (gs_uint32_t *)malloc(N*sizeof(gs_uint32_t));\r
+       for(gs_int32_t i=0;i<N;i++)\r
+               u->sums[i] = 0;\r
+    u->N = N;\r
+  }\r
+  u->sums[u->pos] += s;\r
+}\r
+\r
+void super_moving_sum_udaf_HFTA_AGGR_UPDATE_(gs_sp_t  buf, gs_uint64_t sub_sum) {\r
+  struct moving_sum_udaf_str * u = (struct moving_sum_udaf_str *) buf;\r
+  gs_uint32_t s = (gs_uint32_t)(sub_sum & 0xffffffff);\r
+  if(u->sums == NULL){\r
+    gs_uint32_t N = (gs_uint32_t)((sub_sum & 0xffffffff00000000ull) >> 32);\r
+       u->sums = (gs_uint32_t *)malloc(N*sizeof(gs_uint32_t));\r
+       for(gs_int32_t i=0;i<N;i++)\r
+               u->sums[i] = 0;\r
+    u->N = N;\r
+  }\r
+  u->sums[u->pos] += s;\r
+}\r
+\r
+void moving_sum_udaf_HFTA_AGGR_OUTPUT_(gs_p_t *result, gs_sp_t  buf){\r
+       *result = (gs_p_t)(buf);\r
+}\r
+\r
+void moving_sum_udaf_HFTA_AGGR_DESTROY_(gs_sp_t  buf){\r
+  struct moving_sum_udaf_str * u = (struct moving_sum_udaf_str *) buf;\r
+  if(u->sums != NULL)\r
+       free(u->sums);\r
+}\r
+\r
+void moving_sum_udaf_HFTA_AGGR_REINIT_( gs_sp_t  buf){\r
+  struct moving_sum_udaf_str * u = (struct moving_sum_udaf_str *) buf;\r
+  u->pos++;\r
+  if(u->pos >= u->N)\r
+       u->pos = 0;\r
+  u->sums[u->pos] = 0;\r
+}\r
+\r
+gs_uint32_t moving_sum_extract(gs_p_t result){\r
+  struct moving_sum_udaf_str * u = (struct moving_sum_udaf_str *) result;\r
+  gs_uint32_t s=0, i=0;\r
+  for(i=0; i<u->N;i++){\r
+    s += u->sums[i];\r
+  }\r
+  return s;\r
+}\r
+\r
+gs_float_t moving_sum_extract_exp(gs_p_t result, gs_float_t alpha){\r
+  struct moving_sum_udaf_str * u = (struct moving_sum_udaf_str *) result;\r
+  gs_uint32_t p=0, i=0;\r
+  gs_float_t s=0.0, m=1.0;\r
+  p=u->pos;\r
+  for(i=0; i<u->N;i++){\r
+    s += u->sums[i]*m;\r
+    if(p==0)\r
+               p=u->N - 1;\r
+    else\r
+               p--;\r
+       m *= alpha;\r
+  }\r
+  return s;\r
+}\r
+\r
+\r
+// -------------------------------------------------------------------\r
+//              sum over 3 intervals : test rUDAF\r
+\r
+struct sum3_udaf_str{\r
+  gs_uint32_t s_2;\r
+  gs_uint32_t s_1;\r
+  gs_uint32_t s_0;\r
+};\r
+\r
+void sum3_HFTA_AGGR_INIT_(gs_sp_t  buf) {\r
+  struct sum3_udaf_str * u = (struct sum3_udaf_str *) buf;\r
+  u->s_0 = 0; u->s_1 = 0; u->s_2 = 0;\r
+  return;\r
+}          \r
+\r
+void sum3_HFTA_AGGR_UPDATE_(gs_sp_t  buf, gs_uint32_t s) {\r
+  struct sum3_udaf_str * u = (struct sum3_udaf_str *) buf;\r
+  u->s_0 += s;\r
+  return;\r
+}\r
+\r
+void sum3_HFTA_AGGR_OUTPUT_(gs_uint32_t *result, gs_sp_t  buf) {\r
+  struct sum3_udaf_str * u = (struct sum3_udaf_str *) buf;\r
+  *result = u->s_0 + u->s_1 + u->s_2;\r
+  return; \r
+}\r
+\r
+void sum3_HFTA_AGGR_DESTROY_(gs_sp_t  buf) {\r
+  return;\r
+}\r
+\r
+void sum3_HFTA_AGGR_REINIT_( gs_sp_t  buf) {\r
+  struct sum3_udaf_str * u = (struct sum3_udaf_str *) buf;\r
+  u->s_2 = u->s_1;\r
+  u->s_1 = u->s_0;\r
+  u->s_0 = 0;\r
+  return;\r
+}\r
+\r
+\r
+#define HISTORY_LENGTH 1024\r
+\r
+/////////////////////////////////////////////////////////////////////////\r
+/////   Calculate the average of all positive gs_float_t numbers\r
+\r
+struct posavg_struct{\r
+  gs_float_t sum;\r
+  gs_float_t cnt;\r
+};\r
+\r
+void POSAVG_HFTA_AGGR_INIT_(gs_sp_t  buf) {\r
+  struct posavg_struct * a = (struct posavg_struct *) buf;\r
+  a->sum=0;\r
+  a->cnt=0;\r
+  return;\r
+}\r
+\r
+void POSAVG_HFTA_AGGR_UPDATE_(gs_sp_t  buf, gs_float_t v) {\r
+  struct posavg_struct * a = (struct posavg_struct *) buf;\r
+  if (v>=0) {\r
+    a->sum=a->sum+v;\r
+    a->cnt=a->cnt+1;\r
+  }\r
+  return;\r
+}\r
+\r
+void POSAVG_HFTA_AGGR_OUTPUT_(gs_float_t * v, gs_sp_t  buf) {\r
+  struct posavg_struct * a = (struct posavg_struct *) buf;\r
+  if (a->cnt>0) {\r
+    *v=(a->sum/a->cnt);\r
+  } else {\r
+    *v=-1;\r
+  }\r
+  return;\r
+}\r
+\r
+void POSAVG_HFTA_AGGR_DESTROY_(gs_sp_t  buf) {\r
+  return;\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////\r
+/////                   avg_udaf (simple example)\r
+\r
+//              struct received from subaggregate\r
+struct avg_udaf_lfta_struct_t{\r
+        gs_int64_t  sum;\r
+        gs_uint32_t cnt;\r
+};\r
+\r
+//              sctarchpad struct\r
+struct avg_udaf_hfta_struct_t{\r
+        gs_int64_t sum;\r
+        gs_uint32_t cnt;\r
+};\r
+\r
+//                      avg_udaf functions\r
+void avg_udaf_HFTA_AGGR_INIT_(gs_sp_t b){\r
+        avg_udaf_hfta_struct_t *s = (avg_udaf_hfta_struct_t *) b;\r
+        s->sum = 0;\r
+        s->cnt = 0;\r
+}\r
+\r
+void avg_udaf_HFTA_AGGR_UPDATE_(gs_sp_t b, gs_uint32_t v){\r
+        avg_udaf_hfta_struct_t *s = (avg_udaf_hfta_struct_t *) b;\r
+        s->sum += v;\r
+        s->cnt ++;\r
+}\r
+\r
+void avg_udaf_HFTA_AGGR_OUTPUT_(vstring *r,gs_sp_t b){\r
+        r->length = 12;\r
+        r->offset = (gs_p_t)(b);\r
+        r->reserved = SHALLOW_COPY;\r
+}\r
+\r
+void avg_udaf_HFTA_AGGR_DESTROY_(gs_sp_t b){\r
+        return;\r
+}\r
+\r
+\r
+//                      avg_udaf superaggregate functions\r
+void avg_udaf_hfta_HFTA_AGGR_INIT_(gs_sp_t b){\r
+        avg_udaf_hfta_struct_t *s = (avg_udaf_hfta_struct_t *) b;\r
+        s->sum = 0;\r
+        s->cnt = 0;\r
+}\r
+\r
+void avg_udaf_hfta_HFTA_AGGR_UPDATE_(gs_sp_t b, vstring *v){\r
+        if(v->length != 12) return;\r
+        avg_udaf_hfta_struct_t *s = (avg_udaf_hfta_struct_t *) b;\r
+        avg_udaf_lfta_struct_t *vs = (avg_udaf_lfta_struct_t *)(v->offset);\r
+        s->sum += vs->sum;\r
+        s->cnt += vs->cnt;\r
+}\r
+\r
+void avg_udaf_hfta_HFTA_AGGR_OUTPUT_(vstring *r,gs_sp_t b){\r
+        r->length = 12;\r
+        r->offset = (gs_p_t)(b);\r
+        r->reserved = SHALLOW_COPY;\r
+}\r
+\r
+void avg_udaf_hfta_HFTA_AGGR_DESTROY_(gs_sp_t b){\r
+        return;\r
+}\r
+\r
+//              Extraction function\r
+gs_float_t extr_avg_fcn(vstring *v){\r
+        if(v->length != 12) return 0;\r
+        avg_udaf_hfta_struct_t *vs = (avg_udaf_hfta_struct_t *)(v->offset);\r
+        gs_float_t r = (gs_float_t)(vs->sum) / vs->cnt;\r
+    return r;\r
+}\r
+\r
+/////////////////////////////////////////////////////////\r
+//             FIRST aggregate\r
+// hfta only\r
+\r
+void FIRST_HFTA_AGGR_INIT_(gs_uint32_t* scratch) {\r
+       *scratch = UINT_MAX;            // we will encode uninitialized value of UINT_MAX\r
+}\r
+\r
+void FIRST_HFTA_AGGR_REINIT_(gs_uint32_t* scratch) { }\r
+\r
+void FIRST_HFTA_AGGR_UPDATE_(gs_uint32_t* scratch, gs_uint32_t val) {\r
+       if (*scratch == UINT_MAX)\r
+               *scratch = val;\r
+}\r
+\r
+void FIRST_HFTA_AGGR_OUTPUT_(gs_uint32_t* res, gs_uint32_t* scratch) {\r
+       *res = *scratch;\r
+}\r
+\r
+void FIRST_HFTA_AGGR_DESTROY_(gs_uint32_t* scratch) { }\r
+\r
+void FIRST_ULL_HFTA_AGGR_INIT_(gs_uint64_t* scratch) {\r
+       *scratch = UINT_MAX;            // we will encode uninitialized value of UINT_MAX\r
+}\r
+\r
+void FIRST_ULL_HFTA_AGGR_REINIT_(gs_uint64_t* scratch) { }\r
+\r
+void FIRST_ULL_HFTA_AGGR_UPDATE_(gs_uint64_t* scratch, gs_uint64_t val) {\r
+       if (*scratch == UINT_MAX)\r
+               *scratch = val;\r
+}\r
+\r
+void FIRST_ULL_HFTA_AGGR_OUTPUT_(gs_uint64_t* res, gs_uint64_t* scratch) {\r
+       *res = *scratch;\r
+}\r
+\r
+void FIRST_ULL_HFTA_AGGR_DESTROY_(gs_uint64_t* scratch) { }\r
+\r
+\r
+void FIRST_STR_HFTA_AGGR_INIT_(vstring* scratch) {\r
+       scratch->offset= 0;\r
+}\r
+\r
+void FIRST_STR_HFTA_AGGR_REINIT_(vstring* scratch) { }\r
+\r
+void FIRST_STR_HFTA_AGGR_UPDATE_(vstring* scratch, vstring* val) {\r
+       if (!scratch->offset) {\r
+    scratch->length = val->length;\r
+    scratch->offset = val->offset;\r
+    scratch->reserved = SHALLOW_COPY;\r
+       }\r
+}\r
+\r
+void FIRST_STR_HFTA_AGGR_OUTPUT_(vstring* res, vstring* scratch) {\r
+       *res = *scratch;\r
+}\r
+\r
+void FIRST_STR_HFTA_AGGR_DESTROY_(vstring* scratch) { }\r
+\r
+// hfta/lfta split\r
+\r
+void FIRST_hfta_HFTA_AGGR_INIT_(gs_uint32_t* scratch) {\r
+       *scratch = UINT_MAX;            // we will encode uninitialized value of UINT_MAX\r
+}\r
+\r
+void FIRST_hfta_HFTA_AGGR_REINIT_(gs_uint32_t* scratch) { }\r
+\r
+void FIRST_hfta_HFTA_AGGR_UPDATE_(gs_uint32_t* scratch, gs_uint32_t val) {\r
+       if (*scratch == UINT_MAX)\r
+               *scratch = val;\r
+}\r
+\r
+void FIRST_hfta_HFTA_AGGR_OUTPUT_(gs_uint32_t* res, gs_uint32_t* scratch) {\r
+       *res = *scratch;\r
+}\r
+\r
+void FIRST_hfta_HFTA_AGGR_DESTROY_(gs_uint32_t* scratch) { }\r
+\r
+void FIRST_ULL_hfta_HFTA_AGGR_INIT_(gs_uint64_t* scratch) {\r
+       *scratch = UINT_MAX;            // we will encode uninitialized value of UINT_MAX\r
+}\r
+\r
+void FIRST_ULL_hfta_HFTA_AGGR_REINIT_(gs_uint64_t* scratch) { }\r
+\r
+void FIRST_ULL_hfta_HFTA_AGGR_UPDATE_(gs_uint64_t* scratch, gs_uint64_t val) {\r
+       if (*scratch == UINT_MAX)\r
+               *scratch = val;\r
+}\r
+\r
+void FIRST_ULL_hfta_HFTA_AGGR_OUTPUT_(gs_uint64_t* res, gs_uint64_t* scratch) {\r
+       *res = *scratch;\r
+}\r
+\r
+void FIRST_ULL_hfta_HFTA_AGGR_DESTROY_(gs_uint64_t* scratch) { }\r
+\r
+\r
+void FIRST_STR_hfta_HFTA_AGGR_INIT_(vstring* scratch) {\r
+       scratch->offset= 0;\r
+}\r
+\r
+void FIRST_STR_hfta_HFTA_AGGR_REINIT_(vstring* scratch) { }\r
+\r
+void FIRST_STR_hfta_HFTA_AGGR_UPDATE_(vstring* scratch, vstring* val) {\r
+       if (!scratch->offset) {\r
+    scratch->length = val->length;\r
+    scratch->offset = val->offset;\r
+    scratch->reserved = SHALLOW_COPY;\r
+       }\r
+}\r
+\r
+void FIRST_STR_hfta_HFTA_AGGR_OUTPUT_(vstring* res, vstring* scratch) {\r
+       *res = *scratch;\r
+}\r
+\r
+void FIRST_STR_hfta_HFTA_AGGR_DESTROY_(vstring* scratch) { }\r
+\r
+\r
+/////////////////////////////////////////////////////////\r
+//             LAST aggregate\r
+\r
+// hfta only\r
+\r
+void LAST_HFTA_AGGR_INIT_(gs_uint32_t* scratch) { }\r
+\r
+void LAST_HFTA_AGGR_REINIT_(gs_uint32_t* scratch) { }\r
+\r
+void LAST_HFTA_AGGR_UPDATE_(gs_uint32_t* scratch, gs_uint32_t val) {\r
+       *scratch = val;\r
+}\r
+\r
+void LAST_HFTA_AGGR_OUTPUT_(gs_uint32_t* res, gs_uint32_t* scratch) {\r
+       *res = *scratch;\r
+}\r
+\r
+void LAST_HFTA_AGGR_DESTROY_(gs_uint32_t* scratch) { }\r
+\r
+void LAST_ULLHFTA_AGGR_INIT_(gs_uint64_t* scratch) { }\r
+\r
+void LAST_ULL_HFTA_AGGR_REINIT_(gs_uint64_t* scratch) { }\r
+\r
+void LAST_ULL_HFTA_AGGR_UPDATE_(gs_uint64_t* scratch, gs_uint64_t val) {\r
+       *scratch = val;\r
+}\r
+\r
+void LAST_ULL_HFTA_AGGR_OUTPUT_(gs_uint64_t* res, gs_uint64_t* scratch) {\r
+       *res = *scratch;\r
+}\r
+\r
+void LAST_ULL_HFTA_AGGR_DESTROY_(gs_uint64_t* scratch) { }\r
+\r
+\r
+void LAST_STR_HFTA_AGGR_INIT_(vstring* scratch) {\r
+       scratch->offset= 0;\r
+}\r
+\r
+void LAST_STR_HFTA_AGGR_REINIT_(vstring* scratch) { }\r
+\r
+void LAST_STR_HFTA_AGGR_UPDATE_(vstring* scratch, vstring* val) {\r
+       scratch->length = val->length;\r
+  scratch->offset = val->offset;\r
+  scratch->reserved = SHALLOW_COPY;\r
+}\r
+\r
+void LAST_STR_HFTA_AGGR_OUTPUT_(vstring* res, vstring* scratch) {\r
+       *res = *scratch;\r
+}\r
+\r
+void LAST_STR_HFTA_AGGR_DESTROY_(vstring* scratch) { }\r
+\r
+// hfta/lfta split\r
+\r
+void LAST_hfta_HFTA_AGGR_INIT_(gs_uint32_t* scratch) { }\r
+\r
+void LAST_hfta_HFTA_AGGR_REINIT_(gs_uint32_t* scratch) { }\r
+\r
+void LAST_hfta_HFTA_AGGR_UPDATE_(gs_uint32_t* scratch, gs_uint32_t val) {\r
+       *scratch = val;\r
+}\r
+\r
+void LAST_hfta_HFTA_AGGR_OUTPUT_(gs_uint32_t* res, gs_uint32_t* scratch) {\r
+       *res = *scratch;\r
+}\r
+\r
+void LAST_hfta_HFTA_AGGR_DESTROY_(gs_uint32_t* scratch) { }\r
+\r
+void LAST_ULL_hfta_HFTA_AGGR_INIT_(gs_uint64_t* scratch) { }\r
+\r
+void LAST_ULL_hfta_HFTA_AGGR_REINIT_(gs_uint64_t* scratch) { }\r
+\r
+void LAST_ULL_hfta_HFTA_AGGR_UPDATE_(gs_uint64_t* scratch, gs_uint64_t val) {\r
+       *scratch = val;\r
+}\r
+\r
+void LAST_ULL_hfta_HFTA_AGGR_OUTPUT_(gs_uint64_t* res, gs_uint64_t* scratch) {\r
+       *res = *scratch;\r
+}\r
+\r
+void LAST_ULL_hfta_HFTA_AGGR_DESTROY_(gs_uint64_t* scratch) { }\r
+\r
+\r
+void LAST_STR_hfta_HFTA_AGGR_INIT_(vstring* scratch) {\r
+       scratch->offset= 0;\r
+}\r
+\r
+void LAST_STR_hfta_HFTA_AGGR_REINIT_(vstring* scratch) { }\r
+\r
+void LAST_STR_hfta_HFTA_AGGR_UPDATE_(vstring* scratch, vstring* val) {\r
+       scratch->length = val->length;\r
+  scratch->offset = val->offset;\r
+  scratch->reserved = SHALLOW_COPY;\r
+}\r
+\r
+void LAST_STR_hfta_HFTA_AGGR_OUTPUT_(vstring* res, vstring* scratch) {\r
+       *res = *scratch;\r
+}\r
+\r
+void LAST_STR_hfta_HFTA_AGGR_DESTROY_(vstring* scratch) { }\r
+\r
+\r
+/////////////////////////////////////////////////////////\r
+//             running_array_aggr aggregate\r
+\r
+void running_array_aggr_hfta_HFTA_AGGR_INIT_(vstring* scratch) {\r
+  scratch->offset = NULL;  \r
+  scratch->length = 0;\r
+}\r
+\r
+void running_array_aggr_hfta_HFTA_AGGR_REINIT_(vstring* scratch) { }\r
+\r
+void running_array_aggr_hfta_HFTA_AGGR_UPDATE_(vstring* scratch, vstring* val) {\r
+  char buffer[100];\r
+\r
+  gs_uint32_t* ints = (gs_uint32_t*)val->offset;\r
+  switch (val->length / sizeof (gs_uint32_t)) {\r
+    case 4:\r
+      sprintf(buffer, "%u,%u,%u,%u", ints[0], ints[1], ints[2], ints[3]);\r
+      break;\r
+    case 3:\r
+      sprintf(buffer, "%u,%u,%u", ints[0], ints[1], ints[2]);\r
+      break;   \r
+    case 2:\r
+      sprintf(buffer, "%u,%u", ints[0], ints[1]);\r
+      break;        \r
+    case 1:\r
+      sprintf(buffer, "%u", ints[0]);\r
+      break;  \r
+    case 0:\r
+      return;        \r
+  }\r
+  int buf_len = strlen(buffer);\r
+\r
+  // append the content of buffer to scratch\r
+       if (!scratch->offset) {\r
+    Vstring_Constructor(scratch, buffer);\r
+       } else {\r
+    scratch->offset = (gs_p_t)realloc((void*)scratch->offset, scratch->length + buf_len + 1);\r
+    *((char*)scratch->offset + scratch->length) = ',';\r
+    memcpy((void*)(scratch->offset + scratch->length + 1), (void*)buffer, buf_len);\r
+    scratch->length += buf_len + 1;\r
+    scratch->reserved = INTERNAL;\r
+  }\r
+}\r
+\r
+void running_array_aggr_hfta_HFTA_AGGR_OUTPUT_(vstring* res, vstring* scratch) {\r
+       *res = *scratch;\r
+  res->reserved = SHALLOW_COPY;\r
+}\r
+\r
+void running_array_aggr_hfta_HFTA_AGGR_DESTROY_(vstring* scratch) {\r
+  hfta_vstr_destroy(scratch);\r
+ }\r
+\r