00001
00002
00003
00004
00005 #ifndef IBIS_QUERY_H
00006 #define IBIS_QUERY_H
00010 #include "part.h" // ibis::part
00011 #include "whereClause.h"
00012 #include "selectClause.h"
00013
00051 class FASTBIT_CXX_DLLSPEC ibis::query {
00052 public:
00053 enum QUERY_STATE {
00054 UNINITIALIZED,
00055 SET_COMPONENTS,
00056 SET_RIDS,
00057 SET_PREDICATE,
00058 SPECIFIED,
00059 QUICK_ESTIMATE,
00060 FULL_EVALUATE,
00061 BUNDLES_TRUNCATED,
00062 HITS_TRUNCATED
00063 };
00064
00065 virtual ~query();
00069 query(const char* dir, const ibis::partList& tl);
00071 query(const char* uid=0, const part* et=0, const char* pref=0);
00072
00074 const char* id() const {return myID;};
00075 const char* dir() const {return myDir;}
00076 const char* userName() const {return user;}
00077
00078 time_t timestamp() const {return dstime;}
00080 const part* partition() const {return mypart;}
00082 const selectClause& components() const {return comps;};
00083
00085 int setRIDs(const RIDSet& set);
00087 int setWhereClause(const char *str);
00089 int setWhereClause(const std::vector<const char*>& names,
00090 const std::vector<double>& lbounds,
00091 const std::vector<double>& rbounds);
00093 int setWhereClause(const ibis::qExpr* qexp);
00103 virtual int setSelectClause(const char *str);
00106 int setPartition(const ibis::part* tbl);
00108 int setTable(const ibis::part* tbl) {return setPartition(tbl);}
00110 virtual const char* getWhereClause() const {return conds.getString();}
00112 virtual const char* getSelectClause() const {return *comps;}
00113
00117 void expandQuery();
00121 void contractQuery();
00122
00124 const RIDSet* getUserRIDs() const {return rids_in;}
00125
00136 std::string removeComplexConditions();
00137
00138
00139
00146 int estimate();
00148 long getMinNumHits() const;
00150 long getMaxNumHits() const;
00151
00152
00153
00170 int evaluate(const bool evalSelect=false);
00173 const ibis::bitvector* getHitVector() const {return hits;}
00175 long getNumHits() const;
00178 long countHits() const;
00179
00180 int orderby(const char *names, int direction) const;
00181 long limit(const char *names, int direction, uint32_t keep,
00182 bool updateHits = true);
00183
00194 array_t<char>* getQualifiedBytes(const char* column_name);
00196 array_t<unsigned char>* getQualifiedUBytes(const char* column_name);
00198 array_t<int16_t>* getQualifiedShorts(const char* column_name);
00200 array_t<uint16_t>* getQualifiedUShorts(const char* column_name);
00202 array_t<int32_t>* getQualifiedInts(const char* column_name);
00205 array_t<uint32_t>* getQualifiedUInts(const char* column_name);
00207 array_t<int64_t>* getQualifiedLongs(const char* column_name);
00209 array_t<uint64_t>* getQualifiedULongs(const char* column_name);
00212 array_t<float>* getQualifiedFloats(const char* column_name);
00215 array_t<double>* getQualifiedDoubles(const char* column_name);
00217 std::vector<std::string>* getQualifiedStrings(const char* column_name);
00219 RIDSet* getRIDs() const;
00221 RIDSet* getRIDs(const ibis::bitvector& mask) const;
00223 const RIDSet* getRIDsInBundle(const uint32_t bid) const;
00225
00232 void printSelected(std::ostream& out) const;
00236 void printSelectedWithRID(std::ostream& out) const;
00237
00243 long sequentialScan(ibis::bitvector& bv) const;
00244
00248 long getExpandedHits(ibis::bitvector&) const;
00249
00250
00251 RIDSet* readRIDs() const;
00252 void writeRIDs(const RIDSet* rids) const;
00253
00256 void logMessage(const char* event, const char* fmt, ...) const;
00257
00258
00259
00260
00262 void clear();
00264 QUERY_STATE getState() const;
00266 const char* getLastError() const {return lastError;}
00268 void clearErrorMessage() const {*lastError=0;}
00269
00272 static bool isValidToken(const char* tok);
00274
00275
00276 static unsigned tokenLength() {return 16;}
00277
00279 static void removeQueryRecords()
00280 {ibis::gParameters().add("query.purgeTempFiles", "true");}
00282 static void keepQueryRecords()
00283 {ibis::gParameters().add("query.purgeTempFiles", "false");}
00284
00285 class result;
00286 class weight;
00287 class readLock;
00288 class writeLock;
00289 friend class readLock;
00290 friend class writeLock;
00291
00292 protected:
00293 char* user;
00294 whereClause conds;
00295 selectClause comps;
00296 QUERY_STATE state;
00297 ibis::bitvector* hits;
00298 ibis::bitvector* sup;
00299 mutable ibis::part::readLock* dslock;
00300 mutable char lastError[MAX_LINE+PATH_MAX];
00301
00302 void logError(const char* event, const char* fmt, ...) const;
00303 void logWarning(const char* event, const char* fmt, ...) const;
00304
00305 void reorderExpr();
00306
00307 bool hasBundles() const;
00308 int computeHits();
00309 void getBounds();
00310
00311 void doEstimate(const qExpr* term, ibis::bitvector& low,
00312 ibis::bitvector& high) const;
00314 int doScan(const qExpr* term, const ibis::bitvector& mask,
00315 ibis::bitvector& hits) const;
00317 int doScan(const qExpr* term, ibis::bitvector& hits) const;
00319 int doEvaluate(const qExpr* term, ibis::bitvector& hits) const;
00321 int doEvaluate(const qExpr* term, const ibis::bitvector& mask,
00322 ibis::bitvector& hits) const;
00323
00325 int64_t processJoin();
00326
00328 virtual void writeQuery();
00330 void readQuery(const ibis::partList& tl);
00332 void removeFiles();
00333
00335 void readHits();
00337 void writeHits() const;
00339 void printRIDs(const RIDSet& ridset) const;
00342 uint32_t countPages(unsigned wordsize) const;
00343
00345 int doExpand(ibis::qExpr* exp0) const;
00347 int doContract(ibis::qExpr* exp0) const;
00348
00349
00350
00351 int64_t sortJoin(const std::vector<const ibis::rangeJoin*>& terms,
00352 const ibis::bitvector& mask) const;
00353 int64_t sortJoin(const ibis::rangeJoin& cmp,
00354 const ibis::bitvector& mask) const;
00355 int64_t sortEquiJoin(const ibis::rangeJoin& cmp,
00356 const ibis::bitvector& mask) const;
00357 int64_t sortRangeJoin(const ibis::rangeJoin& cmp,
00358 const ibis::bitvector& mask) const;
00359 int64_t sortEquiJoin(const ibis::rangeJoin& cmp,
00360 const ibis::bitvector& mask,
00361 const char* pairfile) const;
00362 int64_t sortRangeJoin(const ibis::rangeJoin& cmp,
00363 const ibis::bitvector& mask,
00364 const char* pairfile) const;
00365 void orderPairs(const char* pairfile) const;
00366 int64_t mergePairs(const char* pairfile) const;
00367
00368 template <typename T1, typename T2>
00369 int64_t countEqualPairs(const array_t<T1>& val1,
00370 const array_t<T2>& val2) const;
00371 template <typename T1, typename T2>
00372 int64_t countDeltaPairs(const array_t<T1>& val1,
00373 const array_t<T2>& val2, const T1& delta) const;
00374 template <typename T1, typename T2>
00375 int64_t recordEqualPairs(const array_t<T1>& val1,
00376 const array_t<T2>& val2,
00377 const array_t<uint32_t>& ind1,
00378 const array_t<uint32_t>& ind2,
00379 const char* pairfile) const;
00380 template <typename T1, typename T2>
00381 int64_t recordDeltaPairs(const array_t<T1>& val1,
00382 const array_t<T2>& val2,
00383 const array_t<uint32_t>& ind1,
00384 const array_t<uint32_t>& ind2,
00385 const T1& delta, const char* pairfile) const;
00386
00387
00388 void gainReadAccess(const char* mesg) const {
00389 if (ibis::gVerbose > 10)
00390 logMessage("gainReadAccess", "acquiring a read lock for %s",
00391 mesg);
00392 if (0 != pthread_rwlock_rdlock(&lock))
00393 logMessage("gainReadAccess",
00394 "unable to gain read access to rwlock for %s", mesg);
00395 }
00396 void gainWriteAccess(const char* mesg) const {
00397 if (ibis::gVerbose > 10)
00398 logMessage("gainWriteAccess", "acquiring a write lock for %s",
00399 mesg);
00400 if (0 != pthread_rwlock_wrlock(&lock))
00401 logMessage("gainWriteAccess",
00402 "unable to gain write access to rwlock for %s", mesg);
00403 }
00404 void releaseAccess(const char* mesg) const {
00405 if (ibis::gVerbose > 10)
00406 logMessage("releaseAccess", "releasing rwlock for %s", mesg);
00407 if (0 != pthread_rwlock_unlock(&lock))
00408 logMessage("releaseAccess", "unable to unlock the rwlock for %s",
00409 mesg);
00410 }
00411
00412 private:
00413 char* myID;
00414 char* myDir;
00415 RIDSet* rids_in;
00416 const part* mypart;
00417 time_t dstime;
00418 mutable pthread_rwlock_t lock;
00419
00420
00421 static char* newToken(const char*);
00422
00423 void setMyDir(const char *pref);
00424
00425 query(const query&);
00426 query& operator=(const query&);
00427 };
00428
00429 namespace ibis {
00437 template <>
00438 int64_t query::countEqualPairs(const array_t<int32_t>& val1,
00439 const array_t<uint32_t>& val2) const;
00440 template <>
00441 int64_t query::countEqualPairs(const array_t<uint32_t>& val1,
00442 const array_t<int32_t>& val2) const;
00443 template <>
00444 int64_t query::countDeltaPairs(const array_t<int32_t>& val1,
00445 const array_t<uint32_t>& val2,
00446 const int32_t& delta) const;
00447 template <>
00448 int64_t query::countDeltaPairs(const array_t<uint32_t>& val1,
00449 const array_t<int32_t>& val2,
00450 const uint32_t& delta) const;
00451 template <>
00452 int64_t query::recordEqualPairs(const array_t<int32_t>& val1,
00453 const array_t<uint32_t>& val2,
00454 const array_t<uint32_t>& ind1,
00455 const array_t<uint32_t>& ind2,
00456 const char *pairfile) const;
00457 template <>
00458 int64_t query::recordEqualPairs(const array_t<uint32_t>& val1,
00459 const array_t<int32_t>& val2,
00460 const array_t<uint32_t>& ind1,
00461 const array_t<uint32_t>& ind2,
00462 const char *pairfile) const;
00463 template <>
00464 int64_t query::recordDeltaPairs(const array_t<int32_t>& val1,
00465 const array_t<uint32_t>& val2,
00466 const array_t<uint32_t>& ind1,
00467 const array_t<uint32_t>& ind2,
00468 const int32_t& delta,
00469 const char *pairfile) const;
00470 template <>
00471 int64_t query::recordDeltaPairs(const array_t<uint32_t>& val1,
00472 const array_t<int32_t>& val2,
00473 const array_t<uint32_t>& ind1,
00474 const array_t<uint32_t>& ind2,
00475 const uint32_t& delta,
00476 const char *pairfile) const;
00478 }
00479
00481 class ibis::query::weight : public ibis::qExpr::weight {
00482 public:
00483 virtual double operator()(const ibis::qExpr* ex) const;
00484 weight(const ibis::part* ds) : dataset(ds) {}
00485
00486 private:
00487 const ibis::part* dataset;
00488 };
00489
00494 class ibis::query::readLock {
00495 public:
00496 readLock(const query* q, const char* m) : theQuery(q), mesg(m) {
00497 theQuery->gainReadAccess(m);
00498 };
00499 ~readLock() {theQuery->releaseAccess(mesg);}
00500 private:
00501 const query* theQuery;
00502 const char* mesg;
00503
00504 readLock() {};
00505 readLock(const readLock&) {};
00506 };
00507
00512 class ibis::query::writeLock {
00513 public:
00514 writeLock(const query* q, const char* m) : theQuery(q), mesg(m) {
00515 theQuery->gainWriteAccess(m);
00516 };
00517 ~writeLock() {theQuery->releaseAccess(mesg);}
00518 private:
00519 const query* theQuery;
00520 const char* mesg;
00521
00522 writeLock() {};
00523 writeLock(const writeLock&) {};
00524 };
00525 #endif // IBIS_QUERY_H