00001
00002
00003
00004
00005
00006
00007 #ifndef IBIS_EXPR_H
00008 #define IBIS_EXPR_H
00012 #include "util.h"
00013 #include <functional>
00014
00015 namespace ibis {
00016 class qRange;
00017 class qContinuousRange;
00018 class qDiscreteRange;
00019 class qString;
00020 class qMultiString;
00021 class compRange;
00022 class rangeJoin;
00023 class qAnyAny;
00024 }
00025
00029 class ibis::qExpr {
00030 public:
00033 enum TYPE {
00034 LOGICAL_UNDEFINED, LOGICAL_NOT, LOGICAL_AND, LOGICAL_OR, LOGICAL_XOR,
00035 LOGICAL_MINUS, RANGE, DRANGE, STRING, MSTRING, COMPRANGE, MATHTERM,
00036 JOIN, TOPK, ANYANY
00037 };
00039 enum COMPARE {
00040 OP_UNDEFINED, OP_LT, OP_GT, OP_LE, OP_GE, OP_EQ
00041 };
00042
00044 qExpr() : type(LOGICAL_UNDEFINED), left(0), right(0) {}
00045
00047 explicit qExpr(TYPE op) : type(op), left(0), right(0) {}
00049 qExpr(TYPE op, qExpr* qe1, qExpr* qe2) : type(op), left(qe1),
00050 right(qe2) {}
00052 qExpr(const qExpr& qe) : type(qe.type),
00053 left(qe.left ? qe.left->dup() : 0),
00054 right(qe.right ? qe.right->dup() : 0) {}
00056 virtual ~qExpr() {delete right; delete left;}
00057
00059 void setLeft(qExpr *expr) {delete left; left=expr;}
00061 void setRight(qExpr *expr) {delete right; right=expr;}
00063 qExpr*& getLeft() {return left;}
00065 qExpr*& getRight() {return right;}
00066
00068 TYPE getType() const {return type;}
00070 const qExpr* getLeft() const {return left;}
00072 const qExpr* getRight() const {return right;}
00073
00075 bool hasJoin() const;
00076
00078 virtual void print(std::ostream&) const;
00079
00082 virtual void printRange(std::ostream& out) const {
00083 if (left) left->printRange(out);
00084 if (right) right->printRange(out);
00085 };
00086
00088 struct weight {
00089 virtual double operator()(const qExpr* ex) const = 0;
00090 virtual ~weight() {};
00091 };
00092 double reorder(const weight&);
00093
00094 virtual qExpr* dup() const {
00095 qExpr* res = new qExpr(type);
00096 if (left)
00097 res->left = left->dup();
00098 if (right)
00099 res->right = right->dup();
00100 return res;
00101 }
00102
00103 bool isTerminal() const {return (left==0 && right==0);}
00104 bool directEval() const
00105 {return (type==RANGE || type==STRING || type==COMPRANGE ||
00106 type==DRANGE || type==MSTRING || type==ANYANY ||
00107 (type==LOGICAL_NOT && left && left->directEval()));}
00108
00111 virtual bool isSimple() const {
00112 if (left) {
00113 if (right) return left->isSimple() && right->isSimple();
00114 else return left->isSimple();
00115 }
00116 else if (right) {
00117 return right->isSimple();
00118 }
00119 else {
00120 return true;
00121 }
00122 }
00123
00127 int separateSimple(ibis::qExpr *&simple, ibis::qExpr *&tail) const;
00128
00130 void extractJoins(std::vector<const rangeJoin*>& terms) const;
00132 qRange* findRange(const char* vname);
00133
00137 static void simplify(ibis::qExpr*&);
00138
00139 const qExpr& operator=(const qExpr& rhs) {
00140 delete left; delete right;
00141 type = rhs.type;
00142 left = (rhs.left != 0 ? rhs.left->dup() : 0);
00143 right = (rhs.right != 0 ? rhs.right->dup() : 0);
00144 return *this;
00145 }
00146
00147 private:
00148 TYPE type;
00149 qExpr* left;
00150 qExpr* right;
00151
00152
00153 void adjust();
00154 };
00155
00160 class ibis::qRange : public ibis::qExpr {
00161 public:
00163 virtual const char* colName() const = 0;
00166 virtual bool inRange(double val) const = 0;
00167
00169 virtual void restrictRange(double left, double right) = 0;
00171 virtual const double& leftBound() const = 0;
00173 virtual const double& rightBound() const = 0;
00175 virtual bool empty() const = 0;
00176
00177 virtual ~qRange() {};
00178
00179 protected:
00180
00181 qRange() : qExpr(RANGE) {};
00182 qRange(TYPE t) : qExpr(t) {};
00183
00184 private:
00185 qRange(const qRange&) {};
00186 const qRange& operator=(const qRange&);
00187 };
00188
00204 class ibis::qContinuousRange : public ibis::qRange {
00205 public:
00207 qContinuousRange() : name(0), lower(0), upper(0), left_op(OP_UNDEFINED),
00208 right_op(OP_UNDEFINED) {};
00210 qContinuousRange(const char* lstr, COMPARE lop, const char* prop,
00211 COMPARE rop, const char* rstr);
00213 qContinuousRange(const char* col, COMPARE op, uint32_t val) :
00214 name(ibis::util::strnewdup(col)), lower(val),
00215 upper(DBL_MAX), left_op(op), right_op(OP_UNDEFINED) {};
00217 qContinuousRange(const qContinuousRange& rhs) :
00218 name(ibis::util::strnewdup(rhs.name)), lower(rhs.lower),
00219 upper(rhs.upper), left_op(rhs.left_op), right_op(rhs.right_op) {};
00221 qContinuousRange(double lv, COMPARE lop, const char* prop,
00222 COMPARE rop, double rv)
00223 : name(ibis::util::strnewdup(prop)), lower(lv),
00224 upper(rv), left_op(lop), right_op(rop) {};
00226 qContinuousRange(const char* prop, COMPARE op, double val)
00227 : name(ibis::util::strnewdup(prop)), lower(-DBL_MAX),
00228 upper(val), left_op(OP_UNDEFINED), right_op(op) {
00229
00230 if (right_op == ibis::qExpr::OP_GT) {
00231 right_op = ibis::qExpr::OP_UNDEFINED;
00232 left_op = ibis::qExpr::OP_LT;
00233 lower = upper;
00234 upper = DBL_MAX;
00235 }
00236 else if (right_op == ibis::qExpr::OP_GE) {
00237 right_op = ibis::qExpr::OP_UNDEFINED;
00238 left_op = ibis::qExpr::OP_LE;
00239 lower = upper;
00240 upper = DBL_MAX;
00241 }
00242 };
00243
00244 virtual ~qContinuousRange() {delete [] name;}
00245
00246
00247 virtual const char *colName() const {return name;}
00248 COMPARE leftOperator() const {return left_op;}
00249 COMPARE rightOperator() const {return right_op;}
00250 virtual const double& leftBound() const {
00251 return (right_op != OP_EQ ? lower : upper);}
00252 virtual const double& rightBound() const {
00253 return (left_op != OP_EQ ? upper : lower);}
00254
00255
00256 double& leftBound() {return lower;}
00257 double& rightBound() {return upper;}
00258 COMPARE& leftOperator() {return left_op;}
00259 COMPARE& rightOperator() {return right_op;}
00260
00261
00262 void foldBoundaries();
00263
00264 void foldUnsignedBoundaries();
00265
00266
00267 virtual qContinuousRange* dup() const {return new qContinuousRange(*this);}
00268
00269 inline virtual bool inRange(double val) const;
00270 virtual void restrictRange(double left, double right);
00271 virtual bool empty() const;
00272
00273
00274 virtual void print(std::ostream&) const;
00275 virtual void printRange(std::ostream& out) const;
00276
00277 inline bool operator<(const qContinuousRange& y) const;
00278
00279 private:
00280 char* name;
00281 double lower, upper;
00282 COMPARE left_op, right_op;
00283
00284 const qContinuousRange& operator=(const qContinuousRange&);
00285 friend void ibis::qExpr::simplify(ibis::qExpr*&);
00286 };
00287
00290 class ibis::qDiscreteRange : public ibis::qRange {
00291 public:
00293 qDiscreteRange() : qRange(DRANGE) {};
00295 qDiscreteRange(const char *col, const char *nums);
00298 qDiscreteRange(const char *col, const std::vector<uint32_t>& val);
00301 qDiscreteRange(const char *col, const std::vector<double>& val);
00302
00304 qDiscreteRange(const qDiscreteRange& dr)
00305 : qRange(DRANGE), name(dr.name), values(dr.values) {}
00306 virtual ~qDiscreteRange() {};
00307
00308
00309 virtual const char* colName() const {return name.c_str();}
00310 const std::vector<double>& getValues() const {return values;}
00311 std::vector<double>& getValues() {return values;}
00312
00314 virtual qDiscreteRange* dup() const {return new qDiscreteRange(*this);}
00316 inline virtual bool inRange(double val) const;
00317 virtual void restrictRange(double left, double right);
00318 virtual bool empty() const {return values.empty();}
00319 virtual const double& leftBound() const {return values.front();}
00320 virtual const double& rightBound() const {return values.back();}
00321
00323 ibis::qExpr* convert() const;
00324
00325 virtual void print(std::ostream& out) const;
00326 virtual void printRange(std::ostream& out) const;
00327
00328 private:
00329 std::string name;
00330 std::vector<double> values;
00331
00332 const qDiscreteRange& operator=(const qDiscreteRange&);
00333 };
00334
00345 class ibis::qString : public ibis::qExpr {
00346 public:
00347
00348 qString() : lstr(0), rstr(0) {};
00349 qString(const char* ls, const char* rs);
00350 virtual ~qString() {delete [] rstr; delete [] lstr;}
00351
00352 const char* leftString() const {return lstr;}
00353 const char* rightString() const {return rstr;}
00354
00355 virtual qString* dup() const {return new qString(*this);}
00356 virtual void print(std::ostream&) const;
00357
00358 private:
00359 char* lstr;
00360 char* rstr;
00361
00362 qString(const qString& rhs) : qExpr(STRING),
00363 lstr(ibis::util::strnewdup(rhs.lstr)),
00364 rstr(ibis::util::strnewdup(rhs.rstr)) {}
00365 const qString& operator=(const qString&);
00366 };
00367
00368
00369
00370 class ibis::qMultiString : public ibis::qExpr {
00371 public:
00372 qMultiString() : qExpr(MSTRING) {};
00373 qMultiString(const char *col, const char *sval);
00374 virtual ~qMultiString() {};
00375
00377 virtual qMultiString* dup() const {return new qMultiString(*this);}
00378 virtual void print(std::ostream& out) const;
00379
00381 const char* colName() const {return name.c_str();}
00383 const std::vector<std::string>& valueList() const {return values;}
00385 ibis::qExpr* convert() const;
00386
00387 private:
00388 std::string name;
00389 std::vector<std::string> values;
00390 };
00391
00394 class ibis::compRange : public ibis::qExpr {
00395 public:
00396
00397 enum TERM_TYPE {UNDEFINED, VARIABLE, NUMBER, STRING, OPERATOR,
00398 STDFUNCTION1, STDFUNCTION2,
00399 CUSTOMFUNCTION1, CUSTOMFUNCTION2};
00400
00401 enum OPERADOR {UNKNOWN=0, BITOR, BITAND,
00402 PLUS, MINUS, MULTIPLY, DIVIDE, REMAINDER, NEGATE, POWER};
00403
00404 enum STDFUN1 {ACOS=0, ASIN, ATAN, CEIL, COS, COSH, EXP, FABS, FLOOR,
00405 FREXP, LOG10, LOG, MODF, SIN, SINH, SQRT, TAN, TANH};
00406 enum STDFUN2 {ATAN2=0, FMOD, LDEXP, POW};
00407
00408 static char* operator_name[];
00409 static char* stdfun1_name[];
00410 static char* stdfun2_name[];
00411
00412 class term;
00413 class variable;
00414 class bediener;
00416 class barrel {
00417 public:
00418
00419 barrel() {};
00420 barrel(const term* const t) {recordVariable(t);}
00421 virtual ~barrel() {};
00422
00423
00424 uint32_t size() const {return varmap.size();}
00425 const char* name(uint32_t i) const {return namelist[i];}
00426 const double& value(uint32_t i) const {return varvalues[i];}
00427 double& value(uint32_t i) {return varvalues[i];}
00428
00430 void recordVariable(const term* const t);
00434 inline uint32_t recordVariable(const char* name);
00436 bool equivalent(const barrel& rhs) const;
00437
00438 protected:
00439
00440
00441 typedef std::map< const char*, uint32_t, ibis::lessi > termMap;
00442
00443
00444
00445 friend class variable;
00446 double getValue(uint32_t i) const {return varvalues[i];}
00448 double getValue(const char* nm) const {
00449 termMap::const_iterator it = varmap.find(nm);
00450 if (it != varmap.end()) {
00451 uint32_t i = (*it).second;
00452 return varvalues[i];
00453 }
00454 else {
00455 return DBL_MAX;
00456 }
00457 }
00458
00461 termMap varmap;
00462 std::vector< double > varvalues;
00463 std::vector< const char* > namelist;
00464 };
00465
00467 class term : public ibis::qExpr {
00468 public:
00469 virtual ~term() {};
00470
00471 virtual TERM_TYPE termType() const = 0;
00472
00473
00474 virtual double eval() const = 0;
00475
00476 virtual term* dup() const = 0;
00477
00478 virtual void print(std::ostream& out) const = 0;
00479
00480
00481
00482 virtual term* reduce() {return this;};
00483
00484 protected:
00485 term() : qExpr(MATHTERM) {};
00486 };
00487
00489 class variable : public term {
00490 public:
00491
00492
00493
00494 variable(const char* var)
00495 : name(ibis::util::strnewdup(var)), myBar(0), varind(0) {}
00496 variable(const variable& v)
00497 : name(ibis::util::strnewdup(v.name)), myBar(v.myBar),
00498 varind(v.varind) {}
00499 virtual ~variable() {delete [] name;}
00500
00501 virtual TERM_TYPE termType() const {return VARIABLE;}
00502 virtual variable* dup() const {return new variable(*this);}
00503 virtual double eval() const {return myBar->getValue(varind);}
00504 virtual void print(std::ostream& out) const {out << name;}
00505 const char* variableName() const {return name;}
00506
00507 void recordVariable(barrel& bar) const {
00508 varind = bar.recordVariable(name);
00509 myBar = &bar;
00510 }
00511
00512 private:
00513 char* name;
00514 mutable barrel* myBar;
00515 mutable uint32_t varind;
00516
00517 const variable& operator=(const variable&);
00518 };
00519
00521 class number : public term {
00522 public:
00523 number(const char* num) : val(atof(num)) {};
00524 number(double v) : val(v) {};
00525 virtual ~number() {};
00526
00527 virtual TERM_TYPE termType() const {return NUMBER;}
00528 virtual number* dup() const {return new number(val);}
00529 virtual double eval() const {return val;}
00530 virtual void print(std::ostream& out) const {out << val;}
00531
00532
00533 void negate() {val = -val;}
00534
00535 void invert() {val = 1.0/val;}
00536
00537 private:
00538 double val;
00539 friend class bediener;
00540 friend void ibis::qExpr::simplify(ibis::qExpr*&);
00541 };
00542
00544 class literal : public term {
00545 public:
00546 literal(const char* s) : str(ibis::util::strnewdup(s)) {};
00547 virtual ~literal() {delete [] str;}
00548
00549 virtual TERM_TYPE termType() const {return ibis::compRange::STRING;}
00550 virtual literal* dup() const {return new literal(str);}
00551 virtual double eval() const {return 0.0;}
00552 virtual void print(std::ostream& out) const {out << str;}
00553
00554 private:
00555 char* str;
00556
00557 literal(const literal&);
00558 const literal& operator=(const literal&);
00559 };
00560
00561
00562 class bediener : public term {
00563 public:
00564 bediener(ibis::compRange::OPERADOR op) : operador(op) {};
00565 virtual ~bediener() {};
00566
00567 virtual TERM_TYPE termType() const {return OPERATOR;}
00568 virtual bediener* dup() const {
00569 bediener *tmp = new bediener(operador);
00570 tmp->setRight(getRight()->dup());
00571 tmp->setLeft(getLeft()->dup());
00572 return tmp;
00573 }
00574 inline virtual double eval() const;
00575 virtual void print(std::ostream& out) const;
00576 virtual term* reduce();
00577
00578 private:
00579 ibis::compRange::OPERADOR operador;
00580
00581 void reorder();
00582
00583
00584 void linearize(const ibis::compRange::OPERADOR op,
00585 std::vector<ibis::compRange::term*>& terms);
00586
00587
00588 void convertConstants();
00589 friend void ibis::qExpr::simplify(ibis::qExpr*&);
00590 };
00591
00593 class stdFunction1 : public term {
00594 public:
00595 stdFunction1(const char* name);
00596 stdFunction1(const STDFUN1 ft) : ftype(ft) {}
00597 virtual ~stdFunction1() {}
00598
00599 virtual stdFunction1* dup() const {
00600 stdFunction1 *tmp = new stdFunction1(ftype);
00601 tmp->setLeft(getLeft()->dup());
00602 return tmp;
00603 }
00604 virtual TERM_TYPE termType() const {return STDFUNCTION1;}
00605 inline virtual double eval() const;
00606 virtual void print(std::ostream& out) const;
00607 inline virtual term* reduce();
00608
00609 private:
00610 STDFUN1 ftype;
00611 };
00612
00614 class stdFunction2 : public term {
00615 public:
00616 stdFunction2(const char* name);
00617 stdFunction2(const STDFUN2 ft) : ftype(ft) {}
00618 virtual ~stdFunction2() {}
00619
00620 virtual stdFunction2* dup() const {
00621 stdFunction2 *tmp = new stdFunction2(ftype);
00622 tmp->setRight(getRight()->dup());
00623 tmp->setLeft(getLeft()->dup());
00624 return tmp;
00625 }
00626 virtual TERM_TYPE termType() const {return STDFUNCTION2;}
00627 inline virtual double eval() const;
00628 virtual void print(std::ostream& out) const;
00629 inline virtual term* reduce();
00630
00631 private:
00632 STDFUN2 ftype;
00633 };
00634
00635
00636
00637 compRange() : qExpr(ibis::qExpr::COMPRANGE), expr3(0),
00638 op12(ibis::qExpr::OP_UNDEFINED),
00639 op23(ibis::qExpr::OP_UNDEFINED) {;}
00640 compRange(ibis::compRange::term* me1, COMPARE lop,
00641 ibis::compRange::term* me2)
00642 : qExpr(ibis::qExpr::COMPRANGE, me1, me2), expr3(0),
00643 op12(lop), op23(ibis::qExpr::OP_UNDEFINED) {;}
00644 compRange(ibis::compRange::term* me1, ibis::qExpr::COMPARE lop,
00645 ibis::compRange::term* me2, ibis::qExpr::COMPARE rop,
00646 ibis::compRange::term* me3)
00647 : qExpr(ibis::qExpr::COMPRANGE, me1, me2), expr3(me3),
00648 op12(lop), op23(rop) {;}
00649
00650 compRange(const compRange& rhs) :
00651 ibis::qExpr(rhs), expr3(rhs.expr3 ? rhs.expr3->dup() : 0),
00652 op12(rhs.op12), op23(rhs.op23) {};
00653 virtual ~compRange() {delete expr3;}
00654
00655
00656 ibis::qExpr::COMPARE leftOperator() const {return op12;}
00657 ibis::qExpr::COMPARE rightOperator() const {return op23;}
00658 term* getTerm3() {return expr3;}
00659 const term* getTerm3() const {return expr3;}
00660 void setTerm3(term* t) {delete expr3; expr3 = t;}
00661
00663 virtual qExpr* dup() const {return new compRange(*this);}
00665 inline bool inRange() const;
00667 virtual void print(std::ostream&) const;
00668
00669 virtual bool isSimple() const {return isSimpleRange();}
00671 inline bool isSimpleRange() const;
00672
00674 bool maybeStringCompare() const;
00675
00676
00677 ibis::qContinuousRange* simpleRange() const;
00678
00679 private:
00680 ibis::compRange::term *expr3;
00681 ibis::qExpr::COMPARE op12;
00682 ibis::qExpr::COMPARE op23;
00683 };
00684
00689 class ibis::rangeJoin : public ibis::qExpr {
00690 public:
00691 rangeJoin(const char* n1, const char *n2)
00692 : ibis::qExpr(ibis::qExpr::JOIN), name1(n1), name2(n2), expr(0) {};
00693 rangeJoin(const char* n1, const char *n2, ibis::compRange::term *x) :
00694 ibis::qExpr(ibis::qExpr::JOIN), name1(n1), name2(n2), expr(x) {};
00695 virtual ~rangeJoin() {delete expr;};
00696
00697 virtual void print(std::ostream& out) const;
00698 virtual rangeJoin* dup() const
00699 {return new rangeJoin(name1.c_str(), name2.c_str(), expr->dup());};
00700
00701 const char* getName1() const {return name1.c_str();}
00702 const char* getName2() const {return name2.c_str();}
00703 ibis::compRange::term* getRange() {return expr;}
00704 const ibis::compRange::term* getRange() const {return expr;}
00705 void setRange(ibis::compRange::term *t) {delete expr; expr = t;}
00706
00707 private:
00708 std::string name1;
00709 std::string name2;
00710 ibis::compRange::term *expr;
00711
00712 rangeJoin(const rangeJoin&);
00713 const rangeJoin& operator=(const rangeJoin&);
00714 };
00715
00727 class ibis::qAnyAny : public ibis::qExpr {
00728 public:
00729 qAnyAny() : qExpr(ANYANY) {};
00730 qAnyAny(const char *pre, const char *val);
00731 ~qAnyAny() {};
00732
00733 const char* getPrefix() const {return prefix.c_str();}
00734 const std::vector<double>& getValues() const {return values;}
00735
00736
00737 virtual qExpr* dup() const {return new qAnyAny(*this);}
00738
00739 virtual void print(std::ostream& out) const;
00740 virtual void printRange(std::ostream& out) const;
00741
00742 private:
00743 std::string prefix;
00744 std::vector<double> values;
00745 };
00746
00747
00748 inline bool ibis::qContinuousRange::inRange(double val) const {
00749 volatile bool res0 = true;
00750 volatile bool res1 = true;
00751 switch (left_op) {
00752 case OP_LT: res0 = (lower < val); break;
00753 case OP_LE: res0 = (lower <= val); break;
00754 case OP_GT: res0 = (lower > val); break;
00755 case OP_GE: res0 = (lower >= val); break;
00756 case OP_EQ: res0 = (lower == val); break;
00757 default: break;
00758 }
00759 switch (right_op) {
00760 case OP_LT: res1 = (val < upper); break;
00761 case OP_LE: res1 = (val <= upper); break;
00762 case OP_GT: res1 = (val > upper); break;
00763 case OP_GE: res1 = (val >= upper); break;
00764 case OP_EQ: res1 = (val == upper); break;
00765 default: break;
00766 }
00767 return res0 && res1;
00768 }
00769
00770 inline void ibis::qContinuousRange::foldBoundaries() {
00771 switch (left_op) {
00772 case ibis::qExpr::OP_LT:
00773 lower = floor(lower);
00774 break;
00775 case ibis::qExpr::OP_LE:
00776 lower = ceil(lower);
00777 break;
00778 case ibis::qExpr::OP_GT:
00779 lower = ceil(lower);
00780 break;
00781 case ibis::qExpr::OP_GE:
00782 lower = floor(lower);
00783 break;
00784 case ibis::qExpr::OP_EQ:
00785 if (lower != floor(lower))
00786 left_op = ibis::qExpr::OP_UNDEFINED;
00787 break;
00788 default:
00789 break;
00790 }
00791 switch (right_op) {
00792 case ibis::qExpr::OP_LT:
00793 upper = ceil(upper);
00794 break;
00795 case ibis::qExpr::OP_LE:
00796 upper = floor(upper);
00797 break;
00798 case ibis::qExpr::OP_GT:
00799 upper = floor(upper);
00800 break;
00801 case ibis::qExpr::OP_GE:
00802 upper = ceil(upper);
00803 break;
00804 case ibis::qExpr::OP_EQ:
00805 if (upper != floor(upper))
00806 right_op = ibis::qExpr::OP_UNDEFINED;
00807 break;
00808 default:
00809 break;
00810 }
00811 }
00812
00813 inline void ibis::qContinuousRange::foldUnsignedBoundaries() {
00814 switch (left_op) {
00815 case ibis::qExpr::OP_LT:
00816 if (lower >= 0.0) {
00817 lower = floor(lower);
00818 }
00819 else {
00820 left_op = ibis::qExpr::OP_LE;
00821 lower = 0.0;
00822 }
00823 break;
00824 case ibis::qExpr::OP_LE:
00825 if (lower >= 0.0)
00826 lower = ceil(lower);
00827 else
00828 lower = 0.0;
00829 break;
00830 case ibis::qExpr::OP_GT:
00831 lower = ceil(lower);
00832 break;
00833 case ibis::qExpr::OP_GE:
00834 lower = floor(lower);
00835 break;
00836 case ibis::qExpr::OP_EQ:
00837 if (lower != floor(lower) || lower < 0.0)
00838 left_op = ibis::qExpr::OP_UNDEFINED;
00839 break;
00840 default:
00841 break;
00842 }
00843 switch (right_op) {
00844 case ibis::qExpr::OP_LT:
00845 upper = ceil(upper);
00846 break;
00847 case ibis::qExpr::OP_LE:
00848 upper = floor(upper);
00849 break;
00850 case ibis::qExpr::OP_GT:
00851 if (upper > 0.0) {
00852 upper = floor(upper);
00853 }
00854 else {
00855 right_op = ibis::qExpr::OP_GE;
00856 upper = 0.0;
00857 }
00858 break;
00859 case ibis::qExpr::OP_GE:
00860 if (upper >= 0.0)
00861 upper = ceil(upper);
00862 else
00863 upper = 0.0;
00864 break;
00865 case ibis::qExpr::OP_EQ:
00866 if (upper != floor(upper) || upper < 0.0)
00867 right_op = ibis::qExpr::OP_UNDEFINED;
00868 break;
00869 default:
00870 break;
00871 }
00872 }
00873
00874
00875 inline bool ibis::compRange::inRange() const {
00876 volatile bool res = false;
00877 volatile double tm1 =
00878 static_cast<const ibis::compRange::term*>(getLeft())->eval();
00879 volatile double tm2 =
00880 static_cast<const ibis::compRange::term*>(getRight())->eval();
00881 switch (op12) {
00882 case OP_LT: res = (tm1 < tm2); break;
00883 case OP_LE: res = (tm1 <= tm2); break;
00884 case OP_GT: res = (tm1 > tm2); break;
00885 case OP_GE: res = (tm1 >= tm2); break;
00886 case OP_EQ: res = (tm1 == tm2); break;
00887 default: break;
00888 }
00889 if (expr3) {
00890 tm1 = expr3->eval();
00891 switch (op23) {
00892 case OP_LT: res = res && (tm2 < tm1); break;
00893 case OP_LE: res = res && (tm2 <= tm1); break;
00894 case OP_GT: res = res && (tm2 > tm1); break;
00895 case OP_GE: res = res && (tm2 >= tm1); break;
00896 case OP_EQ: res = res && (tm2 == tm1); break;
00897 default: break;
00898 }
00899 }
00900 return res;
00901 }
00902
00904 inline bool ibis::qContinuousRange::operator<
00905 (const ibis::qContinuousRange& y) const {
00906 int cmp = strcmp(colName(), y.colName());
00907 if (cmp < 0)
00908 return true;
00909 else if (cmp > 0)
00910 return false;
00911 else if (left_op < y.left_op)
00912 return true;
00913 else if (left_op > y.left_op)
00914 return false;
00915 else if (right_op < y.right_op)
00916 return true;
00917 else if (right_op > y.right_op)
00918 return false;
00919 else if (lower < y.lower)
00920 return true;
00921 else if (lower > y.lower)
00922 return false;
00923 else if (upper < y.upper)
00924 return true;
00925 else
00926 return false;
00927 }
00928
00933 inline bool ibis::qDiscreteRange::inRange(double val) const {
00934 if (values.empty()) return false;
00935 if (val < values[0] || val > values.back()) return false;
00936
00937 uint32_t i = 0, j = values.size();
00938 if (j < 32) {
00939
00940
00941 for (i = 0; i < j; ++ i)
00942 if (values[i] == val) return true;
00943 }
00944 else {
00945 uint32_t m = (i + j) / 2;
00946 while (i < m) {
00947 if (values[m] == val) return true;
00948 if (values[m] < val)
00949 i = m;
00950 else
00951 j = m;
00952 m = (i + j) / 2;
00953 }
00954
00955
00956 }
00957 return false;
00958 }
00959
00962 inline uint32_t ibis::compRange::barrel::recordVariable(