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 
00214     void update() {
00215         assert(type == dbCursorForUpdate && currId != 0);
00216         db->update(currId, table, record);
00217     }
00218 
00222     void removeAll() {
00223         assert(db != NULL);
00224         reset();
00225         db->deleteTable(table);
00226     }
00227 
00231     void removeAllSelected();
00232 
00236     void setSelectionLimit(size_t lim) { limit = lim; }
00237 
00241     void unsetSelectionLimit() { limit = dbDefaultSelectionLimit; }
00242 
00249     void setPrefetchMode(bool mode) { prefetch = mode; }
00250 
00261     bool isIncremental() { 
00262         return iterator != NULL;
00263     }
00264 
00269     bool hasIncrementalHint() { 
00270         return type == dbCursorIncremental;
00271     }
00272 
00277     void enableCheckForDuplicates(bool enabled) {
00278         checkForDuplicatedIsEnabled = enabled;
00279     }
00280  
00284     void reset();
00285 
00290     bool isLast() const; 
00291 
00296     bool isFirst() const; 
00297 
00303     void freeze();
00304 
00308     void unfreeze();
00309 
00317     bool skip(int n);
00318 
00324     int seek(oid_t oid);
00325 
00330     dbTableDescriptor* getTable() { return table; }
00331 
00332 
00337     bool isInSelection(oid_t oid);
00338 
00343     void fetch() {
00344         dbRecord* row = (type == dbCursorDetached) ? db->fetchRow(tie, currId) : db->getRow(tie, currId);
00345         table->columns->fetchRecordFields(record, (byte*)row);
00346     }
00347 
00351     bool hasNext() const;
00352 
00356     bool hasCurrent() const { 
00357         return currId != 0;
00358     }
00359 
00360 
00361   protected:
00362     dbDatabase*        db;
00363     dbTableDescriptor* table;
00364     dbCursorType       type;
00365     dbCursorType       defaultType;
00366     dbSelection        selection;
00367     bool               allRecords;
00368     oid_t              firstId;
00369     oid_t              lastId;
00370     oid_t              currId;
00371     byte*              record;
00372     size_t             limit;
00373     dbGetTie           tie;
00374     void*              paramBase;
00375 
00376     int4*              bitmap; // bitmap to avoid duplicates
00377     size_t             bitmapSize;
00378     bool               eliminateDuplicates;
00379     bool               checkForDuplicatedIsEnabled;
00380     bool               prefetch;
00381     bool               removed; // current record was removed
00382     bool               lastRecordWasDeleted; //last record was deleted
00383 
00384     size_t             stmtLimitStart;
00385     size_t             stmtLimitLen;
00386     size_t             nSkipped;
00387 
00388     dbAbstractIterator*iterator;
00389     dbBtreeIterator    btreeIterator;
00390     dbRtreeIterator    rtreeIterator;
00391     dbTableIterator    tableIterator;
00392 
00393     void allocateBitmap();
00394     void deallocateBitmap();
00395 
00396     void checkForDuplicates() { 
00397         if (!eliminateDuplicates && checkForDuplicatedIsEnabled && limit > 1) {
00398             allocateBitmap();
00399         }
00400     }
00401 
00402     bool isMarked(oid_t oid) {
00403         return bitmap != NULL && (bitmap[(size_t)(oid >> 5)] & (1 << ((int)oid & 31))) != 0;
00404     }
00405 
00406     void mark(oid_t oid) {
00407         if (bitmap != NULL) {
00408             bitmap[(size_t)(oid >> 5)] |= 1 << ((int)oid & 31);
00409         }
00410     }
00411 
00412     void setStatementLimit(dbQuery const& q) { 
00413         stmtLimitStart = q.stmtLimitStartPtr != NULL ? (nat4)*q.stmtLimitStartPtr : q.stmtLimitStart;
00414         stmtLimitLen = q.stmtLimitLenPtr != NULL ? (nat4)*q.stmtLimitLenPtr : q.stmtLimitLen;
00415     }
00416 
00417     void truncateSelection() { 
00418         selection.truncate(stmtLimitStart, stmtLimitLen);
00419     }
00420 
00421     bool add(oid_t oid) {
00422         if (selection.nRows < limit && selection.nRows < stmtLimitLen) {
00423             if (nSkipped < stmtLimitStart) { 
00424                 nSkipped += 1;
00425                 return true;
00426             }
00427             if (eliminateDuplicates) {
00428                 if (bitmap[(size_t)(oid >> 5)] & (1 << ((int)oid & 31))) {
00429                     return true;
00430                 }
00431                 bitmap[oid >> 5] |= 1 << (oid & 31);
00432             }
00433             selection.add(oid);
00434             return selection.nRows < limit;
00435         }
00436         return false;
00437     }
00438     
00439     byte* fetchNext();
00440     byte* fetchPrev();
00441     byte* fetchFirst();
00442     byte* fetchLast();
00443 
00444     bool gotoNext();
00445     bool gotoPrev();
00446     bool gotoFirst();
00447     bool gotoLast();
00448 
00449     bool moveNext();
00450     bool movePrev();
00451 
00452     void setCurrent(dbAnyReference const& ref);
00453 
00454     void setTable(dbTableDescriptor* aTable) { 
00455         table = aTable;
00456         db = aTable->db;
00457     }
00458 
00459     void setRecord(void* rec) { 
00460         record = (byte*)rec;
00461     }
00462 
00463     dbAnyCursor(dbTableDescriptor& aTable, dbCursorType aType, byte* rec);
00464 
00465   public:
00466     dbAnyCursor();
00467     ~dbAnyCursor();
00468 };
00469 
00473 template<class T>
00474 class dbCursor : public dbAnyCursor {
00475   private:
00476     // Itis not possible to copy cursors
00477     dbCursor<T> operator = (dbCursor<T> const& src) { 
00478         return *this;
00479     } 
00480 
00481   protected:
00482     T record;
00483 
00484   public:
00489     dbCursor(dbCursorType type = dbCursorViewOnly)
00490         : dbAnyCursor(T::dbDescriptor, type, (byte*)&record) {}
00491 
00498     dbCursor(dbDatabase* aDb, dbCursorType type = dbCursorViewOnly)
00499         : dbAnyCursor(T::dbDescriptor, type, (byte*)&record) 
00500     {
00501         db = aDb;
00502         dbTableDescriptor* theTable = db->lookupTable(table);
00503         if (theTable != NULL) { 
00504             table = theTable;
00505         }
00506     }
00507 
00512     T* get() {
00513         return currId == 0 ? (T*)NULL : &record;
00514     }
00515 
00520     T* next() {
00521         return (T*)fetchNext();
00522     }
00523 
00528     T* prev() {
00529         return (T*)fetchPrev();
00530     }
00531 
00536     T* first() {
00537         return (T*)fetchFirst();
00538     }
00539 
00544     T* last() {
00545         return (T*)fetchLast();
00546     }
00547     
00553     int seek(dbReference<T> const& ref) { 
00554         return dbAnyCursor::seek(ref.getOid());
00555     }
00556 
00561     T* operator ->() {
00562         assert(currId != 0);
00563         return &record;
00564     }
00565 
00571     T* at(dbReference<T> const& ref) {
00572         setCurrent(ref);
00573         return &record;
00574     }
00575 
00580     dbReference<T> currentId() const {
00581         return dbReference<T>(currId);
00582     }
00583     
00588     void toArray(dbArray< dbReference<T> >& arr) const { 
00589         arr.resize(selection.nRows);
00590         toArrayOfOid((oid_t*)arr.base());
00591     }
00592 
00593     T* prevAvailable() { 
00594         if (!removed) { 
00595             return prev(); 
00596         } else {
00597             removed = false;
00598             return lastRecordWasDeleted ? get() : prev();
00599         }
00600     }
00601 
00606     bool isInSelection(dbReference<T>& ref) {
00607         return dbAnyCursor::isInSelection(ref.getOid());
00608     }
00609 };
00610 
00611 class dbParallelQueryContext {
00612   public:
00613     dbDatabase* const      db;
00614     dbCompiledQuery* const query;
00615     dbAnyCursor*           cursor;
00616     oid_t                  firstRow;
00617     dbTableDescriptor*     table;
00618     dbSelection            selection[dbMaxParallelSearchThreads];
00619 
00620     void search(int i);
00621 
00622     dbParallelQueryContext(dbDatabase* aDb, dbTableDescriptor* desc,
00623                            dbCompiledQuery* aQuery, dbAnyCursor* aCursor)
00624       : db(aDb), query(aQuery), cursor(aCursor), firstRow(desc->firstRow), table(desc) {}
00625 };
00626 
00627 END_GIGABASE_NAMESPACE
00628 
00629 #endif

Generated on Thu Aug 23 19:35:52 2007 for GigaBASE by doxygen1.2.18