Main Page   Class Hierarchy   Compound List   File List   Compound Members  

database.h

00001 //-< DATABASE.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: 23-Dec-98    K.A. Knizhnik  * GARRET *
00007 //-------------------------------------------------------------------*--------*
00008 // Database management
00009 //-------------------------------------------------------------------*--------*
00010 
00011 #ifndef __DATABASE_H__
00012 #define __DATABASE_H__
00013 
00014 #include "class.h"
00015 #include "reference.h"
00016 #include "file.h"
00017 
00018 BEGIN_FASTDB_NAMESPACE
00019 
00023 #ifdef DISKLESS_CONFIGURATION
00024 // In diskless confiuration database can not be reallocated
00025 const size_t dbDefaultInitDatabaseSize = 32*1024*1024;
00026 #else
00027 const size_t dbDefaultInitDatabaseSize = 1024*1024;
00028 #endif
00029 
00033 const size_t dbDefaultInitIndexSize = 512*1024;
00034 
00038 const size_t dbDefaultExtensionQuantum = 4*1024*1024;
00039 
00043 const unsigned dbMaxParallelSearchThreads = 64;
00044 
00048 enum dbInternalObject { 
00049     dbTableRow, 
00050     dbPageObjectMarker,
00051     dbTtreeMarker,
00052     dbTtreeNodeMarker,
00053     dbHashTableMarker,
00054     dbHashTableItemMarker,
00055     dbRtreeMarker,
00056     dbRtreePageMarker,
00057     
00058     dbInternalObjectMarker = 7 // mask for internals object markers
00059 };
00060     
00061 const offs_t dbFreeHandleMarker = (offs_t)1 << (sizeof(offs_t)*8 - 1); 
00062 
00063 const size_t dbAllocationQuantumBits = 4;
00064 const size_t dbAllocationQuantum = 1 << dbAllocationQuantumBits;
00065 const size_t dbPageBits = 12;
00066 const size_t dbPageSize = 1 << dbPageBits;
00067 const size_t dbIdsPerPage = dbPageSize / sizeof(oid_t);
00068 const size_t dbHandlesPerPage = dbPageSize / sizeof(offs_t);
00069 const size_t dbHandleBits = 1 + sizeof(offs_t)/4; // log(sizeof(offs_t))
00070 const size_t dbBitmapSegmentBits = dbPageBits + 3 + dbAllocationQuantumBits;
00071 const size_t dbBitmapSegmentSize = 1 << dbBitmapSegmentBits;
00072 const size_t dbBitmapPages = 1 << (dbDatabaseOffsetBits-dbBitmapSegmentBits);
00073 const size_t dbDirtyPageBitmapSize = 1 << (dbDatabaseOidBits-dbPageBits+dbHandleBits-3);
00074 const size_t dbDefaultSelectionLimit = 2000000000;
00075 
00076 const int    dbBMsearchThreshold = 512;
00077 
00078 const char   dbMatchAnyOneChar = '_';
00079 const char   dbMatchAnySubstring = '%';
00080 
00081 const int    dbMaxReaders = 64; // maximal number of readers concurrently accessing the database
00082 
00086 enum dbPredefinedIds { 
00087     dbInvalidId,
00088     dbMetaTableId, 
00089     dbBitmapId,
00090     dbFirstUserId = dbBitmapId + dbBitmapPages
00091 };
00092 
00096 class dbHeader { 
00097   public:
00098     offs_t size;  // database file size
00099     int4   curr;  // current root
00100     int4   dirty; // database was not closed normally
00101     int4   initialized; // database is initilaized
00102     int4   pad;
00103     struct { 
00104         offs_t index;           // offset to object index
00105         offs_t shadowIndex;     // offset to shadow index
00106         oid_t  indexSize;       // size of object index
00107         oid_t  shadowIndexSize; // size of object index
00108         oid_t  indexUsed;       // used part of the index   
00109         oid_t  freeList;        // L1 list of free descriptors
00110     } root[2];
00111     
00112     int4 majorVersion;
00113     int4 minorVersion;
00114     int4 mode;
00115 
00116     enum { 
00117         MODE_OID_64        = 0x01,
00118         MODE_OFFS_64       = 0x02,
00119         MODE_AUTOINCREMENT = 0x04,
00120         MODE_RECTANGLE_DIM = 0x08
00121     };    
00122 
00123     int getVersion() { 
00124         return majorVersion*100 + minorVersion;
00125     }
00126     
00127     bool isCompatible();
00128     static int getCurrentMode();
00129 };
00130 
00131 union  dbSynthesizedAttribute;
00132 struct dbInheritedAttribute;
00133 class dbDatabaseThreadContext;
00134 class dbAnyCursor;
00135 class dbQuery;
00136 class dbExprNode;
00137 
00138 struct dbMemoryStatistic { 
00139     offs_t used;
00140     offs_t free;
00141     offs_t nHoles;
00142     offs_t minHoleSize;
00143     offs_t maxHoleSize;
00144     size_t nHolesOfSize[dbDatabaseOffsetBits];
00145 };
00146 
00147 
00148 class dbMonitor { 
00149   public:
00150     sharedsem_t sem;
00151     sharedsem_t mutatorSem;
00152     int  nReaders;
00153     int  nWriters;
00154     int  nConcurrentWriters;
00155     int  nWaitReaders;
00156     int  nWaitWriters;
00157     int  waitForUpgrade;
00158     int  forceCommitCount;
00159     int  backupInProgress;
00160     int  uncommittedChanges;
00161 
00162     int  curr;             // copy of header->root, used to allow read access 
00163                            // to the database during transaction commit
00164 
00165     int  commitInProgress;
00166     int  concurrentTransId;
00167 
00168     unsigned lastDeadlockRecoveryTime;
00169 
00170     int  version; 
00171     int  users;  
00172 
00173     dbProcessId ownerPid;
00174 
00175     dbDatabaseThreadContext*  delayedCommitContext;     // save context of delayed transaction
00176 
00177     int4 dirtyPagesMap[dbDirtyPageBitmapSize/4];
00178 
00179     int  sharedLockOwner[dbMaxReaders];
00180     int  exclusiveLockOwner;
00181     int  clientId;
00182     int  upgradeId;
00183 
00184     int  modified;
00185 };
00186 
00190 class FASTDB_DLL_ENTRY dbL2List { 
00191   public:
00192     dbL2List* next; 
00193     dbL2List* prev; 
00194 
00195     void link(dbL2List* elem) { 
00196         elem->prev = this;
00197         elem->next = next;
00198         next = next->prev = elem;
00199     }
00200     void unlink() { 
00201         next->prev = prev;
00202         prev->next = next;
00203         next = prev = this;
00204     }
00205     bool isEmpty() { 
00206         return next == this;
00207     }
00208     void reset() { 
00209         next = prev = this;
00210     }        
00211     dbL2List() { 
00212         next = prev = this;
00213     }
00214     ~dbL2List() { 
00215         unlink();
00216     }
00217 };
00218 
00219 class dbVisitedObject {
00220   public: 
00221     dbVisitedObject* next;
00222     oid_t            oid;
00223 
00224     dbVisitedObject(oid_t oid, dbVisitedObject* chain) {         
00225         this->oid = oid;
00226         next = chain;
00227     }
00228 };
00229     
00230 #ifdef AUTO_DETECT_PROCESS_CRASH
00231 struct dbWatchDogContext : dbL2List { 
00232     dbThread    thread;
00233     dbWatchDog  watchDog;
00234     int         clientId;
00235     dbDatabase* db;
00236     dbMutex*    mutex;
00237 };
00238 #endif
00239 
00240 template<class T> 
00241 class dbHArray;
00242 
00246 class FASTDB_DLL_ENTRY dbDatabase { 
00247     friend class dbSelection;
00248     friend class dbAnyCursor;
00249     friend class dbHashTable;
00250     friend class dbQuery;
00251     friend class dbTtree;
00252     friend class dbTtreeNode;
00253     friend class dbRtree;
00254     friend class dbRtreePage;
00255     friend class dbParallelQueryContext; 
00256     friend class dbServer;
00257     friend class dbColumnBinding;
00258     friend class dbUserFunctionArgument;
00259     friend class dbAnyContainer;
00260     friend class dbFile;
00261     friend class dbCLI;
00262     friend class GiSTdb;
00263 
00264 #ifdef HAS_TEMPLATE_FRIENDS
00265     template<class T> 
00266     friend class dbHArray;
00267 #else
00268     friend class dbAnyHArray;
00269 #endif
00270 
00271   public:
00281     bool open(char const* databaseName, 
00282               char const* fileName = NULL, 
00283               time_t waitLockTimeoutMsec = INFINITE, 
00284               time_t commitDelaySec = 0);
00285 
00289     void close();
00290 
00294     void commit();
00295 
00300     void precommit();
00301     
00305     void rollback();
00306 
00313     void scheduleBackup(char const* fileName, time_t periodSec);
00314     
00319     void attach();
00320     
00326     void attach(dbDatabaseThreadContext* ctx);
00327 
00328     enum DetachFlags { 
00329         COMMIT          = 1,
00330         DESTROY_CONTEXT = 2
00331     };
00336     void detach(int flags = COMMIT|DESTROY_CONTEXT);
00337 
00341     void lock() { beginTransaction(dbExclusiveLock); }
00342 
00351     bool backup(char const* file, bool compactify);
00352     
00362     bool backup(dbFile* file, bool compactify);
00363     
00368     void assign(dbTableDescriptor& desc) { 
00369         assert(((void)"Table is not yet assigned to the database", 
00370                 desc.tableId == 0));
00371         desc.db = this; 
00372         desc.fixedDatabase = true;
00373     }
00374 
00382     void setConcurrency(unsigned nThreads);
00383 
00388     long getAllocatedSize() { return allocatedSize; }
00389 
00394     long getDatabaseSize() { return header->size; }
00395 
00400     int getNumberOfReaders() { 
00401         return monitor->nReaders;
00402     }
00403 
00408     int getNumberOfWriters() { 
00409         return monitor->nWriters;
00410     }
00411 
00416     int getNumberOfBlockedReaders() { 
00417         return monitor->nReaders;
00418     }
00419 
00424     int getNumberOfBlockedWriters() { 
00425         return monitor->nWriters;
00426     }
00427 
00432     int getNumberOfUsers() { 
00433         return monitor->users;
00434     }
00435 
00443     void allowColumnsDeletion(bool enabled = true) { 
00444         confirmDeleteColumns = enabled;
00445     }
00446 
00454     bool prepareQuery(dbAnyCursor* cursor, dbQuery& query);
00455 
00456     enum dbErrorClass { 
00457         NoError, 
00458         QueryError,
00459         ArithmeticError,
00460         IndexOutOfRangeError,
00461         DatabaseOpenError,
00462         FileError,
00463         OutOfMemoryError,
00464         Deadlock,
00465         NullReferenceError,
00466         LockRevoked,
00467         FileLimitExeeded,
00468         InconsistentInverseReference,
00469         DatabaseReadOnly
00470     };
00471     typedef void (*dbErrorHandler)(int error, char const* msg, int msgarg, void* context); 
00472 
00478     dbErrorHandler setErrorHandler(dbErrorHandler newHandler, void* errorHandlerContext = NULL);
00479 
00487     virtual void handleError(dbErrorClass error, char const* msg = NULL, 
00488                              int arg = 0); 
00489 
00496     void insertRecord(dbTableDescriptor* table, dbAnyReference* ref, 
00497                       void const* record);
00498 
00502     bool isOpen() const { return opened; }
00503 
00504 
00508     bool isCommitted();
00509 
00513     bool isAttached();
00514 
00518     bool isUpdateTransaction();
00519 
00523     int  getVersion();
00524 
00529     void setFileSizeLimit(size_t limit) { 
00530         dbFileSizeLimit = limit;
00531     }
00532 
00533 #ifdef FUZZY_CHECKPOINT
00534 
00539     void setFuzzyCheckpointBuffer(size_t nPages) { 
00540         file.setCheckpointBufferSize(nPages);
00541     }
00542 #endif
00543 
00544 #ifndef NO_MEMBER_TEMPLATES
00545 
00550     template<class T>
00551     dbReference<T> insert(T const& record) {
00552         dbReference<T> ref;
00553         insertRecord(lookupTable(&T::dbDescriptor), &ref, &record);
00554         return ref;
00555     }
00556 #endif
00557 
00563     dbTableDescriptor* lookupTable(dbTableDescriptor* desc);
00564 
00569     void getMemoryStatistic(dbMemoryStatistic& stat);
00570 
00571     enum dbAccessType { 
00572         dbReadOnly,
00573         dbAllAccess,
00574         dbConcurrentRead,
00575         dbConcurrentUpdate
00576     };
00588     dbDatabase(dbAccessType type = dbAllAccess,
00589                size_t dbInitSize = dbDefaultInitDatabaseSize,
00590                size_t dbExtensionQuantum = dbDefaultExtensionQuantum,
00591                size_t dbInitIndexSize = dbDefaultInitIndexSize,
00592                int nThreads = 1 
00593                // Do not specify the last parameter - it is only for checking
00594                // that application and FastDB library were built with the 
00595                // same compiler options (-DNO_PTHREADS is critical)
00596                // Mismached parameters should cause linker error
00597 #ifdef NO_PTHREADS
00598                , bool usePthreads = false
00599 #endif
00600                );
00604     virtual ~dbDatabase(); 
00605 
00606     const dbAccessType accessType;
00607     const size_t initSize;
00608     const size_t extensionQuantum;
00609     const size_t initIndexSize;
00610 
00611     static unsigned dbParallelScanThreshold; 
00612 
00613   protected:
00614     static size_t internalObjectSize[];
00615 
00616     dbThreadPool threadPool;
00617 
00618     dbThreadContext<dbDatabaseThreadContext> threadContext;
00619 
00620     byte*     baseAddr;         // base address of database file mapping
00621     dbHeader* header;           // database header information
00622     offs_t*   currIndex;        // current database object index
00623     offs_t*   index[2];
00624     unsigned  parThreads;
00625     bool      modified;
00626 
00627     size_t    currRBitmapPage;  //current bitmap page for allocating records
00628     size_t    currRBitmapOffs;  //offset in current bitmap page for allocating
00629                                 //unaligned records
00630     size_t    currPBitmapPage;  //current bitmap page for allocating page objects
00631     size_t    currPBitmapOffs;  //offset in current bitmap page for allocating
00632                                 //page objects
00633     struct dbLocation { 
00634         offs_t      pos;
00635         size_t      size;
00636         dbLocation* next;
00637     };
00638     dbLocation* reservedChain;
00639     
00640     char*     databaseName;
00641     int       databaseNameLen;
00642     char*     fileName;
00643     int       version;
00644 
00645     size_t    mmapSize;
00646     
00647     size_t    committedIndexSize;
00648     size_t    currIndexSize;
00649     oid_t     updatedRecordId;
00650 
00651     unsigned  dbWaitLockTimeout;
00652 
00653     size_t    dbFileSizeLimit;
00654 
00655     bool      uncommittedChanges;
00656 
00657     dbFile                    file;
00658     dbSharedObject<dbMonitor> shm;
00659     dbGlobalCriticalSection   cs;
00660     dbGlobalCriticalSection   mutatorCS;
00661     dbInitializationMutex     initMutex;
00662     dbSemaphore               writeSem; 
00663     dbSemaphore               readSem; 
00664     dbSemaphore               upgradeSem; 
00665     dbEvent                   backupCompletedEvent;
00666     dbMonitor*                monitor;
00667 
00668     dbTableDescriptor*        tables;
00669 
00670     int*                      bitmapPageAvailableSpace;
00671     bool                      opened;
00672 
00673     long                      allocatedSize;
00674     
00675     time_t                    commitDelay;     
00676     time_t                    commitTimeout;
00677     time_t                    commitTimerStarted;
00678     
00679     dbMutex                   delayedCommitStartTimerMutex;
00680     dbMutex                   delayedCommitStopTimerMutex;
00681     dbLocalEvent              delayedCommitStartTimerEvent; 
00682     dbEvent                   delayedCommitStopTimerEvent; 
00683     dbLocalEvent              commitThreadSyncEvent;
00684     bool                      delayedCommitEventsOpened;
00685 
00686     dbMutex                   backupMutex;    
00687     dbLocalEvent              backupInitEvent;
00688     char*                     backupFileName;
00689     time_t                    backupPeriod;
00690     bool                      stopDelayedCommitThread;
00691 
00692     dbThread                  backupThread;
00693     dbThread                  commitThread;
00694  
00695     int                       accessCount;
00696 
00697     dbL2List                  threadContextList;
00698     dbMutex                   threadContextListMutex;
00699 
00700     dbErrorHandler            errorHandler;
00701     void*                     errorHandlerContext;
00702     int                       schemeVersion;
00703     dbVisitedObject*          visitedChain;
00704 
00705     bool                      confirmDeleteColumns;
00706 
00707     int                       maxClientId;
00708     int                       selfId;
00709 #ifdef AUTO_DETECT_PROCESS_CRASH
00710     dbWatchDog                selfWatchDog;
00711     dbL2List                  watchDogThreadContexts;
00712     dbMutex*                  watchDogMutex;
00713 #endif
00714     
00720     dbTableDescriptor* loadMetaTable();
00721 
00722     void cleanup(dbInitializationMutex::initializationStatus status, int step);
00723 
00724     void delayedCommit();
00725     void backupScheduler();
00726 
00727     static void thread_proc delayedCommitProc(void* arg) { 
00728         ((dbDatabase*)arg)->delayedCommit();
00729     }
00730 
00731     static void thread_proc backupSchedulerProc(void* arg) { 
00732         ((dbDatabase*)arg)->backupScheduler();
00733     }
00734 
00735     virtual bool isReplicated();
00736 
00737 #ifdef AUTO_DETECT_PROCESS_CRASH
00738 
00742     void revokeLock(int clientId);
00743 
00748     static void watchDogThread(dbWatchDogContext* ctx);
00749 
00753     void startWatchDogThreads();
00754     
00758     void addLockOwner();
00759 
00763     void removeLockOwner(int clientId);
00764 #endif
00765 
00770     void commit(dbDatabaseThreadContext* ctx);
00771 
00776     void restoreTablesConsistency();
00777 
00783     dbRecord* getRow(oid_t oid) { 
00784         assert(!(currIndex[oid]&(dbFreeHandleMarker|dbInternalObjectMarker)));
00785         return (dbRecord*)(baseAddr + currIndex[oid]); 
00786     }
00787 
00797     dbRecord* putRow(oid_t oid, size_t newSize); 
00798 
00804     dbRecord* putRow(oid_t oid) { 
00805         if (oid < committedIndexSize && index[0][oid] == index[1][oid]) { 
00806             size_t size = getRow(oid)->size;
00807             size_t pageNo = oid/dbHandlesPerPage;
00808             monitor->dirtyPagesMap[pageNo >> 5] |= 1 << (pageNo & 31);
00809             cloneBitmap(currIndex[oid], size);
00810             allocate(size, oid);
00811         } 
00812         return (dbRecord*)(baseAddr + currIndex[oid]); 
00813     }
00814 
00820     byte* get(oid_t oid) { 
00821         return baseAddr + (currIndex[oid] & ~dbInternalObjectMarker); 
00822     }
00823 
00829     byte* put(oid_t oid) { 
00830         if (oid < committedIndexSize && index[0][oid] == index[1][oid]) { 
00831             offs_t offs = currIndex[oid];
00832             size_t size = internalObjectSize[offs & dbInternalObjectMarker];
00833             size_t pageNo = oid/dbHandlesPerPage;
00834             monitor->dirtyPagesMap[pageNo >> 5] |= 1 << (pageNo & 31);
00835             allocate(size, oid);
00836             cloneBitmap(offs & ~dbInternalObjectMarker, size);
00837         } 
00838         return baseAddr + (currIndex[oid] & ~dbInternalObjectMarker); 
00839     }
00840     
00854     bool isPrefixSearch(dbAnyCursor* cursor, 
00855                         dbExprNode* expr, dbExprNode* andExpr, 
00856                         dbFieldDescriptor* &indexedField);
00857 
00871     bool isIndexApplicable(dbAnyCursor* cursor, 
00872                            dbExprNode* expr, dbExprNode* andExpr, 
00873                            dbFieldDescriptor* &indexedField);
00874 
00886     bool isIndexApplicable(dbAnyCursor* cursor, 
00887                            dbExprNode* expr, dbExprNode* andExpr);
00888 
00901     bool followInverseReference(dbExprNode* expr, dbExprNode* andExpr, 
00902                                 dbAnyCursor* cursor, oid_t iref);
00903 
00911     bool existsInverseReference(dbExprNode* expr, int nExistsClauses);
00912 
00922     static void _fastcall execute(dbExprNode* expr, 
00923                                   dbInheritedAttribute& iattr,
00924                                   dbSynthesizedAttribute& sattr);
00925 
00935     bool evaluate(dbExprNode* expr, oid_t oid, dbTable* table, dbAnyCursor* cursor);
00936 
00941     void select(dbAnyCursor* cursor);
00942 
00948     void select(dbAnyCursor* cursor, dbQuery& query);
00949 
00955     void traverse(dbAnyCursor* cursor, dbQuery& query);
00956 
00963     void update(oid_t oid, dbTableDescriptor* table, void const* record);
00964     
00970     void remove(dbTableDescriptor* table, oid_t oid);
00971 
00979     offs_t allocate(size_t size, oid_t oid = 0);
00980 
00986     void deallocate(offs_t pos, size_t size);
00987 
00993     void extend(offs_t size);
00994 
01000     void cloneBitmap(offs_t pos, size_t size);
01001 
01008     oid_t allocateId(int n = 1);
01009 
01016     void freeId(oid_t oid, int n = 1);
01017 
01023     void updateCursors(oid_t oid, bool removed = false);
01024     
01028     void recovery();
01029 
01038     bool checkVersion();
01039 
01045     oid_t allocateObject(dbInternalObject marker) {
01046         oid_t oid = allocateId();
01047         offs_t pos = allocate(internalObjectSize[marker]) + marker;
01048         currIndex[oid] = pos;
01049         return oid;
01050     }
01051 
01058     oid_t allocateRow(oid_t tableId, size_t size)
01059     {
01060         oid_t oid = allocateId();
01061         allocateRow(tableId, oid, size);
01062         return oid;
01063     }
01064     
01072     void allocateRow(oid_t tableId, oid_t oid, size_t size);
01073 
01079     void freeRow(oid_t tableId, oid_t oid);
01080 
01084     void freeObject(oid_t oid); 
01085     
01089     static void deleteCompiledQuery(dbExprNode* tree); 
01090 
01097     enum dbLockType { 
01098         dbSharedLock, 
01099         dbExclusiveLock,
01100         dbCommitLock
01101     };
01102 
01103     bool beginTransaction(dbLockType);
01104 
01108     void endTransaction() { 
01109         endTransaction(threadContext.get());
01110     }
01111     
01116     void endTransaction(dbDatabaseThreadContext* ctx);
01117 
01122     void initializeMetaTable();
01123     
01131     bool loadScheme(bool alter);
01132 
01138     bool completeDescriptorsInitialization();
01139 
01145     void reformatTable(oid_t tableId, dbTableDescriptor* desc);
01146 
01154     bool addIndices(bool alter, dbTableDescriptor* desc);
01155 
01161     oid_t addNewTable(dbTableDescriptor* desc);
01162 
01168     void updateTableDescriptor(dbTableDescriptor* desc, oid_t tableId);
01169 
01178     void insertInverseReference(dbFieldDescriptor* fd, 
01179                                 oid_t reverseId, oid_t targetId);
01180 
01186     void removeInverseReferences(dbTableDescriptor* desc, oid_t oid);
01187 
01196     void removeInverseReference(dbFieldDescriptor* fd, 
01197                                 oid_t reverseId, oid_t targetId);
01198 
01203     void deleteTable(dbTableDescriptor* desc);
01204 
01209     void dropTable(dbTableDescriptor* desc);
01210 
01215     void createIndex(dbFieldDescriptor* fd);
01216 
01221     void createHashTable(dbFieldDescriptor* fd);
01222 
01227     void dropIndex(dbFieldDescriptor* fd);
01228 
01233     void dropHashTable(dbFieldDescriptor* fd);
01234 
01240     void linkTable(dbTableDescriptor* table, oid_t tableId);
01241 
01246     void unlinkTable(dbTableDescriptor* table);
01247 
01254     bool wasReserved(offs_t pos, size_t size);
01255 
01264     void reserveLocation(dbLocation& location, offs_t pos, size_t size);
01265 
01270     void commitLocation();
01271 
01277     dbTableDescriptor* findTable(char const* name);
01278     
01285     dbTableDescriptor* findTableByName(char const* name);
01286 
01291     dbTableDescriptor* getTables() { 
01292         return tables;
01293     }
01294 
01298     void setDirty();
01299 };
01300 
01301 
01302 #ifdef REPLICATION_SUPPORT
01303 
01304 #include "sockio.h"
01305 
01306 class FASTDB_DLL_ENTRY dbConnection { 
01307  public:
01308     socket_t*    reqSock;
01309     socket_t*    respSock;
01310     dbLocalEvent statusEvent;
01311     dbLocalEvent readyEvent;
01312     dbLocalEvent useEvent;
01313     dbMutex      writeCS;
01314     int          useCount;
01315     int          waitUseEventFlag;
01316     int          waitStatusEventFlag;
01317     int          status;
01318     int          updateCounter;
01319 
01320     dbConnection() { 
01321         readyEvent.open();
01322         useEvent.open();
01323         statusEvent.open();
01324         useCount = 0;
01325         waitUseEventFlag = 0;
01326         waitStatusEventFlag = 0;
01327         status = 0;
01328         reqSock = respSock = NULL;
01329     }
01330     ~dbConnection() { 
01331         readyEvent.close();
01332         useEvent.close();
01333         statusEvent.close();
01334         delete reqSock;
01335         delete respSock;
01336     }
01337 }; 
01338 
01339 class FASTDB_DLL_ENTRY dbReplicatedDatabase : public dbDatabase {
01340     friend class dbFile;
01341   protected:
01342     char**        serverURL;
01343     int           nServers;
01344     int           id;
01345     dbConnection* con;
01346 
01347     enum NodeStatus { 
01348         ST_OFFLINE,  // node is not available 
01349         ST_ONLINE,   // node is available 
01350         ST_ACTIVE,   // primary node is running, replicating changes
01351         ST_STANDBY,  // standby node receives changes from primary node
01352         ST_RECOVERED // node is recovered after the fault
01353     };
01354     
01355     dbLocalEvent  startEvent;
01356     dbLocalEvent  recoveredEvent;
01357     dbMutex       startCS;
01358     fd_set        inputSD;
01359     int           nInputSD;
01360 
01361     int           activeNodeId;
01362     dbMutex       sockCS;
01363     socket_t*     acceptSock;
01364     dbThread      readerThread;
01365 
01366     static void thread_proc startReader(void* arg);
01367 
01368     void reader();
01369     virtual bool isReplicated();
01370 
01371   public:
01372     void deleteConnection(int nodeId);
01373     void lockConnection(int nodeId);
01374     void unlockConnection(int nodeId);
01375     void changeActiveNode();
01376     void addConnection(int nodeId, socket_t* s);
01377     bool writeReq(int nodeId, ReplicationRequest const& hdr, 
01378                   void* body = NULL, size_t bodySize = 0);
01379     bool writeResp(int nodeId, ReplicationRequest const& hdr);
01380 
01381     bool open(char const* databaseName, char const* fileName,
01382               int id, char* servers[], int nServers);
01383     virtual void close();
01384 
01385     int getNumberOfOnlineNodes();
01386 
01387     static int dbPollInterval;
01388     static int dbWaitReadyTimeout;
01389     static int dbWaitStatusTimeout;
01390     static int dbRecoveryConnectionAttempts;
01391     static int dbStartupConnectionAttempts;
01392 
01393     dbReplicatedDatabase(dbAccessType type = dbAllAccess,
01394                          size_t dbInitSize = dbDefaultInitDatabaseSize,
01395                          size_t dbExtensionQuantum = dbDefaultExtensionQuantum,
01396                          size_t dbInitIndexSize = dbDefaultInitIndexSize,
01397                          int nThreads = 1)
01398         : dbDatabase(type, dbInitSize, dbExtensionQuantum, dbInitIndexSize, nThreads)
01399     {}
01400 };
01401 #endif
01402 
01403 template<class T>
01404 dbReference<T> insert(T const& record) { 
01405     dbReference<T> ref;
01406     T::dbDescriptor.getDatabase()->insertRecord(&T::dbDescriptor, &ref, &record);
01407     return ref;
01408 }
01409 
01410 #ifdef NO_MEMBER_TEMPLATES
01411 template<class T>
01412 dbReference<T> insert(dbDatabase& db, T const& record) {
01413     dbReference<T> ref;
01414     db.insertRecord(db.lookupTable(&T::dbDescriptor), &ref, &record);
01415     return ref;
01416 }
01417 #endif
01418 
01422 class dbSearchContext { 
01423   public:
01424     dbDatabase*     db;
01425     dbExprNode*     condition;
01426     dbAnyCursor*    cursor;
01427     char*           firstKey;
01428     int             firstKeyInclusion;
01429     char*           lastKey;
01430     int             lastKeyInclusion;
01431     int             type;
01432     int             sizeofType;
01433     int             prefixLength;
01434     dbUDTComparator comparator;
01435     int             offs;
01436     int             probes;
01437 };
01438 
01439 
01440 END_FASTDB_NAMESPACE
01441 
01442 #endif

Generated on Mon Oct 23 13:23:58 2006 for FastDB by doxygen1.2.18