Main Page | Class Hierarchy | Class List | File List | Class 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 BEGIN_GIGABASE_NAMESPACE
00015 
00016 #include "selection.h"
00017 #include "btree.h"
00018 #include "rtree.h"
00019 
00020 enum dbCursorType {
00021     dbCursorViewOnly,
00022     dbCursorForUpdate
00023 };
00024 
00028 class dbTableIterator : public dbAbstractIterator {
00029     dbAnyCursor* cursor;
00030     dbExprNode*  filter;
00031     oid_t        curr;
00032 
00033   public:
00034     void init(dbAnyCursor* cursor, dbExprNode*  filter) {
00035         this->cursor = cursor;
00036         this->filter = filter;
00037         curr = 0;
00038     }
00039 
00040     virtual oid_t next();
00041     virtual oid_t prev();
00042     virtual oid_t first();
00043     virtual oid_t last();
00044 };
00045 
00046 
00047 
00051 class GIGABASE_DLL_ENTRY dbAnyCursor : public dbL2List {
00052     friend class dbDatabase;
00053     friend class dbHashTable;
00054     friend class dbRtreePage;
00055     friend class dbBtreePage;
00056     friend class dbRtreeIterator;
00057     friend class dbBtreeIterator;
00058     friend class dbTableIterator;
00059     friend class dbThickBtreePage;
00060     friend class dbSubSql;
00061     friend class dbStatement;
00062     friend class dbServer;
00063     friend class dbAnyContainer;
00064     friend class dbCLI;
00065     friend class JniResultSet;
00066   public:
00071     int getNumberOfRecords() const { return (int)selection.nRows; }
00072 
00076     void remove();
00077 
00082     bool isEmpty() const { 
00083         return currId == 0; 
00084     }
00085 
00090     bool isUpdateCursor() const { 
00091         return type == dbCursorForUpdate;
00092     }
00093 
00098     bool isLimitReached() const { 
00099         return selection.nRows >= limit || selection.nRows >= stmtLimitLen; 
00100     }
00101 
00112     int select(dbQuery& query, dbCursorType aType, void* paramStruct = NULL) {
00113         paramBase = paramStruct;
00114         type = aType;
00115         reset();
00116         db->select(this, query);
00117         paramBase = NULL;
00118         if (gotoFirst() && prefetch) {
00119             fetch();
00120         }
00121         return (int)selection.nRows;
00122     }
00123 
00131     oid_t* toArrayOfOid(oid_t* arr) const;
00132 
00139     int select(dbQuery& query, void* paramStruct = NULL) {
00140         return select(query, defaultType, paramStruct);
00141     }
00142 
00150     int select(char_t const* condition, dbCursorType aType, void* paramStruct = NULL) {
00151         dbQuery query(condition);
00152         return select(query, aType, paramStruct);
00153     }
00154 
00161     int select(char_t const* condition, void* paramStruct = NULL) {
00162         return select(condition, defaultType, paramStruct);
00163     }
00164 
00170     int select(dbCursorType aType) {
00171         type = aType;
00172         reset();
00173         db->select(this);
00174         if (gotoFirst() && prefetch) {
00175             fetch();
00176         }
00177         return (int)selection.nRows;
00178     }
00179 
00184     int select() {
00185         return select(defaultType);
00186     }
00187 
00194     int selectByKey(char_t const* key, void const* value);
00195 
00204     int selectByKeyRange(char_t const* key, void const* minValue, void const* maxValue, bool ascent = true);
00205 
00210     void update() {
00211         assert(type == dbCursorForUpdate && currId != 0);
00212         db->update(currId, table, record);
00213     }
00214 
00218     void removeAll() {
00219         assert(db != NULL);
00220         reset();
00221         db->deleteTable(table);
00222     }
00223 
00227     void removeAllSelected();
00228 
00232     void setSelectionLimit(size_t lim) { limit = lim; }
00233 
00237     void unsetSelectionLimit() { limit = dbDefaultSelectionLimit; }
00238 
00245     void setPrefetchMode(bool mode) { prefetch = mode; }
00246 
00255     bool setIncrementalHint(bool inc) { 
00256         bool prev = inc;
00257         assert(!inc || type != dbCursorForUpdate);
00258         incremental = inc;
00259         return prev;
00260     }
00261 
00271     bool isIncremental() { 
00272         return iterator != NULL;
00273     }
00274 
00278     void reset();
00279 
00284     bool isLast() const; 
00285 
00290     bool isFirst() const; 
00291 
00297     void freeze();
00298 
00302     void unfreeze();
00303 
00311     bool skip(int n);
00312 
00318     int seek(oid_t oid);
00319 
00324     dbTableDescriptor* getTable() { return table; }
00325 
00326 
00331     bool isInSelection(oid_t oid);
00332 
00337     void fetch() {
00338         table->columns->fetchRecordFields(record,
00339                                           (byte*)db->getRow(tie, currId));
00340     }
00341 
00345     bool hasNext() const;
00346 
00350     bool hasCurrent() const { 
00351         return currId != 0;
00352     }
00353 
00354 
00355   protected:
00356     dbDatabase*        db;
00357     dbTableDescriptor* table;
00358     dbCursorType       type;
00359     dbCursorType       defaultType;
00360     dbSelection        selection;
00361     bool               allRecords;
00362     oid_t              firstId;
00363     oid_t              lastId;
00364     oid_t              currId;
00365     byte*              record;
00366     size_t             limit;
00367     dbGetTie           tie;
00368     void*              paramBase;
00369 
00370     int4*              bitmap; // bitmap to avoid duplicates
00371     size_t             bitmapSize;
00372     bool               eliminateDuplicates;
00373     bool               prefetch;
00374     bool               removed; // current record was removed
00375     bool               incremental;
00376 
00377     size_t             stmtLimitStart;
00378     size_t             stmtLimitLen;
00379     size_t             nSkipped;
00380 
00381     dbAbstractIterator*iterator;
00382     dbBtreeIterator    btreeIterator;
00383     dbRtreeIterator    rtreeIterator;
00384     dbTableIterator    tableIterator;
00385 
00386     void allocateBitmap();
00387 
00388     void checkForDuplicates() { 
00389         if (!eliminateDuplicates && limit > 1) {
00390             allocateBitmap();
00391         }
00392     }
00393 
00394     bool isMarked(oid_t oid) {
00395         return bitmap != NULL && (bitmap[oid >> 5] & (1 << (oid & 31))) != 0;
00396     }
00397 
00398     void mark(oid_t oid) {
00399         if (bitmap != NULL) {
00400             bitmap[oid >> 5] |= 1 << (oid & 31);
00401         }
00402     }
00403 
00404     void setStatementLimit(dbQuery const& q) { 
00405         stmtLimitStart = q.stmtLimitStartPtr != NULL ? (nat4)*q.stmtLimitStartPtr : q.stmtLimitStart;
00406         stmtLimitLen = q.stmtLimitLenPtr != NULL ? (nat4)*q.stmtLimitLenPtr : q.stmtLimitLen;
00407     }
00408 
00409     void truncateSelection() { 
00410         selection.truncate(stmtLimitStart, stmtLimitLen);
00411     }
00412 
00413     bool add(oid_t oid) {
00414         if (selection.nRows < limit && selection.nRows < stmtLimitLen) {
00415             if (nSkipped < stmtLimitStart) { 
00416                 nSkipped += 1;
00417                 return true;
00418             }
00419             if (eliminateDuplicates) {
00420                 if (bitmap[oid >> 5] & (1 << (oid & 31))) {
00421                     return true;
00422                 }
00423                 bitmap[oid >> 5] |= 1 << (oid & 31);
00424             }
00425             selection.add(oid);
00426             return selection.nRows < limit;
00427         }
00428         return false;
00429     }
00430 
00431     bool gotoNext();
00432     bool gotoPrev();
00433     bool gotoFirst();
00434     bool gotoLast();
00435 
00436     void setCurrent(dbAnyReference const& ref);
00437 
00438     void setTable(dbTableDescriptor* aTable) { 
00439         table = aTable;
00440         db = aTable->db;
00441     }
00442 
00443     void setRecord(void* rec) { 
00444         record = (byte*)rec;
00445     }
00446 
00447     dbAnyCursor(dbTableDescriptor& aTable, dbCursorType aType, byte* rec);
00448 
00449   public:
00450     dbAnyCursor();
00451     ~dbAnyCursor();
00452 };
00453 
00457 template<class T>
00458 class dbCursor : public dbAnyCursor {
00459   protected:
00460     T record;
00461 
00462   public:
00467     dbCursor(dbCursorType type = dbCursorViewOnly)
00468         : dbAnyCursor(T::dbDescriptor, type, (byte*)&record) {}
00469 
00476     dbCursor(dbDatabase* aDb, dbCursorType type = dbCursorViewOnly)
00477         : dbAnyCursor(T::dbDescriptor, type, (byte*)&record) 
00478     {
00479         db = aDb;
00480         dbTableDescriptor* theTable = db->lookupTable(table);
00481         if (theTable != NULL) { 
00482             table = theTable;
00483         }
00484     }
00485 
00490     T* get() {
00491         return currId == 0 ? (T*)NULL : &record;
00492     }
00493 
00498     T* next() {
00499         if (gotoNext()) {
00500             fetch();
00501             return &record;
00502         }
00503         return NULL;
00504     }
00505 
00510     T* prev() {
00511         if (gotoPrev()) {
00512             fetch();
00513             return &record;
00514         }
00515         return NULL;
00516     }
00517 
00522     T* first() {
00523         if (gotoFirst()) {
00524             fetch();
00525             return &record;
00526         }
00527         return NULL;
00528     }
00529 
00534     T* last() {
00535         if (gotoLast()) {
00536             fetch();
00537             return &record;
00538         }
00539         return NULL;
00540     }
00541     
00547     int seek(dbReference<T> const& ref) { 
00548         return dbAnyCursor::seek(ref.getOid());
00549     }
00550 
00555     T* operator ->() {
00556         assert(currId != 0);
00557         return &record;
00558     }
00559 
00565     T* at(dbReference<T> const& ref) {
00566         setCurrent(ref);
00567         return &record;
00568     }
00569 
00574     dbReference<T> currentId() const {
00575         return dbReference<T>(currId);
00576     }
00577     
00582     void toArray(dbArray< dbReference<T> >& arr) const { 
00583         arr.resize(selection.nRows);
00584         toArrayOfOid((oid_t*)arr.base());
00585     }
00586 
00603     T* nextAvailable() { 
00604         if (!removed) { 
00605             return next(); 
00606         } else { 
00607             removed = false;
00608             return get();
00609         }
00610     }
00611 
00616     bool isInSelection(dbReference<T>& ref) {
00617         return dbAnyCursor::isInSelection(ref.getOid());
00618     }
00619 };
00620 
00621 class dbParallelQueryContext {
00622   public:
00623     dbDatabase* const      db;
00624     dbCompiledQuery* const query;
00625     dbAnyCursor*           cursor;
00626     oid_t                  firstRow;
00627     dbTableDescriptor*     table;
00628     dbSelection            selection[dbMaxParallelSearchThreads];
00629 
00630     void search(int i);
00631 
00632     dbParallelQueryContext(dbDatabase* aDb, dbTableDescriptor* desc,
00633                            dbCompiledQuery* aQuery, dbAnyCursor* aCursor)
00634       : db(aDb), query(aQuery), cursor(aCursor), firstRow(desc->firstRow), table(desc) {}
00635 };
00636 
00637 END_GIGABASE_NAMESPACE
00638 
00639 #endif

Generated on Thu Nov 24 23:14:29 2005 for GigaBASE by doxygen 1.3.5