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 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     void add(oid_t oid) { 
00039         if (last == NULL) { 
00040             first = last = new segment(NULL);
00041         } else if (last->nRows == quantum) { 
00042             last = last->next = new segment(last);
00043         }
00044         last->rows[last->nRows++] = oid;
00045         nRows += 1;
00046     }
00047     
00048     void sort(dbDatabase* db, dbOrderByNode* order);
00049     static int compare(dbRecord* a, dbRecord* b, dbOrderByNode* order);
00050 
00051     void toArray(oid_t* oids);
00052 
00053     dbSelection() { 
00054         nRows = 0;
00055         pos = 0;
00056         first = curr = last = NULL;
00057     }
00058     void reverse();
00059     void reset();
00060 };
00061 
00062 enum dbCursorType { 
00063     dbCursorViewOnly,
00064     dbCursorForUpdate
00065 };
00066 
00070 class FASTDB_DLL_ENTRY dbAnyCursor : public dbL2List { 
00071     friend class dbAnyContainer;
00072     friend class dbDatabase;
00073     friend class dbHashTable;
00074     friend class dbTtreeNode;
00075     friend class dbSubSql;
00076     friend class dbStatement;
00077     friend class dbServer;
00078     friend class dbCLI;
00079   public:
00084     int getNumberOfRecords() { return selection.nRows; }
00085 
00089     void remove();
00090     
00095     bool isEmpty() { return currId == 0; }
00096 
00101     bool isLimitReached() { return selection.nRows >= limit; }
00102 
00110     oid_t* toArrayOfOid(oid_t* arr); 
00111 
00122     int select(dbQuery& query, dbCursorType aType, void* paramStruct = NULL) {
00123         type = aType;
00124         reset();
00125         paramBase = paramStruct;
00126         db->select(this, query);
00127         paramBase = NULL;
00128         if (gotoFirst() && prefetch) { 
00129             fetch();
00130         }
00131         return selection.nRows;
00132     } 
00133     
00140     int select(dbQuery& query, void* paramStruct = NULL) { 
00141         return select(query, defaultType, paramStruct);
00142     }
00143      
00151     int select(char const* condition, dbCursorType aType, void* paramStruct = NULL) { 
00152         dbQuery query(condition);
00153         return select(query, aType, paramStruct);
00154     } 
00155 
00162     int select(char 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 selection.nRows;
00179     } 
00180 
00185     int select() {
00186         return select(defaultType);
00187     }
00188 
00193     void update() { 
00194         assert(type == dbCursorForUpdate && currId != 0);
00195         updateInProgress = true;
00196         db->update(currId, table, record);
00197         updateInProgress = false;
00198     }
00199 
00203     void removeAll() {
00204         assert(db != NULL);
00205         db->deleteTable(table);
00206         reset();
00207     }
00208 
00212     void removeAllSelected();
00213 
00217     void setSelectionLimit(size_t lim) { limit = lim; }
00218     
00222     void unsetSelectionLimit() { limit = dbDefaultSelectionLimit; }
00223 
00230     void setPrefetchMode(bool mode) { prefetch = mode; }
00231 
00235     void reset();
00236 
00241     bool isLast(); 
00242 
00247     bool isFirst(); 
00248 
00254     void freeze();
00255 
00259     void unfreeze();
00260 
00264     dbTableDescriptor* getTable() { return table; }
00265 
00266   protected: 
00267     dbDatabase*        db;
00268     dbTableDescriptor* table;
00269     dbCursorType       type;
00270     dbCursorType       defaultType;
00271     dbSelection        selection;
00272     bool               allRecords;
00273     oid_t              firstId;
00274     oid_t              lastId;
00275     oid_t              currId;
00276     byte*              record;
00277     size_t             limit;
00278 
00279     int4*              bitmap; // bitmap to avoid duplicates
00280     size_t             bitmapSize;
00281     bool               eliminateDuplicates;
00282     bool               prefetch;
00283     bool               removed; // current record was removed
00284     bool               updateInProgress;
00285 
00286     void*              paramBase;
00287     
00288     void checkForDuplicates() { 
00289         if (!eliminateDuplicates && limit > 1) { 
00290             eliminateDuplicates = true;
00291             size_t size = (db->currIndexSize + 31) / 32;
00292             if (size > bitmapSize) { 
00293                 delete[] bitmap;
00294                 bitmap = new int4[size];
00295                 bitmapSize = size;
00296             }
00297             memset(bitmap, 0, size*4);
00298         }
00299     }
00300 
00301     bool isMarked(oid_t oid) { 
00302         return bitmap != NULL && (bitmap[oid >> 5] & (1 << (oid & 31))) != 0;
00303     }
00304 
00305     void mark(oid_t oid) { 
00306         if (bitmap != NULL) { 
00307             bitmap[oid >> 5] |= 1 << (oid & 31);
00308         }
00309     }    
00310 
00311     bool add(oid_t oid) { 
00312         if (selection.nRows < limit) { 
00313             if (eliminateDuplicates) { 
00314                 if (bitmap[oid >> 5] & (1 << (oid & 31))) { 
00315                     return true;
00316                 }
00317                 bitmap[oid >> 5] |= 1 << (oid & 31);
00318             } 
00319             selection.add(oid);
00320             return selection.nRows < limit;
00321         } 
00322         return false;
00323     }
00324 
00325     bool gotoNext();
00326     bool gotoPrev(); 
00327     bool gotoFirst();
00328     bool gotoLast();
00329     
00330     void setCurrent(dbAnyReference const& ref);
00331 
00332     void fetch() { 
00333         assert(!(db->currIndex[currId] 
00334                  & (dbInternalObjectMarker|dbFreeHandleMarker)));
00335         table->columns->fetchRecordFields(record, 
00336                                           (byte*)db->getRow(currId));
00337     }
00338 
00339     void adjustReferences(size_t base, size_t size, long shift) { 
00340         if (currId != 0) { 
00341             table->columns->adjustReferences(record, base, size, shift);
00342         }
00343     }
00344 
00345     void setTable(dbTableDescriptor* aTable) { 
00346         table = aTable;
00347         db = aTable->db;
00348     }
00349 
00350     void setRecord(byte* rec) { 
00351         record = rec;
00352     }
00353 
00354     dbAnyCursor(dbTableDescriptor& aTable, dbCursorType aType, byte* rec)
00355     : table(&aTable),type(aType),defaultType(aType),
00356       allRecords(false),currId(0),record(rec)
00357     {
00358         db = aTable.db;
00359         limit = dbDefaultSelectionLimit;
00360         updateInProgress = false;
00361         prefetch = true;
00362         removed = false;
00363         bitmap = NULL; 
00364         bitmapSize = 0;
00365         eliminateDuplicates = false;
00366         paramBase = NULL;
00367     }
00368   public:
00369     dbAnyCursor() 
00370     : table(NULL),type(dbCursorViewOnly),defaultType(dbCursorViewOnly),
00371           allRecords(false),currId(0),record(NULL)
00372     {
00373         limit = dbDefaultSelectionLimit;
00374         updateInProgress = false;
00375         prefetch = false;
00376         removed = false;
00377         bitmap = NULL;
00378         bitmapSize = 0;
00379         eliminateDuplicates = false;
00380         db = NULL;
00381         paramBase = NULL;
00382     }
00383     ~dbAnyCursor();
00384 };
00385 
00386 
00390 template<class T>
00391 class dbCursor : public dbAnyCursor { 
00392   protected:
00393     T record;
00394     
00395   public:
00400     dbCursor(dbCursorType type = dbCursorViewOnly) 
00401         : dbAnyCursor(T::dbDescriptor, type, (byte*)&record) {}
00402 
00409     dbCursor(dbDatabase* aDb, dbCursorType type = dbCursorViewOnly)
00410         : dbAnyCursor(T::dbDescriptor, type, (byte*)&record)
00411     {
00412         db = aDb;
00413         dbTableDescriptor* theTable = db->lookupTable(table);
00414         if (theTable != NULL) { 
00415             table = theTable;
00416         }
00417     }
00418 
00423     T* get() { 
00424         return currId == 0 ? (T*)NULL : &record; 
00425     }
00426     
00431     T* next() { 
00432         if (gotoNext()) { 
00433             fetch();
00434             return &record;
00435         }
00436         return NULL;
00437     }
00438 
00443     T* prev() { 
00444         if (gotoPrev()) { 
00445             fetch();
00446             return &record;
00447         }
00448         return NULL;
00449     }
00450 
00455     T* first() { 
00456         if (gotoFirst()) {
00457             fetch();
00458             return &record;
00459         }
00460         return NULL;
00461     }
00462 
00467     T* last() { 
00468         if (gotoLast()) {
00469             fetch();
00470             return &record;
00471         }
00472         return NULL;
00473     }    
00474     
00479     T* operator ->() { 
00480         assert(currId != 0);
00481         return &record;
00482     }
00483 
00489     T* at(dbReference<T> const& ref) { 
00490         setCurrent(ref);
00491         return &record;
00492     }
00493     
00498     void toArray(dbArray< dbReference<T> >& arr) { 
00499         arr.resize(selection.nRows);
00500         toArrayOfOid((oid_t*)arr.base());
00501     }
00502 
00507     dbReference<T> currentId() { 
00508         return dbReference<T>(currId);
00509     }
00510 
00527     T* nextAvailable() { 
00528         if (!removed) { 
00529             return next(); 
00530         } else { 
00531             removed = false;
00532             return get();
00533         }
00534     }
00535 };
00536 
00537 class dbParallelQueryContext { 
00538   public:
00539     dbDatabase* const      db;
00540     dbCompiledQuery* const query;
00541     oid_t                  firstRow;
00542     dbTable*               table;
00543     dbAnyCursor*           cursor;
00544     dbSelection            selection[dbMaxParallelSearchThreads];
00545 
00546     void search(int i); 
00547 
00548     dbParallelQueryContext(dbDatabase* aDb, dbTable* aTable, 
00549                            dbCompiledQuery* aQuery, dbAnyCursor* aCursor)
00550       : db(aDb), query(aQuery), firstRow(aTable->firstRow), table(aTable), cursor(aCursor) {}
00551 };
00552 
00553 
00554 extern char* strupper(char* s);
00555 
00556 extern char* strlower(char* s);
00557 
00558 #endif

Generated on Fri Nov 15 21:06:28 2002 for FastDB by doxygen1.2.15