Main Page | Class Hierarchy | Class List | File List | Class 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 class dbOrderByNode;
00015 
00016 class FASTDB_DLL_ENTRY dbSelection { 
00017   public:
00018     enum { quantum = 1024 };
00019     class segment { 
00020       public:
00021         segment* prev;
00022         segment* next;
00023         size_t   nRows;
00024         oid_t    rows[quantum];
00025 
00026         segment(segment* after) { 
00027             prev = after;
00028             next = NULL;
00029             nRows = 0;
00030         }       
00031     };
00032     segment*  first;
00033     segment*  last;
00034     segment*  curr;
00035     size_t    nRows;
00036     size_t    pos;
00037 
00038     segment*  createNewSegment(segment* after);
00039 
00040     void add(oid_t oid) {
00041         if (last == NULL) { 
00042             first = last = createNewSegment(NULL);
00043         } else if (last->nRows == quantum) { 
00044             last = last->next = createNewSegment(last);
00045         }
00046         last->rows[last->nRows++] = oid;
00047         nRows += 1;
00048     }
00049    
00050     void sort(dbDatabase* db, dbOrderByNode* order);
00051     static int compare(dbRecord* a, dbRecord* b, dbOrderByNode* order);
00052     static int compare(oid_t a, oid_t b, dbOrderByNode* order);
00053 
00054     void toArray(oid_t* oids) const;
00055 
00056     dbSelection() { 
00057         nRows = 0;
00058         pos = 0;
00059         first = curr = last = NULL;
00060     }
00061     void reverse();
00062     void reset();
00063 };
00064 
00065 enum dbCursorType { 
00066     dbCursorViewOnly,
00067     dbCursorForUpdate
00068 };
00069 
00073 class FASTDB_DLL_ENTRY dbAnyCursor : public dbL2List { 
00074     friend class dbAnyContainer;
00075     friend class dbDatabase;
00076     friend class dbHashTable;
00077     friend class dbTtreeNode;
00078     friend class dbSubSql;
00079     friend class dbStatement;
00080     friend class dbServer;
00081     friend class dbCLI;
00082   public:
00087     int getNumberOfRecords() const { return selection.nRows; }
00088 
00092     void remove();
00093     
00098     bool isEmpty() const { return currId == 0; }
00099 
00104     bool isUpdateCursor() const { 
00105         return type == dbCursorForUpdate;
00106     }
00107 
00112     bool isLimitReached() const { return selection.nRows >= limit; }
00113 
00121     oid_t* toArrayOfOid(oid_t* arr) const; 
00122 
00133     int select(dbQuery& query, dbCursorType aType, void* paramStruct = NULL) {
00134         type = aType;
00135         reset();
00136         paramBase = paramStruct;
00137         db->select(this, query);
00138         paramBase = NULL;
00139         if (gotoFirst() && prefetch) { 
00140             fetch();
00141         }
00142         return selection.nRows;
00143     } 
00144     
00151     int select(dbQuery& query, void* paramStruct = NULL) { 
00152         return select(query, defaultType, paramStruct);
00153     }
00154      
00162     int select(char const* condition, dbCursorType aType, void* paramStruct = NULL) { 
00163         dbQuery query(condition);
00164         return select(query, aType, paramStruct);
00165     } 
00166 
00173     int select(char const* condition, void* paramStruct = NULL) { 
00174         return select(condition, defaultType, paramStruct);
00175     }
00176 
00182     int select(dbCursorType aType) { 
00183         type = aType;
00184         reset();
00185         db->select(this); 
00186         if (gotoFirst() && prefetch) { 
00187             fetch();
00188         }
00189         return selection.nRows;
00190     } 
00191 
00196     int select() {
00197         return select(defaultType);
00198     }
00199 
00206     int selectByKey(char const* key, void const* value);
00207 
00215     int selectByKeyRange(char const* key, void const* minValue, void const* maxValue);
00216 
00221     void update() { 
00222         assert(type == dbCursorForUpdate && currId != 0);
00223         updateInProgress = true;
00224         db->update(currId, table, record);
00225         updateInProgress = false;
00226     }
00227 
00231     void removeAll() {
00232         assert(db != NULL);
00233         db->deleteTable(table);
00234         reset();
00235     }
00236 
00240     void removeAllSelected();
00241 
00245     void setSelectionLimit(size_t lim) { limit = lim; }
00246     
00250     void unsetSelectionLimit() { limit = dbDefaultSelectionLimit; }
00251 
00258     void setPrefetchMode(bool mode) { prefetch = mode; }
00259 
00263     void reset();
00264 
00269     bool isLast() const; 
00270 
00275     bool isFirst() const; 
00276 
00282     void freeze();
00283 
00287     void unfreeze();
00288 
00296     bool skip(int n);
00297 
00298 
00304     int seek(oid_t oid);
00305 
00309     dbTableDescriptor* getTable() { return table; }
00310 
00311 
00316     void setTable(dbTableDescriptor* aTable) { 
00317         table = aTable;
00318         db = aTable->db;
00319     }
00320 
00325     void setRecord(void* rec) { 
00326         record = (byte*)rec;
00327     }
00328 
00333     void* getRecord() { 
00334         return record;
00335     }
00336 
00341     bool isInSelection(oid_t oid);
00342 
00343 
00348     void fetch() { 
00349         assert(!(db->currIndex[currId] 
00350                  & (dbInternalObjectMarker|dbFreeHandleMarker)));
00351         table->columns->fetchRecordFields(record, 
00352                                           (byte*)db->getRow(currId));
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 
00369     int4*              bitmap; // bitmap to avoid duplicates
00370     size_t             bitmapSize;
00371     bool               eliminateDuplicates;
00372     bool               prefetch;
00373     bool               removed; // current record was removed
00374     bool               updateInProgress;
00375 
00376     void*              paramBase;
00377     
00378     void checkForDuplicates();
00379 
00380     bool isMarked(oid_t oid) { 
00381         return bitmap != NULL && (bitmap[oid >> 5] & (1 << (oid & 31))) != 0;
00382     }
00383 
00384     void mark(oid_t oid) { 
00385         if (bitmap != NULL) { 
00386             bitmap[oid >> 5] |= 1 << (oid & 31);
00387         }
00388     }    
00389 
00390     bool add(oid_t oid) { 
00391         if (selection.nRows < limit) { 
00392             if (eliminateDuplicates) { 
00393                 if (bitmap[oid >> 5] & (1 << (oid & 31))) { 
00394                     return true;
00395                 }
00396                 bitmap[oid >> 5] |= 1 << (oid & 31);
00397             } 
00398             selection.add(oid);
00399             return selection.nRows < limit;
00400         } 
00401         return false;
00402     }
00403 
00404     bool gotoNext();
00405     bool gotoPrev(); 
00406     bool gotoFirst();
00407     bool gotoLast();
00408     
00409     void setCurrent(dbAnyReference const& ref);
00410 
00411     void adjustReferences(size_t base, size_t size, long shift) { 
00412         if (currId != 0) { 
00413             table->columns->adjustReferences(record, base, size, shift);
00414         }
00415     }
00416 
00417     dbAnyCursor(dbTableDescriptor& aTable, dbCursorType aType, byte* rec)
00418     : table(&aTable),type(aType),defaultType(aType),
00419       allRecords(false),currId(0),record(rec)
00420     {
00421         db = aTable.db;
00422         limit = dbDefaultSelectionLimit;
00423         updateInProgress = false;
00424         prefetch = true;
00425         removed = false;
00426         bitmap = NULL; 
00427         bitmapSize = 0;
00428         eliminateDuplicates = false;
00429         paramBase = NULL;
00430     }
00431   public:
00432     dbAnyCursor() 
00433     : table(NULL),type(dbCursorViewOnly),defaultType(dbCursorViewOnly),
00434           allRecords(false),currId(0),record(NULL)
00435     {
00436         limit = dbDefaultSelectionLimit;
00437         updateInProgress = false;
00438         prefetch = false;
00439         removed = false;
00440         bitmap = NULL;
00441         bitmapSize = 0;
00442         eliminateDuplicates = false;
00443         db = NULL;
00444         paramBase = NULL;
00445     }
00446     ~dbAnyCursor();
00447 };
00448 
00449 
00453 template<class T>
00454 class dbCursor : public dbAnyCursor { 
00455   protected:
00456     T record;
00457     
00458   public:
00463     dbCursor(dbCursorType type = dbCursorViewOnly) 
00464         : dbAnyCursor(T::dbDescriptor, type, (byte*)&record) {}
00465 
00472     dbCursor(dbDatabase* aDb, dbCursorType type = dbCursorViewOnly)
00473         : dbAnyCursor(T::dbDescriptor, type, (byte*)&record)
00474     {
00475         db = aDb;
00476         dbTableDescriptor* theTable = db->lookupTable(table);
00477         if (theTable != NULL) { 
00478             table = theTable;
00479         }
00480     }
00481 
00486     T* get() { 
00487         return currId == 0 ? (T*)NULL : &record; 
00488     }
00489     
00494     T* next() { 
00495         if (gotoNext()) { 
00496             fetch();
00497             return &record;
00498         }
00499         return NULL;
00500     }
00501 
00506     T* prev() { 
00507         if (gotoPrev()) { 
00508             fetch();
00509             return &record;
00510         }
00511         return NULL;
00512     }
00513 
00518     T* first() { 
00519         if (gotoFirst()) {
00520             fetch();
00521             return &record;
00522         }
00523         return NULL;
00524     }
00525 
00530     T* last() { 
00531         if (gotoLast()) {
00532             fetch();
00533             return &record;
00534         }
00535         return NULL;
00536     }    
00537     
00543     int seek(dbReference<T> const& ref) { 
00544         return dbAnyCursor::seek(ref.getOid());
00545     }
00546 
00551     T* operator ->() { 
00552         assert(currId != 0);
00553         return &record;
00554     }
00555 
00561     T* at(dbReference<T> const& ref) { 
00562         setCurrent(ref);
00563         return &record;
00564     }
00565     
00570     void toArray(dbArray< dbReference<T> >& arr) const { 
00571         arr.resize(selection.nRows);
00572         toArrayOfOid((oid_t*)arr.base());
00573     }
00574 
00579     dbReference<T> currentId() const { 
00580         return dbReference<T>(currId);
00581     }
00582 
00599     T* nextAvailable() { 
00600         if (!removed) { 
00601             return next(); 
00602         } else { 
00603             removed = false;
00604             return get();
00605         }
00606     }
00607 
00612     bool isInSelection(dbReference<T>& ref)  const {
00613         return dbAnyCursor::isInSelection(ref.getOid());
00614     }
00615 };
00616 
00617 class dbParallelQueryContext { 
00618   public:
00619     dbDatabase* const      db;
00620     dbCompiledQuery* const query;
00621     oid_t                  firstRow;
00622     dbTable*               table;
00623     dbAnyCursor*           cursor;
00624     dbSelection            selection[dbMaxParallelSearchThreads];
00625 
00626     void search(int i); 
00627 
00628     dbParallelQueryContext(dbDatabase* aDb, dbTable* aTable, 
00629                            dbCompiledQuery* aQuery, dbAnyCursor* aCursor)
00630       : db(aDb), query(aQuery), firstRow(aTable->firstRow), table(aTable), cursor(aCursor) {}
00631 };
00632 
00633 
00634 extern char* strupper(char* s);
00635 
00636 extern char* strlower(char* s);
00637 
00638 #endif

Generated on Thu Feb 12 13:04:48 2004 for FastDB by doxygen 1.3.5