Main Page   Class Hierarchy   Compound List   File List   Compound Members  

cursor.h

00001 //-< CURSOR.H >------------------------------------------------------*--------*
00002 // GigaBASE                  Version 1.0         (c) 1999  GARRET    *     ?  *
00003 // (Post Relational Database Management System)                      *   /\|  *
00004 //                                                                   *  /  \  *
00005 //                          Created:     20-Nov-98    K.A. Knizhnik  * / [] \ *
00006 //                          Last update: 10-Dec-98    K.A. Knizhnik  * GARRET *
00007 //-------------------------------------------------------------------*--------*
00008 // Table cursor
00009 //-------------------------------------------------------------------*--------*
00010 
00011 #ifndef __CURSOR_H__
00012 #define __CURSOR_H__
00013 
00014 #include "btree.h"
00015 #include "rtree.h"
00016 
00017 BEGIN_GIGABASE_NAMESPACE
00018 
00019 #include "selection.h"
00020 
00021 enum dbCursorType {
00022     dbCursorViewOnly,
00023     dbCursorForUpdate,
00027     dbCursorIncremental,
00036     dbCursorDetached
00037 };
00038 
00042 class dbTableIterator : public dbAbstractIterator {
00043     dbAnyCursor* cursor;
00044     dbExprNode*  filter;
00045     oid_t        curr;
00046 
00047   public:
00048     void init(dbAnyCursor* cursor, dbExprNode*  filter) {
00049         this->cursor = cursor;
00050         this->filter = filter;
00051         curr = 0;
00052     }
00053 
00054     virtual oid_t next();
00055     virtual oid_t prev();
00056     virtual oid_t first();
00057     virtual oid_t last();
00058 };
00059 
00060 
00061 
00065 class GIGABASE_DLL_ENTRY dbAnyCursor : public dbL2List {
00066     friend class dbDatabase;
00067     friend class dbHashTable;
00068     friend class dbRtreePage;
00069     friend class dbBtreePage;
00070     friend class dbRtreeIterator;
00071     friend class dbBtreeIterator;
00072     friend class dbTableIterator;
00073     friend class dbThickBtreePage;
00074     friend class dbSubSql;
00075     friend class dbStatement;
00076     friend class dbServer;
00077     friend class dbAnyContainer;
00078     friend class dbCLI;
00079     friend class JniResultSet;
00080   public:
00085     int getNumberOfRecords() const { return (int)selection.nRows; }
00086 
00090     void remove();
00091 
00096     bool isEmpty() const { 
00097         return currId == 0; 
00098     }
00099 
00104     bool isUpdateCursor() const { 
00105         return type == dbCursorForUpdate;
00106     }
00107 
00112     bool isLimitReached() const { 
00113         return selection.nRows >= limit || selection.nRows >= stmtLimitLen; 
00114     }
00115 
00126     int select(dbQuery& query, dbCursorType aType, void* paramStruct = NULL);
00127 
00135     oid_t* toArrayOfOid(oid_t* arr) const;
00136 
00143     int select(dbQuery& query, void* paramStruct = NULL) {
00144         return select(query, defaultType, paramStruct);
00145     }
00146 
00154     int select(char_t const* condition, dbCursorType aType, void* paramStruct = NULL) {
00155         dbQuery query(condition);
00156         return select(query, aType, paramStruct);
00157     }
00158 
00165     int select(char_t const* condition, void* paramStruct = NULL) {
00166         return select(condition, defaultType, paramStruct);
00167     }
00168 
00174     int select(dbCursorType aType) {
00175         type = aType;
00176         reset();
00177         db->select(this);
00178         if (gotoFirst() && prefetch) {
00179             fetch();
00180         }
00181         return (int)selection.nRows;
00182     }
00183 
00188     int select() {
00189         return select(defaultType);
00190     }
00191 
00198     int selectByKey(char_t const* key, void const* value);
00199 
00208     int selectByKeyRange(char_t const* key, void const* minValue, void const* maxValue, bool ascent = true);
00209 
00215     bool update() {
00216         assert(type == dbCursorForUpdate && currId != 0);
00217         return db->update(currId, table, record);
00218     }
00219 
00223     void removeAll() {
00224         assert(db != NULL);
00225         reset();
00226         db->deleteTable(table);
00227     }
00228 
00232     void removeAllSelected();
00233 
00237     void setSelectionLimit(size_t lim) { limit = lim; }
00238 
00242     void unsetSelectionLimit() { limit = dbDefaultSelectionLimit; }
00243 
00250     void setPrefetchMode(bool mode) { prefetch = mode; }
00251 
00262     bool isIncremental() { 
00263         return iterator != NULL;
00264     }
00265 
00270     bool hasIncrementalHint() { 
00271         return type == dbCursorIncremental;
00272     }
00273 
00278     void enableCheckForDuplicates(bool enabled) {
00279         checkForDuplicatedIsEnabled = enabled;
00280     }
00281  
00285     void reset();
00286 
00291     bool isLast() const; 
00292 
00297     bool isFirst() const; 
00298 
00304     void freeze();
00305 
00309     void unfreeze();
00310 
00318     bool skip(int n);
00319 
00325     int seek(oid_t oid);
00326 
00331     dbTableDescriptor* getTable() { return table; }
00332 
00333 
00338     bool isInSelection(oid_t oid);
00339 
00344     void fetch() {
00345         dbRecord* row = (type == dbCursorDetached) ? db->fetchRow(tie, currId) : db->getRow(tie, currId);
00346         table->columns->fetchRecordFields(record, (byte*)row);
00347     }
00348 
00352     bool hasNext() const;
00353 
00357     bool hasCurrent() const { 
00358         return currId != 0;
00359     }
00360 
00361 
00362   protected:
00363     dbDatabase*        db;
00364     dbTableDescriptor* table;
00365     dbCursorType       type;
00366     dbCursorType       defaultType;
00367     dbSelection        selection;
00368     bool               allRecords;
00369     oid_t              firstId;
00370     oid_t              lastId;
00371     oid_t              currId;
00372     byte*              record;
00373     size_t             limit;
00374     dbGetTie           tie;
00375     void*              paramBase;
00376 
00377     int4*              bitmap; // bitmap to avoid duplicates
00378     size_t             bitmapSize;
00379     bool               eliminateDuplicates;
00380     bool               checkForDuplicatedIsEnabled;
00381     bool               prefetch;
00382     bool               removed; // current record was removed
00383     bool               lastRecordWasDeleted; //last record was deleted
00384 
00385     size_t             stmtLimitStart;
00386     size_t             stmtLimitLen;
00387     size_t             nSkipped;
00388 
00389     dbAbstractIterator*iterator;
00390     dbBtreeIterator    btreeIterator;
00391     dbRtreeIterator    rtreeIterator;
00392     dbTableIterator    tableIterator;
00393 
00394     void allocateBitmap();
00395     void deallocateBitmap();
00396 
00397     void checkForDuplicates() { 
00398         if (!eliminateDuplicates && checkForDuplicatedIsEnabled && limit > 1) {
00399             allocateBitmap();
00400         }
00401     }
00402 
00403     bool isMarked(oid_t oid) {
00404         return bitmap != NULL && (bitmap[(size_t)(oid >> 5)] & (1 << ((int)oid & 31))) != 0;
00405     }
00406 
00407     void mark(oid_t oid) {
00408         if (bitmap != NULL) {
00409             bitmap[(size_t)(oid >> 5)] |= 1 << ((int)oid & 31);
00410         }
00411     }
00412 
00413     void setStatementLimit(dbQuery const& q) { 
00414         stmtLimitStart = q.stmtLimitStartPtr != NULL ? (nat4)*q.stmtLimitStartPtr : q.stmtLimitStart;
00415         stmtLimitLen = q.stmtLimitLenPtr != NULL ? (nat4)*q.stmtLimitLenPtr : q.stmtLimitLen;
00416     }
00417 
00418     void truncateSelection() { 
00419         selection.truncate(stmtLimitStart, stmtLimitLen);
00420     }
00421 
00422     bool add(oid_t oid) {
00423         if (selection.nRows < limit && selection.nRows < stmtLimitLen) {
00424             if (nSkipped < stmtLimitStart) { 
00425                 nSkipped += 1;
00426                 return true;
00427             }
00428             if (eliminateDuplicates) {
00429                 if (bitmap[(size_t)(oid >> 5)] & (1 << ((int)oid & 31))) {
00430                     return true;
00431                 }
00432                 bitmap[oid >> 5] |= 1 << (oid & 31);
00433             }
00434             selection.add(oid);
00435             return selection.nRows < limit;
00436         }
00437         return false;
00438     }
00439     
00440     byte* fetchNext();
00441     byte* fetchPrev();
00442     byte* fetchFirst();
00443     byte* fetchLast();
00444 
00445     bool gotoNext();
00446     bool gotoPrev();
00447     bool gotoFirst();
00448     bool gotoLast();
00449 
00450     bool moveNext();
00451     bool movePrev();
00452 
00453     void setCurrent(dbAnyReference const& ref);
00454 
00455     void setTable(dbTableDescriptor* aTable) { 
00456         table = aTable;
00457         db = aTable->db;
00458     }
00459 
00460     void setRecord(void* rec) { 
00461         record = (byte*)rec;
00462     }
00463 
00464     dbAnyCursor(dbTableDescriptor& aTable, dbCursorType aType, byte* rec);
00465 
00466   public:
00467     dbAnyCursor();
00468     ~dbAnyCursor();
00469 };
00470 
00474 template<class T>
00475 class dbCursor : public dbAnyCursor {
00476   private:
00477     // Itis not possible to copy cursors
00478     dbCursor<T> operator = (dbCursor<T> const& src) { 
00479         return *this;
00480     } 
00481 
00482   protected:
00483     T record;
00484 
00485   public:
00490     dbCursor(dbCursorType type = dbCursorViewOnly)
00491         : dbAnyCursor(T::dbDescriptor, type, (byte*)&record) {}
00492 
00499     dbCursor(dbDatabase* aDb, dbCursorType type = dbCursorViewOnly)
00500         : dbAnyCursor(T::dbDescriptor, type, (byte*)&record) 
00501     {
00502         db = aDb;
00503         dbTableDescriptor* theTable = db->lookupTable(table);
00504         if (theTable != NULL) { 
00505             table = theTable;
00506         }
00507     }
00508 
00513     T* get() {
00514         return currId == 0 ? (T*)NULL : &record;
00515     }
00516 
00521     T* next() {
00522         return (T*)fetchNext();
00523     }
00524 
00529     T* prev() {
00530         return (T*)fetchPrev();
00531     }
00532 
00537     T* first() {
00538         return (T*)fetchFirst();
00539     }
00540 
00545     T* last() {
00546         return (T*)fetchLast();
00547     }
00548     
00554     int seek(dbReference<T> const& ref) { 
00555         return dbAnyCursor::seek(ref.getOid());
00556     }
00557 
00562     T* operator ->() {
00563         assert(currId != 0);
00564         return &record;
00565     }
00566 
00572     T* at(dbReference<T> const& ref) {
00573         setCurrent(ref);
00574         return &record;
00575     }
00576 
00581     dbReference<T> currentId() const {
00582         return dbReference<T>(currId);
00583     }
00584     
00589     void toArray(dbArray< dbReference<T> >& arr) const { 
00590         arr.resize(selection.nRows);
00591         toArrayOfOid((oid_t*)arr.base());
00592     }
00593 
00594     T* prevAvailable() { 
00595         if (!removed) { 
00596             return prev(); 
00597         } else {
00598             removed = false;
00599             return lastRecordWasDeleted ? get() : prev();
00600         }
00601     }
00602 
00607     bool isInSelection(dbReference<T>& ref) {
00608         return dbAnyCursor::isInSelection(ref.getOid());
00609     }
00610 };
00611 
00612 class dbParallelQueryContext {
00613   public:
00614     dbDatabase* const      db;
00615     dbCompiledQuery* const query;
00616     dbAnyCursor*           cursor;
00617     oid_t                  firstRow;
00618     dbTableDescriptor*     table;
00619     dbSelection            selection[dbMaxParallelSearchThreads];
00620 
00621     void search(int i);
00622 
00623     dbParallelQueryContext(dbDatabase* aDb, dbTableDescriptor* desc,
00624                            dbCompiledQuery* aQuery, dbAnyCursor* aCursor)
00625       : db(aDb), query(aQuery), cursor(aCursor), firstRow(desc->firstRow), table(desc) {}
00626 };
00627 
00628 END_GIGABASE_NAMESPACE
00629 
00630 #endif

Generated on Thu Feb 14 21:46:03 2008 for GigaBASE by doxygen1.2.18