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
00024 };
00025 
00029 class dbTableIterator : public dbAbstractIterator {
00030     dbAnyCursor* cursor;
00031     dbExprNode*  filter;
00032     oid_t        curr;
00033 
00034   public:
00035     void init(dbAnyCursor* cursor, dbExprNode*  filter) {
00036         this->cursor = cursor;
00037         this->filter = filter;
00038         curr = 0;
00039     }
00040 
00041     virtual oid_t next();
00042     virtual oid_t prev();
00043     virtual oid_t first();
00044     virtual oid_t last();
00045 };
00046 
00047 
00048 
00052 class GIGABASE_DLL_ENTRY dbAnyCursor : public dbL2List {
00053     friend class dbDatabase;
00054     friend class dbHashTable;
00055     friend class dbRtreePage;
00056     friend class dbBtreePage;
00057     friend class dbRtreeIterator;
00058     friend class dbBtreeIterator;
00059     friend class dbTableIterator;
00060     friend class dbThickBtreePage;
00061     friend class dbSubSql;
00062     friend class dbStatement;
00063     friend class dbServer;
00064     friend class dbAnyContainer;
00065     friend class dbCLI;
00066     friend class JniResultSet;
00067   public:
00072     int getNumberOfRecords() const { return (int)selection.nRows; }
00073 
00077     void remove();
00078 
00083     bool isEmpty() const { 
00084         return currId == 0; 
00085     }
00086 
00091     bool isUpdateCursor() const { 
00092         return type == dbCursorForUpdate;
00093     }
00094 
00099     bool isLimitReached() const { 
00100         return selection.nRows >= limit || selection.nRows >= stmtLimitLen; 
00101     }
00102 
00113     int select(dbQuery& query, dbCursorType aType, void* paramStruct = NULL) {
00114         paramBase = paramStruct;
00115         type = aType;
00116         reset();
00117         db->select(this, query);
00118         paramBase = NULL;
00119         if (gotoFirst() && prefetch) {
00120             fetch();
00121         }
00122         return (int)selection.nRows;
00123     }
00124 
00132     oid_t* toArrayOfOid(oid_t* arr) const;
00133 
00140     int select(dbQuery& query, void* paramStruct = NULL) {
00141         return select(query, defaultType, paramStruct);
00142     }
00143 
00151     int select(char_t const* condition, dbCursorType aType, void* paramStruct = NULL) {
00152         dbQuery query(condition);
00153         return select(query, aType, paramStruct);
00154     }
00155 
00162     int select(char_t const* condition, void* paramStruct = NULL) {
00163         return select(condition, defaultType, paramStruct);
00164     }
00165 
00171     int select(dbCursorType aType) {
00172         type = aType;
00173         reset();
00174         db->select(this);
00175         if (gotoFirst() && prefetch) {
00176             fetch();
00177         }
00178         return (int)selection.nRows;
00179     }
00180 
00185     int select() {
00186         return select(defaultType);
00187     }
00188 
00195     int selectByKey(char_t const* key, void const* value);
00196 
00205     int selectByKeyRange(char_t const* key, void const* minValue, void const* maxValue, bool ascent = true);
00206 
00211     void update() {
00212         assert(type == dbCursorForUpdate && currId != 0);
00213         db->update(currId, table, record);
00214     }
00215 
00219     void removeAll() {
00220         assert(db != NULL);
00221         reset();
00222         db->deleteTable(table);
00223     }
00224 
00228     void removeAllSelected();
00229 
00233     void setSelectionLimit(size_t lim) { limit = lim; }
00234 
00238     void unsetSelectionLimit() { limit = dbDefaultSelectionLimit; }
00239 
00246     void setPrefetchMode(bool mode) { prefetch = mode; }
00247 
00256     bool setIncrementalHint(bool inc) { 
00257         bool prev = incremental;
00258         assert(!inc || type != dbCursorForUpdate);
00259         incremental = inc;
00260         return prev;
00261     }
00262 
00272     bool isIncremental() { 
00273         return iterator != NULL;
00274     }
00275 
00279     void reset();
00280 
00285     bool isLast() const; 
00286 
00291     bool isFirst() const; 
00292 
00298     void freeze();
00299 
00303     void unfreeze();
00304 
00312     bool skip(int n);
00313 
00319     int seek(oid_t oid);
00320 
00325     dbTableDescriptor* getTable() { return table; }
00326 
00327 
00332     bool isInSelection(oid_t oid);
00333 
00338     void fetch() {
00339         table->columns->fetchRecordFields(record,
00340                                           (byte*)db->getRow(tie, currId));
00341     }
00342 
00346     bool hasNext() const;
00347 
00351     bool hasCurrent() const { 
00352         return currId != 0;
00353     }
00354 
00355 
00356   protected:
00357     dbDatabase*        db;
00358     dbTableDescriptor* table;
00359     dbCursorType       type;
00360     dbCursorType       defaultType;
00361     dbSelection        selection;
00362     bool               allRecords;
00363     oid_t              firstId;
00364     oid_t              lastId;
00365     oid_t              currId;
00366     byte*              record;
00367     size_t             limit;
00368     dbGetTie           tie;
00369     void*              paramBase;
00370 
00371     int4*              bitmap; // bitmap to avoid duplicates
00372     size_t             bitmapSize;
00373     bool               eliminateDuplicates;
00374     bool               prefetch;
00375     bool               removed; // current record was removed
00376     bool               lastRecordWasDeleted; //last record was deleted
00377     bool               incremental;
00378 
00379     size_t             stmtLimitStart;
00380     size_t             stmtLimitLen;
00381     size_t             nSkipped;
00382 
00383     dbAbstractIterator*iterator;
00384     dbBtreeIterator    btreeIterator;
00385     dbRtreeIterator    rtreeIterator;
00386     dbTableIterator    tableIterator;
00387 
00388     void allocateBitmap();
00389     void deallocateBitmap();
00390 
00391     void checkForDuplicates() { 
00392         if (!eliminateDuplicates && limit > 1) {
00393             allocateBitmap();
00394         }
00395     }
00396 
00397     bool isMarked(oid_t oid) {
00398         return bitmap != NULL && (bitmap[(size_t)(oid >> 5)] & (1 << ((int)oid & 31))) != 0;
00399     }
00400 
00401     void mark(oid_t oid) {
00402         if (bitmap != NULL) {
00403             bitmap[(size_t)(oid >> 5)] |= 1 << ((int)oid & 31);
00404         }
00405     }
00406 
00407     void setStatementLimit(dbQuery const& q) { 
00408         stmtLimitStart = q.stmtLimitStartPtr != NULL ? (nat4)*q.stmtLimitStartPtr : q.stmtLimitStart;
00409         stmtLimitLen = q.stmtLimitLenPtr != NULL ? (nat4)*q.stmtLimitLenPtr : q.stmtLimitLen;
00410     }
00411 
00412     void truncateSelection() { 
00413         selection.truncate(stmtLimitStart, stmtLimitLen);
00414     }
00415 
00416     bool add(oid_t oid) {
00417         if (selection.nRows < limit && selection.nRows < stmtLimitLen) {
00418             if (nSkipped < stmtLimitStart) { 
00419                 nSkipped += 1;
00420                 return true;
00421             }
00422             if (eliminateDuplicates) {
00423                 if (bitmap[(size_t)(oid >> 5)] & (1 << ((int)oid & 31))) {
00424                     return true;
00425                 }
00426                 bitmap[oid >> 5] |= 1 << (oid & 31);
00427             }
00428             selection.add(oid);
00429             return selection.nRows < limit;
00430         }
00431         return false;
00432     }
00433 
00434     bool gotoNext();
00435     bool gotoPrev();
00436     bool gotoFirst();
00437     bool gotoLast();
00438 
00439     bool moveNext();
00440     bool movePrev();
00441 
00442     void setCurrent(dbAnyReference const& ref);
00443 
00444     void setTable(dbTableDescriptor* aTable) { 
00445         table = aTable;
00446         db = aTable->db;
00447     }
00448 
00449     void setRecord(void* rec) { 
00450         record = (byte*)rec;
00451     }
00452 
00453     dbAnyCursor(dbTableDescriptor& aTable, dbCursorType aType, byte* rec);
00454 
00455   public:
00456     dbAnyCursor();
00457     ~dbAnyCursor();
00458 };
00459 
00463 template<class T>
00464 class dbCursor : public dbAnyCursor {
00465   private:
00466     // Itis not possible to copy cursors
00467     dbCursor<T> operator = (dbCursor<T> const& src) { 
00468         return *this;
00469     } 
00470 
00471   protected:
00472     T record;
00473 
00474   public:
00479     dbCursor(dbCursorType type = dbCursorViewOnly)
00480         : dbAnyCursor(T::dbDescriptor, type, (byte*)&record) {}
00481 
00488     dbCursor(dbDatabase* aDb, dbCursorType type = dbCursorViewOnly)
00489         : dbAnyCursor(T::dbDescriptor, type, (byte*)&record) 
00490     {
00491         db = aDb;
00492         dbTableDescriptor* theTable = db->lookupTable(table);
00493         if (theTable != NULL) { 
00494             table = theTable;
00495         }
00496     }
00497 
00502     T* get() {
00503         return currId == 0 ? (T*)NULL : &record;
00504     }
00505 
00510     T* next() {
00511         if (gotoNext()) {
00512             fetch();
00513             return &record;
00514         }
00515         return NULL;
00516     }
00517 
00522     T* prev() {
00523         if (gotoPrev()) {
00524             fetch();
00525             return &record;
00526         }
00527         return NULL;
00528     }
00529 
00534     T* first() {
00535         if (gotoFirst()) {
00536             fetch();
00537             return &record;
00538         }
00539         return NULL;
00540     }
00541 
00546     T* last() {
00547         if (gotoLast()) {
00548             fetch();
00549             return &record;
00550         }
00551         return NULL;
00552     }
00553     
00559     int seek(dbReference<T> const& ref) { 
00560         return dbAnyCursor::seek(ref.getOid());
00561     }
00562 
00567     T* operator ->() {
00568         assert(currId != 0);
00569         return &record;
00570     }
00571 
00577     T* at(dbReference<T> const& ref) {
00578         setCurrent(ref);
00579         return &record;
00580     }
00581 
00586     dbReference<T> currentId() const {
00587         return dbReference<T>(currId);
00588     }
00589     
00594     void toArray(dbArray< dbReference<T> >& arr) const { 
00595         arr.resize(selection.nRows);
00596         toArrayOfOid((oid_t*)arr.base());
00597     }
00598 
00615     T* nextAvailable() { 
00616         if (!removed) { 
00617             return next(); 
00618         } else {
00619             removed = false;
00620             return lastRecordWasDeleted ? NULL : get();
00621         }
00622     }
00623 
00641     T* prevAvailable() { 
00642         if (!removed) { 
00643             return prev(); 
00644         } else {
00645             removed = false;
00646             return lastRecordWasDeleted ? get() : prev();
00647         }
00648     }
00649 
00654     bool isInSelection(dbReference<T>& ref) {
00655         return dbAnyCursor::isInSelection(ref.getOid());
00656     }
00657 };
00658 
00659 class dbParallelQueryContext {
00660   public:
00661     dbDatabase* const      db;
00662     dbCompiledQuery* const query;
00663     dbAnyCursor*           cursor;
00664     oid_t                  firstRow;
00665     dbTableDescriptor*     table;
00666     dbSelection            selection[dbMaxParallelSearchThreads];
00667 
00668     void search(int i);
00669 
00670     dbParallelQueryContext(dbDatabase* aDb, dbTableDescriptor* desc,
00671                            dbCompiledQuery* aQuery, dbAnyCursor* aCursor)
00672       : db(aDb), query(aQuery), cursor(aCursor), firstRow(desc->firstRow), table(desc) {}
00673 };
00674 
00675 END_GIGABASE_NAMESPACE
00676 
00677 #endif

Generated on Mon Oct 23 13:22:59 2006 for GigaBASE by doxygen1.2.18