Changeset: 2987c8785dec for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=2987c8785dec
Modified Files:
        gdk/gdk_join.c
        gdk/gdk_private.h
        sql/backends/monet5/sql.c
Branch: arrays
Log Message:

projecting a dimension should result in a new dimension,
i.e a (min, max, step) representation. If finding such a
pattern in the projected values is not possible then the
projection is ignored.


diffs (truncated from 334 to 300 lines):

diff --git a/gdk/gdk_join.c b/gdk/gdk_join.c
--- a/gdk/gdk_join.c
+++ b/gdk/gdk_join.c
@@ -3411,10 +3411,156 @@ BATproject(BAT *l, BAT *r)
        return NULL;
 }
 BAT* BATdimensionProject(BAT* oidsBAT, BAT* dimensionBAT) {
-       (void)*oidsBAT;
-       (void)*dimensionBAT;
+       BAT *resBAT;
+       int tpe = ATOMtype(dimensionBAT->ttype);//, nilcheck = 1, sortcheck = 
1, stringtrick = 0;
+       
+       assert(BAThdense(oidsBAT));
+    assert(BAThdense(dimensionBAT));
+    assert(ATOMtype(oidsBAT->ttype) == TYPE_oid);
 
-       return NULL;
+#define dimensionise(TYPE) \
+       do { \
+               long flg=0, cnt=0, elementsInGroup=-1; \
+               oid *oids; \
+               BUN i=0; \
+               TYPE dimMin, dimMax, dimStep; \
+               TYPE resMin, resMax, resStep; \
+               long dimGroupRepeats, dimElementRepeats; \
+               long resGroupRepeats, resElementRepeats; \
+\
+               dimensionCharacteristics(TYPE, dimensionBAT, &dimMin, &dimMax, 
&dimStep, &dimElementRepeats, &dimGroupRepeats); \
+               /*min, step, max implied by oids*/ \
+               oids = (oid*)Tloc(oidsBAT, BUNfirst(oidsBAT)); \
+               resMin = dimensionElement(dimMin, dimMax, dimStep, 
dimElementRepeats, oids[0]); \
+               resMax = dimensionElement(dimMin, dimMax, dimStep, 
dimElementRepeats, oids[BATcount(oidsBAT)-1]); \
+\
+               /*min and max should appear the same number of times*/ \
+               resGroupRepeats = 0; \
+               for(i=0; i<BATcount(oidsBAT); i++) { \
+                       TYPE el_cur = dimensionElement(dimMin, dimMax, dimStep, 
dimElementRepeats, oids[i]); \
+                       cnt++; \
+                       if(el_cur == resMin) { \
+                               if(flg>0) { \
+                                       fprintf(stderr, "BATdimensionProject: 
dimension not regular (max more than min)\n"); \
+                                       return NULL; \
+                               } \
+                               flg++; \
+                               cnt = 1; \
+                       } \
+                       if(el_cur == resMax) { \
+                               if(flg<1) { \
+                                       fprintf(stderr, "BATdimensionProject: 
dimension not regular (min more than max)\n"); \
+                                       return NULL; \
+                               } \
+                               flg--; \
+                               resGroupRepeats++; \
+\
+                               if(elementsInGroup >= 0 && elementsInGroup != 
cnt) { \
+                                       fprintf(stderr, "BATdimensionProject: 
dimension not regular (different number of elements among groups)\n"); \
+                                       return NULL; \
+                               } \
+                               elementsInGroup = cnt; \
+                               cnt = 0; \
+                       } \
+               } \
+\
+fprintf(stderr, "dimensionise: groupRepeats = %ld, elementsInGroup = %ld\n", 
resGroupRepeats, elementsInGroup); \
+               /*check that the step is the same between the elements and each 
element is repeated the same number of times*/ \
+               resElementRepeats = -1; \
+               for(i=0; i<BATcount(oidsBAT); i++) { \
+                       if(dimensionElement(dimMin, dimMax, dimStep, 
dimElementRepeats, oids[i]) == resMax) { \
+                               /*iterate over the elements in the group*/ \
+                               BUN j; \
+                               long r=0; \
+                               BUN groupStart = i-elementsInGroup+1; \
+                               TYPE el_cur, el_prev = dimensionElement(dimMin, 
dimMax, dimStep, dimElementRepeats, oids[groupStart]); \
+fprintf(stderr, "dimensionise: Group:[%ld, %ld]\n", groupStart, i); \
+                               for(j=groupStart; j<=i; j++) { \
+                                       el_cur = dimensionElement(dimMin, 
dimMax, dimStep, dimElementRepeats, oids[j]); \
+/*fprintf(stderr, "dimensionise: In group element %ld\n", j); */\
+                                       if(el_prev == el_cur)  {\
+                                               r++; \
+/*fprintf(stderr, "dimensionise: same element %ld\n", r); */\
+                                       } \
+                                       else { \
+                                               if(resElementRepeats >=0 && 
resElementRepeats != r) { \
+                                                       fprintf(stderr, 
"BATdimensionProject: dimension not regular (different number of 
repetitions)\n"); \
+                                                       return NULL; \
+                                               } else if(resElementRepeats <0) 
{ \
+                                                       resElementRepeats = r; \
+                                                       resStep = el_cur - 
el_prev; \
+                                               } \
+                                               if(resStep != (el_cur - 
el_prev)) { \
+                                                       fprintf(stderr, 
"BATdimensionProject: dimension not regular (not equal steps)\n"); \
+                                                       return NULL; \
+                                               } \
+                                               el_prev=el_cur; \
+                                               r=1; \
+                                       } \
+                               } \
+                               /*check the last element in the group*/ \
+                               if(resElementRepeats >=0 && resElementRepeats 
!= r) { \
+                                       fprintf(stderr, "BATdimensionProject: 
dimension not regular (different number of repetitions)\n"); \
+                                       return NULL; \
+                               } else if(resElementRepeats <0) { \
+                                       resElementRepeats = r; \
+                                       resStep = 0; /*if here then there is 
only one element in the group*/\
+                               } \
+                       } \
+               } \
+\
+fprintf(stderr, "dimensionise: elementRepeats=%ld\n", resElementRepeats); \
+               /*create the BAT*/ \
+               resBAT = createDimension(TYPE, resMin, resMax, resStep, 
resElementRepeats, resGroupRepeats); \
+       } while(0) 
+
+       if(BATcount(oidsBAT)) { 
+               switch (tpe) {
+       case TYPE_bte:
+               dimensionise(bte);
+               break;
+       case TYPE_sht:
+               dimensionise(sht);
+               break;
+       case TYPE_int:
+               dimensionise(int);
+               break;
+       case TYPE_flt:
+               dimensionise(flt);
+               break;
+       case TYPE_dbl:
+               dimensionise(dbl);
+               break;
+       case TYPE_lng:
+               dimensionise(lng);
+               break;
+#ifdef HAVE_HGE
+       case TYPE_hge:
+               dimensionise(hge);
+               break;
+#endif
+       case TYPE_oid:
+#if SIZEOF_OID == SIZEOF_INT
+               dimensionise(int);
+#else
+               dimensionise(lng);
+#endif
+        break;
+       default:
+                       fprintf(stderr, "BATdimensionProject: dimension type 
not handled\n");
+                       return NULL;
+           }
+       } else {
+               //no oids. Empty BAT
+               if((resBAT = BATnew(TYPE_void, tpe, 0, TRANSIENT)) == NULL) 
+                       return NULL;
+
+               BATsetcount(resBAT,0);
+        BATseqbase(resBAT,0);
+        BATderiveProps(resBAT,FALSE);
+       }
+
+       return resBAT;
 }
 
 BAT* BATnonDimensionProject(BAT* oidsBAT, BAT* dimensionBAT) {
@@ -3577,7 +3723,7 @@ fprintf(stderr, "BATdimensionProject: ne
 #endif
         break;
        default:
-                       fprintf(stderr, "BATdimensionProject: dimension type 
not handled\n");
+                       fprintf(stderr, "BATnonDimensionProject: type not 
handled\n");
                        return NULL;
            }
        } else {
diff --git a/gdk/gdk_private.h b/gdk/gdk_private.h
--- a/gdk/gdk_private.h
+++ b/gdk/gdk_private.h
@@ -425,3 +425,58 @@ GDKreallocmax_debug(void *ptr, size_t si
 #define GDKreallocmax(p, s, ps, e)     GDKreallocmax_debug((p), (s), (ps), 
(e), __FILE__, __LINE__)
 #endif
 #endif
+
+
+/*Dimensional Columns*/
+#define dimensionCharacteristics(TPE, dimensionBAT, min, max, step, 
elementRepeats, groupRepeats) \
+do {\
+       TPE *vls; \
+       vls = (TPE*)Tloc(dimensionBAT, BUNfirst(dimensionBAT)); \
+       *min = vls[0]; \
+       *step = vls[BATcount(dimensionBAT)-1]; \
+       *max = vls[BATcount(dimensionBAT)-2]; \
+\
+       *elementRepeats = *groupRepeats = 0; \
+       vls = (TPE*)Tloc(dimensionBAT, BUNfirst(dimensionBAT)); \
+\
+       for(i=0; i<BATcount(dimensionBAT)-2; i++) { /*last element is the step 
and at least one element is max*/\
+               if(vls[i] != *min) \
+                       break; \
+               (*elementRepeats)++; \
+       } \
+       *groupRepeats = BATcount(dimensionBAT)-i-1; \
+} while(0)
+
+#define dimensionElement(min, max, step, elementRepeats, oid) \
+       ({ \
+               long elementsNum = floor((max-min)/step) + 1; \
+               long elementsPerGroup = elementsNum*elementRepeats; \
+               long elementInGroup = 
floor((oid%elementsPerGroup)/elementRepeats); \
+               min+elementInGroup*step; \
+       })
+
+#define createDimension(TPE, min, max, step, elementRepeats, groupRepeats) \
+       ({ \
+               long i; \
+               TPE* vls; \
+               BAT *resBAT = BATnew(TYPE_void, TYPE_##TPE, 
elementRepeats+groupRepeats+1, TRANSIENT); \
+               if(!resBAT) \
+            return NULL; \
+\
+fprintf(stderr, "createDimension: %ld total elements\n", 
(elementRepeats+groupRepeats+1)); \
+        vls = (TPE*)Tloc(resBAT, BUNfirst(resBAT)); \
+        for(i=0; i<elementRepeats; i++) { \
+            *vls = min; \
+            vls++; \
+        } \
+        for(i=0; i<groupRepeats; i++) { \
+            *vls = max; \
+            vls++; \
+        } \
+        *vls = step; \
+\
+        BATsetcount(resBAT,elementRepeats+groupRepeats+1); \
+        BATseqbase(resBAT,0); \
+        BATderiveProps(resBAT,FALSE); \
+               resBAT; \
+       })
diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c
--- a/sql/backends/monet5/sql.c
+++ b/sql/backends/monet5/sql.c
@@ -2231,51 +2231,56 @@ str materialiseDimension(bat* res, bat* 
 
        tpe = ATOMtype(dimensionBAT->ttype);
 
+#define dimensionCharacteristics(TPE, dimensionBAT, min, max, step, 
elementRepeats, groupRepeats) \
+do {\
+    TPE *vls; \
+    vls = (TPE*)Tloc(dimensionBAT, BUNfirst(dimensionBAT)); \
+    *min = vls[0]; \
+    *step = vls[BATcount(dimensionBAT)-1]; \
+    *max = vls[BATcount(dimensionBAT)-2]; \
+\
+    *elementRepeats = *groupRepeats = 0; \
+    vls = (TPE*)Tloc(dimensionBAT, BUNfirst(dimensionBAT)); \
+\
+    for(i=0; i<BATcount(dimensionBAT)-2; i++) { /*last element is the step and 
at least one element is max*/\
+        if(vls[i] != *min) \
+            break; \
+        (*elementRepeats)++; \
+    } \
+    *groupRepeats = BATcount(dimensionBAT)-i-1; \
+} while(0)
 
 #define materialise(TPE) \
     do { \
         /*find the min, max, step in the dimension*/ \
-        long repeat1, repeat2, elementsNum; \
+        long elementRepeats, groupRepeats, elementsNum; \
         TPE min, max, step; \
         oid i, j; \
-        TPE *el_in, *el_out, el; \
+        TPE *el_out, el; \
 \
-        el_in = (TPE*)Tloc(dimensionBAT, BUNfirst(dimensionBAT)); \
-        min = el_in[0]; \
-        step = el_in[BATcount(dimensionBAT)-1]; \
-               max = el_in[BATcount(dimensionBAT)-2]; \
+               dimensionCharacteristics(TPE, dimensionBAT, &min, &max, &step, 
&elementRepeats, &groupRepeats); \
+fprintf(stderr, "materialise: elementRepeats = %ld - groupRepeats = %ld\n", 
elementRepeats, groupRepeats); \
 \
-        repeat1 = 1; \
-        for(i=1; i<BATcount(dimensionBAT)-1; i++) { \
-            if(max != el_in[i]) \
-                repeat1++; \
-            else { \
-                               repeat2 = 0; \
-                break; \
-            } \
-        } \
-\
-        for(; i<BATcount(dimensionBAT)-1; i++) { \
-fprintf(stderr, "%u\n", (unsigned int)i); \
-            if(max == el_in[i]) \
-                repeat2++; \
-            else { \
-                break; \
-            } \
-        } \
-fprintf(stderr, "materialise repeat1 = %ld\n", repeat1); \
-fprintf(stderr, "materialise repeat2 = %ld\n", repeat2); \
-\
-        elementsNum = floor((max-min)/step) + 1; \
+               if(!step) { \
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to