Main Page   Class Hierarchy   Compound List   File List   Compound Members  

cursor.h

00001 //-< CURSOR.H >------------------------------------------------------*--------*
00002 // FastDB                    Version 1.0         (c) 1999  GARRET    *     ?  *
00003 // (Main Memory 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_FASTDB_NAMESPACE
00015 
00016 class dbOrderByNode;
00017 
00018 class FASTDB_DLL_ENTRY dbSelection { 
00019   public:
00020     enum { quantum = 1024 };
00021     class segment { 
00022       public:
00023         segment* prev;
00024         segment* next;
00025         size_t   nRows;
00026         oid_t    rows[quantum];
00027 
00028         segment(segment* after) { 
00029             prev = after;
00030             next = NULL;
00031             nRows = 0;
00032         }       
00033     };
00034     segment*  first;
00035     segment*  last;
00036     segment*  curr;
00037     size_t    nRows;
00038     size_t    pos;
00039 
00040     segment*  createNewSegment(segment* after);
00041 
00042     void add(oid_t oid) {
00043         if (last == NULL) { 
00044             first = last = createNewSegment(NULL);
00045         } else if (last->nRows == quantum) { 
00046             last = last->next = createNewSegment(last);
00047         }
00048         last->rows[last->nRows++] = oid;
00049         nRows += 1;
00050     }
00051    
00052     void sort(dbDatabase* db, dbOrderByNode* order);
00053     static int compare(oid_t a, oid_t b, dbOrderByNode* order);
00054 
00055     void toArray(oid_t* oids) const;
00056     void truncate(size_t from, size_t length);
00057 
00058     dbSelection() { 
00059         nRows = 0;
00060         pos = 0;
00061         first = curr = last = NULL;
00062     }
00063     void reverse();
00064     void reset();
00065 };
00066 
00067 enum dbCursorType { 
00068     dbCursorViewOnly,
00069     dbCursorForUpdate
00070 };
00071 
00075 class FASTDB_DLL_ENTRY dbAnyCursor : public dbL2List { 
00076     friend class dbAnyContainer;
00077     friend class dbDatabase;
00078     friend class dbHashTable;
00079     friend class dbTtreeNode;
00080     friend class dbRtreePage;
00081     friend class dbSubSql;
00082     friend class dbStatement;
00083     friend class dbServer;
00084     friend class dbCLI;
00085     friend class JniResultSet;
00086   public:
00091     int getNumberOfRecords() const { return (int)selection.nRows; }
00092 
00096     void remove();
00097     
00102     bool isEmpty() const { return currId == 0; }
00103 
00108     bool isUpdateCursor() const { 
00109         return type == dbCursorForUpdate;
00110     }
00111 
00116     bool isLimitReached() const { return selection.nRows >= limit || selection.nRows >= stmtLimitLen; }
00117 
00125     oid_t* toArrayOfOid(oid_t* arr) const; 
00126 
00137     int select(dbQuery& query, dbCursorType aType, void* paramStruct = NULL) {
00138         type = aType;
00139         reset();
00140         paramBase = paramStruct;
00141         db->select(this, query);
00142         paramBase = NULL;
00143         if (gotoFirst() && prefetch) { 
00144             fetch();
00145         }
00146         return (int)selection.nRows;
00147     } 
00148     
00155     int select(dbQuery& query, void* paramStruct = NULL) { 
00156         return select(query, defaultType, paramStruct);
00157     }
00158      
00166     int select(char const* condition, dbCursorType aType, void* paramStruct = NULL) { 
00167         dbQuery query(condition);
00168         return select(query, aType, paramStruct);
00169     } 
00170 
00177     int select(char const* condition, void* paramStruct = NULL) { 
00178         return select(condition, defaultType, paramStruct);
00179     }
00180 
00186     int select(dbCursorType aType) { 
00187         type = aType;
00188         reset();
00189         db->select(this); 
00190         if (gotoFirst() && prefetch) { 
00191             fetch();
00192         }
00193         return (int)selection.nRows;
00194     } 
00195 
00200     int select() {
00201         return select(defaultType);
00202     }
00203 
00210     int selectByKey(char const* key, void const* value);
00211 
00219     int selectByKeyRange(char const* key, void const* minValue, void const* maxValue);
00220 
00225     void update() { 
00226         assert(type == dbCursorForUpdate && currId != 0);
00227         db->update(currId, table, record);
00228     }
00229 
00233     void removeAll() {
00234         assert(db != NULL);
00235         db->deleteTable(table);
00236         reset();
00237     }
00238 
00242     void removeAllSelected();
00243 
00247     void setSelectionLimit(size_t lim) { limit = lim; }
00248     
00252     void unsetSelectionLimit() { limit = dbDefaultSelectionLimit; }
00253 
00260     void setPrefetchMode(bool mode) { prefetch = mode; }
00261 
00262 
00267     void enableCheckForDuplicates(bool enabled) {
00268         checkForDuplicatedIsEnabled = enabled;
00269     }
00270         
00271 
00275     void reset();
00276 
00281     bool isLast() const; 
00282 
00287     bool isFirst() const; 
00288 
00294     void freeze();
00295 
00299     void unfreeze();
00300 
00308     bool skip(int n);
00309 
00310 
00316     int seek(oid_t oid);
00317 
00321     dbTableDescriptor* getTable() { return table; }
00322 
00323 
00328     void setTable(dbTableDescriptor* aTable) { 
00329         table = aTable;
00330         db = aTable->db;
00331     }
00332 
00337     void setRecord(void* rec) { 
00338         record = (byte*)rec;
00339     }
00340 
00345     void* getRecord() { 
00346         return record;
00347     }
00348 
00353     bool isInSelection(oid_t oid);
00354 
00355 
00360     void fetch() { 
00361         assert(!(db->currIndex[currId] 
00362                  & (dbInternalObjectMarker|dbFreeHandleMarker)));
00363         table->columns->fetchRecordFields(record, 
00364                                           (byte*)db->getRow(currId));
00365     }
00366 
00370     bool hasNext() const;
00371     
00372   protected: 
00373     dbDatabase*        db;
00374     dbTableDescriptor* table;
00375     dbCursorType       type;
00376     dbCursorType       defaultType;
00377     dbSelection        selection;
00378     bool               allRecords;
00379     oid_t              firstId;
00380     oid_t              lastId;
00381     oid_t              currId;
00382     byte*              record;
00383     size_t             limit;
00384 
00385     int4*              bitmap; // bitmap to avoid duplicates
00386     size_t             bitmapSize;
00387     bool               eliminateDuplicates;
00388     bool               checkForDuplicatedIsEnabled;
00389     bool               prefetch;
00390     bool               removed; // current record was removed
00391     bool               lastRecordWasDeleted; //last record was deleted
00392 
00393     size_t             stmtLimitStart;
00394     size_t             stmtLimitLen;
00395     size_t             nSkipped;
00396 
00397     void*              paramBase;
00398     
00399     void checkForDuplicates();
00400     void deallocateBitmap();
00401 
00402     bool isMarked(oid_t oid) { 
00403         return bitmap != NULL && (bitmap[oid >> 5] & (1 << (oid & 31))) != 0;
00404     }
00405 
00406     void setStatementLimit(dbQuery const& q) { 
00407         stmtLimitStart = q.stmtLimitStartPtr != NULL ? (nat4)*q.stmtLimitStartPtr : q.stmtLimitStart;
00408         stmtLimitLen = q.stmtLimitLenPtr != NULL ? (nat4)*q.stmtLimitLenPtr : q.stmtLimitLen;
00409     }
00410 
00411     void truncateSelection() { 
00412         selection.truncate(stmtLimitStart, stmtLimitLen);
00413     }
00414 
00415     void mark(oid_t oid) { 
00416         if (bitmap != NULL) { 
00417             bitmap[oid >> 5] |= 1 << (oid & 31);
00418         }
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[oid >> 5] & (1 << (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 
00442     bool gotoNext();
00443     bool gotoPrev(); 
00444     bool gotoFirst();
00445     bool gotoLast();
00446     
00447     bool moveNext();
00448     bool movePrev();
00449 
00450     void setCurrent(dbAnyReference const& ref);
00451 
00452     void adjustReferences(size_t base, size_t size, long shift) { 
00453         if (currId != 0 && record != NULL) { 
00454             table->columns->adjustReferences(record, base, size, shift);
00455         }
00456     }
00457 
00458     dbAnyCursor(dbTableDescriptor& aTable, dbCursorType aType, byte* rec)
00459     : table(&aTable),type(aType),defaultType(aType),
00460       allRecords(false),currId(0),record(rec)
00461     {
00462         db = aTable.db;
00463         limit = dbDefaultSelectionLimit;
00464         prefetch = rec != NULL;
00465         removed = false;
00466         bitmap = NULL; 
00467         bitmapSize = 0;
00468         eliminateDuplicates = false;
00469         checkForDuplicatedIsEnabled = true;
00470         paramBase = NULL;
00471         stmtLimitLen = dbDefaultSelectionLimit;
00472         stmtLimitStart = 0;
00473         nSkipped = 0;
00474     }
00475   public:
00476     dbAnyCursor() 
00477     : table(NULL),type(dbCursorViewOnly),defaultType(dbCursorViewOnly),
00478           allRecords(false),currId(0),record(NULL)
00479     {
00480         limit = dbDefaultSelectionLimit;
00481         prefetch = false;
00482         removed = false;
00483         bitmap = NULL;
00484         bitmapSize = 0;
00485         eliminateDuplicates = false;
00486         checkForDuplicatedIsEnabled = true;
00487         db = NULL;
00488         paramBase = NULL;
00489         stmtLimitLen = dbDefaultSelectionLimit;
00490         stmtLimitStart = 0;
00491         nSkipped = 0;
00492     }
00493     ~dbAnyCursor();
00494 };
00495 
00496 
00500 template<class T>
00501 class dbCursor : public dbAnyCursor { 
00502   private:
00503     // Itis not possible to copy cursors
00504     dbCursor<T> operator = (dbCursor<T> const& src) { 
00505         return *this;
00506     } 
00507 
00508   protected:
00509     T record;
00510     
00511   public:
00516     dbCursor(dbCursorType type = dbCursorViewOnly) 
00517         : dbAnyCursor(T::dbDescriptor, type, (byte*)&record) {}
00518 
00525     dbCursor(dbDatabase* aDb, dbCursorType type = dbCursorViewOnly)
00526         : dbAnyCursor(T::dbDescriptor, type, (byte*)&record)
00527     {
00528         db = aDb;
00529         dbTableDescriptor* theTable = db->lookupTable(table);
00530         if (theTable != NULL) { 
00531             table = theTable;
00532         }
00533     }
00534 
00539     T* get() { 
00540         return currId == 0 ? (T*)NULL : &record; 
00541     }
00542     
00547     T* next() {
00548         return (T*)fetchNext();
00549     }
00550 
00555     T* prev() { 
00556         return (T*)fetchPrev();
00557     }
00558 
00563     T* first() { 
00564         if (gotoFirst()) {
00565             fetch();
00566             return &record;
00567         }
00568         return NULL;
00569     }
00570 
00575     T* last() { 
00576         if (gotoLast()) {
00577             fetch();
00578             return &record;
00579         }
00580         return NULL;
00581     }    
00582     
00588     int seek(dbReference<T> const& ref) { 
00589         return dbAnyCursor::seek(ref.getOid());
00590     }
00591 
00596     T* operator ->() { 
00597         assert(currId != 0);
00598         return &record;
00599     }
00600 
00606     T* at(dbReference<T> const& ref) { 
00607         setCurrent(ref);
00608         return &record;
00609     }
00610     
00615     void toArray(dbArray< dbReference<T> >& arr) const { 
00616         arr.resize(selection.nRows);
00617         toArrayOfOid((oid_t*)arr.base());
00618     }
00619 
00624     dbReference<T> currentId() const { 
00625         return dbReference<T>(currId);
00626     }
00627 
00632     bool isInSelection(dbReference<T>& ref) {
00633         return dbAnyCursor::isInSelection(ref.getOid());
00634     }
00635 };
00636 
00637 class dbParallelQueryContext { 
00638   public:
00639     dbDatabase* const      db;
00640     dbCompiledQuery* const query;
00641     oid_t                  firstRow;
00642     dbTable*               table;
00643     dbAnyCursor*           cursor;
00644     dbSelection            selection[dbMaxParallelSearchThreads];
00645 
00646     void search(int i); 
00647 
00648     dbParallelQueryContext(dbDatabase* aDb, dbTable* aTable, 
00649                            dbCompiledQuery* aQuery, dbAnyCursor* aCursor)
00650       : db(aDb), query(aQuery), firstRow(aTable->firstRow), table(aTable), cursor(aCursor) {}
00651 };
00652 
00653 
00654 extern char* strupper(char* s);
00655 
00656 extern char* strlower(char* s);
00657 
00658 END_FASTDB_NAMESPACE
00659 
00660 #endif

Generated on Thu Feb 14 12:42:30 2008 for FastDB by doxygen1.2.18