Changeset: f8f9d71dd378 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=f8f9d71dd378
Modified Files:
        gdk/gdk_arrays.c
        gdk/gdk_arrays.h
        monetdb5/modules/kernel/arrays.c
        monetdb5/modules/kernel/arrays.h
Branch: arrays
Log Message:

fixed range selections and thetasubselects


diffs (268 lines):

diff --git a/gdk/gdk_arrays.c b/gdk/gdk_arrays.c
--- a/gdk/gdk_arrays.c
+++ b/gdk/gdk_arrays.c
@@ -540,7 +540,7 @@ gdk_return dimensionBATsubselect(BAT** o
                TPE min, max, step; \
                dimensionCharacteristics(TPE, dimensionBAT, &min, &max, &step, 
&elementRepeats, &groupRepeats); \
                elementsNum = dimensionElementsNum(min, max, step); \
-               element_oid = dimensionFndLowerValuePos(el, min, step, 
includeHigh>0); \
+               element_oid = dimensionFndLowerValuePos(el, min, max, step, 
includeHigh>0); \
                if(element_oid >= elementsNum) \
                        element_oid = elementsNum-1; /* all elements are 
included*/\
        } while(0)
diff --git a/gdk/gdk_arrays.h b/gdk/gdk_arrays.h
--- a/gdk/gdk_arrays.h
+++ b/gdk/gdk_arrays.h
@@ -95,18 +95,30 @@ gdk_cells* cells_replace_dimension(gdk_c
  * or the position of the index that is closest to the given value and greater 
than it*/
 #define dimensionFndGreaterValuePos(value, min, step, eq) \
        ({\
-               BUN pos = (BUN)(value-min)/step; \
-               fmod((value-min), step) ? ++pos : (pos +(1-eq)); \
+               BUN pos = 0; \
+               if(value >= min) { \
+                       /*the index of the value greater or equal to a value < 
min is the index of the min (0)*/ \
+                       pos = (BUN)(value-min)/step; \
+                       fmod((value-min), step) ? ++pos : (pos +=(1-eq)); \
+               } \
+               pos; \
        })
 
 /*find the position in the dimension indices (no repetitions) of the  given 
value
  * or the position of the index that is closest to the given value and smaller 
than it*/
-#define dimensionFndLowerValuePos(value, min, step, eq) \
+#define dimensionFndLowerValuePos(value, min, max, step, eq) \
        ({\
-               BUN pos = (BUN)(value-min)/step; \
-               if(value < min) \
-                       pos = -2; \
-               fmod((value-min), step) ? pos : (pos - (1-eq)); \
+               BUN pos = 0; \
+               if(value <= max) { \
+                       if(value < min) \
+                               pos = BUN_NONE; \
+                       pos = (BUN)(value-min)/step; \
+                       fmod((value-min), step) ? pos : (pos -= (1-eq)); \
+               } else {\
+                       /*the index of the value  <= to a value > max is the 
index of the max*/ \
+                       pos = (BUN)(max-min)/step; \
+               } \
+               pos; \
        })
 
 
@@ -143,39 +155,39 @@ gdk_cells* cells_replace_dimension(gdk_c
        idx; \
 })
 
-#define lowerIdx(dim, value, eq) \
+#define greaterIdx(dim, value, eq) \
 ({\
        BUN idx = 0; \
        switch(dim->type) { \
         case TYPE_bte: \
-                       idx = dimensionFndLowerValuePos(*(bte*)value, 
*(bte*)dim->min, *(bte*)dim->step, eq); \
+                       idx = dimensionFndLowerValuePos(*(bte*)value, 
*(bte*)dim->min, *(bte*)dim->max, *(bte*)dim->step, eq); \
                        break; \
         case TYPE_sht: \
-                       idx = dimensionFndLowerValuePos(*(sht*)value, 
*(sht*)dim->min, *(sht*)dim->step, eq); \
+                       idx = dimensionFndLowerValuePos(*(sht*)value, 
*(sht*)dim->min, *(sht*)dim->max, *(sht*)dim->step, eq); \
             break; \
         case TYPE_int:\
-                       idx = dimensionFndLowerValuePos(*(int*)value, 
*(int*)dim->min, *(int*)dim->step, eq); \
+                       idx = dimensionFndLowerValuePos(*(int*)value, 
*(int*)dim->min, *(int*)dim->max, *(int*)dim->step, eq); \
             break; \
         case TYPE_flt:\
-                       idx = dimensionFndLowerValuePos(*(flt*)value, 
*(flt*)dim->min, *(flt*)dim->step, eq); \
+                       idx = dimensionFndLowerValuePos(*(flt*)value, 
*(flt*)dim->min, *(flt*)dim->max, *(flt*)dim->step, eq); \
             break; \
         case TYPE_dbl:\
-                       idx = dimensionFndLowerValuePos(*(dbl*)value, 
*(dbl*)dim->min, *(dbl*)dim->step, eq); \
+                       idx = dimensionFndLowerValuePos(*(dbl*)value, 
*(dbl*)dim->min, *(dbl*)dim->max, *(dbl*)dim->step, eq); \
             break; \
         case TYPE_lng:\
-                       idx = dimensionFndLowerValuePos(*(lng*)value, 
*(lng*)dim->min, *(lng*)dim->step, eq); \
+                       idx = dimensionFndLowerValuePos(*(lng*)value, 
*(lng*)dim->min, *(lng*)dim->max, *(lng*)dim->step, eq); \
             break; \
         case TYPE_hge:\
-                       idx = dimensionFndLowerValuePos(*(hge*)value, 
*(hge*)dim->min, *(hge*)dim->step, eq); \
+                       idx = dimensionFndLowerValuePos(*(hge*)value, 
*(hge*)dim->min, *(hge*)dim->max, *(hge*)dim->step, eq); \
                        break; \
         case TYPE_oid:\
-                       idx = dimensionFndLowerValuePos(*(oid*)value, 
*(oid*)dim->min, *(oid*)dim->step, eq); \
+                       idx = dimensionFndLowerValuePos(*(oid*)value, 
*(oid*)dim->min, *(oid*)dim->max, *(oid*)dim->step, eq); \
             break; \
        } \
        idx; \
 })
 
-#define greaterIdx(dim, value, eq) \
+#define lowerIdx(dim, value, eq) \
 ({\
        BUN idx = 0; \
        switch(dim->type) { \
diff --git a/monetdb5/modules/kernel/arrays.c b/monetdb5/modules/kernel/arrays.c
--- a/monetdb5/modules/kernel/arrays.c
+++ b/monetdb5/modules/kernel/arrays.c
@@ -229,12 +229,9 @@ str ALGdimensionSubselect2(ptr *dimsRes,
        gdk_cells *dimensionsCandidates_in = NULL, *dimensionsCandidates_out = 
NULL;
        BAT *candidatesBAT_in = NULL, *candidatesBAT_out = NULL;
 
-       gdk_dimension *dimensionCand_in = NULL, *dimensionCand_out = NULL;
-
        int type;
        const void *nil;
 
-       (void)(bit*)hi;
        (void)(bit*)anti;
        
        if(oidsCand) {
@@ -278,7 +275,35 @@ str ALGdimensionSubselect2(ptr *dimsRes,
                                return emptyCandidateResults(dimsRes, oidsRes);
                        }
                }
-       } else if(ATOMcmp(type, low, nil) == 0 && ATOMcmp(type, high, nil) == 
0) {
+       } else if(ATOMcmp(type, low, nil) == 0) { //no lower bound
+               oid qualifyingIdx_min = 0; 
+               oid qualifyingIdx_max = greaterIdx(dimension, high, *hi); 
+       
+               if(qualifyingIdx_max >= dimension->initialElementsNum) {
+                       freeCells(dimensionsCandidates_in);
+                       return emptyCandidateResults(dimsRes, oidsRes);
+               } else {
+                       if(!updateCandidateResults(&dimensionsCandidates_out, 
&candidatesBAT_out, dimensionsCandidates_in, candidatesBAT_in, 
dimension->dimNum, dimension->initialElementsNum, qualifyingIdx_min, 
qualifyingIdx_max)) {
+                               //remove all the dimensions, there will be no 
results in the output
+                               freeCells(dimensionsCandidates_in);
+                               return emptyCandidateResults(dimsRes, oidsRes);
+                       }
+               } 
+       } else if(ATOMcmp(type, high, nil) == 0) { //no upper bound
+               oid qualifyingIdx_min = lowerIdx(dimension, low, *li); 
+               oid qualifyingIdx_max = dimension->initialElementsNum-1;
+
+               if(qualifyingIdx_min >= dimension->initialElementsNum) {
+                       freeCells(dimensionsCandidates_in);
+                       return emptyCandidateResults(dimsRes, oidsRes);
+               } else {
+                       if(!updateCandidateResults(&dimensionsCandidates_out, 
&candidatesBAT_out, dimensionsCandidates_in, candidatesBAT_in, 
dimension->dimNum, dimension->initialElementsNum, qualifyingIdx_min, 
qualifyingIdx_max)) {
+                               //remove all the dimensions, there will be no 
results in the output
+                               freeCells(dimensionsCandidates_in);
+                               return emptyCandidateResults(dimsRes, oidsRes);
+                       }
+               } 
+       } else if(ATOMcmp(type, low, nil) != 0 && ATOMcmp(type, high, nil) != 
0) {
                oid qualifyingIdx_min = lowerIdx(dimension, low, *li); 
                oid qualifyingIdx_max = greaterIdx(dimension, high, *hi); 
 
@@ -286,27 +311,15 @@ str ALGdimensionSubselect2(ptr *dimsRes,
                        freeCells(dimensionsCandidates_in);
                        return emptyCandidateResults(dimsRes, oidsRes);
                } else {
-                       dimensionCand_out = 
createDimension_oid(dimension->dimNum, dimension->initialElementsNum, 
qualifyingIdx_min, qualifyingIdx_max, 1);
-                       dimensionCand_in = 
getDimension(dimensionsCandidates_in, dimension->dimNum);
-
-                       //if the existing results for the dimension and the new 
computed results can be combined in a new dimension
-                       if(compatibleRanges(dimensionCand_in, 
dimensionCand_out)) {
-                               //merge the dimension in the candidates with 
the result of this operation
-                               dimensionCand_out = 
mergeCandidateDimensions(dimensionCand_in, dimensionCand_out);
-                               if(!dimensionCand_out) {
-                                       //the dimensions cannot be merged to a 
new dimension. Create a BAT
-                                       dimensionsCandidates_out = 
cells_remove_dimension(dimensionsCandidates_in, dimensionCand_in->dimNum);
-                               } else 
-                                       dimensionsCandidates_out = 
cells_replace_dimension(dimensionsCandidates_in, dimensionCand_out);
-                       } else {
+                       if(!updateCandidateResults(&dimensionsCandidates_out, 
&candidatesBAT_out, dimensionsCandidates_in, candidatesBAT_in, 
dimension->dimNum, dimension->initialElementsNum, qualifyingIdx_min, 
qualifyingIdx_max)) {
                                //remove all the dimensions, there will be no 
results in the output
                                freeCells(dimensionsCandidates_in);
                                return emptyCandidateResults(dimsRes, oidsRes);
-                       }       
+                       }
                } 
-               
-
-               return MAL_SUCCEED;
+       } else {
+               //both values are NULL. Empty result
+               return emptyCandidateResults(dimsRes, oidsRes);
        }
 
        if(oidsCand && candidatesBAT_in != candidatesBAT_out) //there was a 
candidatesBAT in the input that is not sent in the output
@@ -324,6 +337,64 @@ str ALGdimensionSubselect1(ptr *dimsRes,
        return ALGdimensionSubselect2(dimsRes, oidsRes, dims, dim, NULL, NULL, 
low, high, li, hi, anti);
 }
 
+str ALGdimensionThetasubselect2(ptr *dimsRes, bat* oidsRes, const ptr *dims, 
const ptr* dim, const ptr *dimsCand, const bat* oidsCand, const void *val, 
const char **opp) {
+       bit li = 0;
+       bit hi = 0;
+       bit anti = 0;
+       const char *op = *opp;
+       gdk_dimension *dimension = *dim;
+       const void *nil = ATOMnilptr(dimension->type);
+
+       if (op[0] == '=' && ((op[1] == '=' && op[2] == 0) || op[2] == 0)) {
+        /* "=" or "==" */
+               li = hi = 1;
+               anti = 0;
+        return ALGdimensionSubselect2(dimsRes, oidsRes, dims, dim, dimsCand, 
oidsCand, val, nil, &li, &hi, &anti);
+    }
+    if (op[0] == '!' && op[1] == '=' && op[2] == 0) {
+        /* "!=" (equivalent to "<>") */ 
+               li = hi = anti = 1;
+        return ALGdimensionSubselect2(dimsRes, oidsRes, dims, dim, dimsCand, 
oidsCand, val, nil, &li, &hi, &anti);
+    }
+    if (op[0] == '<') { 
+        if (op[1] == 0) {
+            /* "<" */
+                       li = hi = anti = 0;
+            return ALGdimensionSubselect2(dimsRes, oidsRes, dims, dim, 
dimsCand, oidsCand, nil, val, &li, &hi, &anti);
+        }
+        if (op[1] == '=' && op[2] == 0) {
+            /* "<=" */
+                       li = anti = 0;
+                       hi = 1;
+            return ALGdimensionSubselect2(dimsRes, oidsRes, dims, dim, 
dimsCand, oidsCand, nil, val, &li, &hi, &anti);
+        }
+        if (op[1] == '>' && op[2] == 0) {
+            /* "<>" (equivalent to "!=") */ 
+                       li = hi = anti = 1;
+            return ALGdimensionSubselect2(dimsRes, oidsRes, dims, dim, 
dimsCand, oidsCand, val, nil, &li, &hi, &anti);
+        }
+    }
+    if (op[0] == '>') { 
+        if (op[1] == 0) {
+            /* ">" */
+                       li = hi = anti = 0;
+            return ALGdimensionSubselect2(dimsRes, oidsRes, dims, dim, 
dimsCand, oidsCand, val, nil, &li, &hi, &anti);
+        }
+        if (op[1] == '=' && op[2] == 0) {
+            /* ">=" */
+                       li = 1;
+                       hi = anti = 0;
+            return ALGdimensionSubselect2(dimsRes, oidsRes, dims, dim, 
dimsCand, oidsCand, val, nil, &li, &hi, &anti);
+        }
+    }
+
+    throw(MAL, "algebra.dimensionThetasubselect", "BATdimensionThetasubselect: 
unknown operator.\n");
+}
+
+str ALGdimensionThetasubselect1(ptr *dimsRes, bat* oidsRes, const ptr *dims, 
const ptr* dim, const void *val, const char **op) {
+       return ALGdimensionThetasubselect2(dimsRes, oidsRes, dims, dim, NULL, 
NULL, val, op);
+}
+
 str ALGmbrproject(bat *result, const bat *bid, const bat *sid, const bat* rid) 
{
     BAT *b, *s, *r, *bn;
 
diff --git a/monetdb5/modules/kernel/arrays.h b/monetdb5/modules/kernel/arrays.h
--- a/monetdb5/modules/kernel/arrays.h
+++ b/monetdb5/modules/kernel/arrays.h
@@ -20,8 +20,8 @@ algebra_export str ALGdimensionSubselect
                             const void *low, const void *high, const bit *li, 
const bit *hi, const bit *anti);
 algebra_export str ALGdimensionSubselect1(ptr *dimsRes, bat* oidsRes, const 
ptr *dims, const ptr* dim, 
                             const void *low, const void *high, const bit *li, 
const bit *hi, const bit *anti);
-//algebra_export str ALGdimensionThetasubselect1(bat *result, const bat *bid, 
const void *val, const char **op);
-//algebra_export str ALGdimensionThetasubselect2(bat *result, const bat *bid, 
const bat *sid, const void *val, const char **op);
+algebra_export str ALGdimensionThetasubselect2(ptr *dimsRes, bat* oidsRes, 
const ptr *dims, const ptr* dim, const ptr *dimsCand, const bat* oidsCand, 
const void *val, const char **op);
+algebra_export str ALGdimensionThetasubselect1(ptr *dimsRes, bat* oidsRes, 
const ptr *dims, const ptr* dim, const void *val, const char **op);
 
 algebra_export str ALGmbrsubselect(bat *result, const bat *bid, const bat 
*sid, const bat *cid);
 algebra_export str ALGmbrsubselect2(bat *result, const bat *bid, const bat 
*sid);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to