00001
00002
00003
00004
00005
00006
00007
00008
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
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
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;
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;
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;
00099 int4 curr;
00100 int4 dirty;
00101 int4 initialized;
00102 int4 pad;
00103 struct {
00104 offs_t index;
00105 offs_t shadowIndex;
00106 oid_t indexSize;
00107 oid_t shadowIndexSize;
00108 oid_t indexUsed;
00109 oid_t freeList;
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;
00163
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;
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
00594
00595
00596
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;
00621 dbHeader* header;
00622 offs_t* currIndex;
00623 offs_t* index[2];
00624 unsigned parThreads;
00625 bool modified;
00626
00627 size_t currRBitmapPage;
00628 size_t currRBitmapOffs;
00629
00630 size_t currPBitmapPage;
00631 size_t currPBitmapOffs;
00632
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,
01349 ST_ONLINE,
01350 ST_ACTIVE,
01351 ST_STANDBY,
01352 ST_RECOVERED
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