• Main Page
  • Classes
  • Files
  • File List

database.h

00001 //-< DATABASE.H >----------------------------------------------------*--------*
00002 // GigaBASE                  Version 1.0         (c) 1999  GARRET    *     ?  *
00003 // (Post Relational Database Management System)                      *   /\|  *
00004 //                                                                   *  /  \  *
00005 //                          Created:     20-Nov-98    K.A. Knizhnik  * / [] \ *
00006 //                          Last update: 14-Feb-99    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 #include "pagepool.h"
00018 
00019 BEGIN_GIGABASE_NAMESPACE
00020 
00021 #if defined(_WINCE) || defined(__SYMBIAN32__)
00022 
00025 const size_t dbDefaultInitIndexSize = 10*1024; // typical nr. of objects in db
00026 
00030 const size_t dbDefaultExtensionQuantum = 1*512*1024;  // alloc per half meg.
00031 
00032 const size_t dbAllocationQuantumBits = 5;
00033 const size_t dbPageBits = 12;
00034 #else
00035 
00038 const size_t dbDefaultInitIndexSize = 512*1024;
00039 
00043 const size_t dbDefaultExtensionQuantum = 4*1024*1024;
00044 const size_t dbAllocationQuantumBits = 6;
00045 const size_t dbPageBits = 13;
00046 #endif
00047 
00051 const unsigned dbMaxParallelSearchThreads = 64;
00052 
00056 enum dbHandleFlags {
00057     dbPageObjectFlag = 0x1,
00058     dbModifiedFlag   = 0x2,
00059     dbFreeHandleFlag = 0x4,
00060     dbFlagsMask      = 0x7,
00061     dbFlagsBits      = 3
00062 };
00063 
00064 const size_t dbAllocationQuantum = 1 << dbAllocationQuantumBits;
00065 const size_t dbPageSize = 1 << dbPageBits;
00066 const size_t dbIdsPerPage = dbPageSize / sizeof(oid_t);
00067 const size_t dbHandlesPerPage = dbPageSize / sizeof(offs_t);
00068 const size_t dbHandleBits = 1 + sizeof(offs_t)/4; // log(sizeof(offs_t))
00069 const size_t dbBitmapSegmentBits = dbPageBits + 3 + dbAllocationQuantumBits;
00070 const size_t dbBitmapSegmentSize = 1 << dbBitmapSegmentBits;
00071 const size_t dbBitmapPages = 1 << (dbDatabaseOffsetBits-dbBitmapSegmentBits);
00072 const size_t dbDirtyPageBitmapSize = 1 << (dbDatabaseOidBits-dbPageBits+dbHandleBits-3);
00073 const size_t dbDefaultSelectionLimit = 2000000000;
00078 const int    dbBMsearchThreshold = 512;
00082 const size_t dbIndexedMergeThreshold = 100;
00083 
00084 
00085 const char_t dbMatchAnyOneChar = '_'; 
00086 const char_t dbMatchAnySubstring = '%';
00087 
00088 const int    dbMaxFileSegments = 64;
00089 const int    dbTableHashSize = 1009;   
00090 
00094 enum dbPredefinedIds {
00095     dbInvalidId,
00096     dbMetaTableId,
00097     dbBitmapId,
00098     dbFirstUserId = dbBitmapId + dbBitmapPages
00099 };
00100 
00104 enum dbLockType { 
00105     dbNoLock,
00106     dbSharedLock,
00107     dbUpdateLock,
00108     dbExclusiveLock
00109 };
00110 
00114 class dbHeader {
00115   public:
00116     int4   curr;  // current root
00117     int4   dirty; // database was not closed normally
00118     int4   initialized; // database is initiliazed
00119 #if dbDatabaseOffsetBits > 32 && defined(ALIGN_HEADER)
00120     int4   pad1;
00121 #endif
00122     struct {
00123         offs_t size;            // database file size
00124         offs_t index;           // offset to object index
00125         offs_t shadowIndex;     // offset to shadow index
00126 #if dbDatabaseOffsetBits > 32 && dbDatabaseOidBits <= 32 && defined(ALIGN_HEADER)
00127         oid_t  pad2;
00128 #endif
00129         oid_t  indexSize;       // size of object index
00130         oid_t  shadowIndexSize; // size of object index
00131         oid_t  indexUsed;       // used part of the index
00132         oid_t  freeList;        // L1 list of free object identifiers
00133         oid_t  bitmapEnd;       // index of last allocated bitmap page
00134 #ifdef DO_NOT_REUSE_OID_WITHIN_SESSION
00135         struct {
00136             oid_t head;
00137             oid_t tail;
00138         } sessionFreeList;  // L1 list of object identifiers deallocated within this session
00139 #endif
00140     } root[2];
00141 
00142     int4       versionMajor;
00143     int4       versionMinor;
00144     int4       transactionId; // used for multiclient access 
00145     int4       mode;
00146 
00147     enum { 
00148         MODE_ALIGN_HEADER  = 0x01,
00149         MODE_OID_64        = 0x02,
00150         MODE_OFFS_64       = 0x04,
00151         MODE_UNICODE       = 0x08,
00152         MODE_AUTOINCREMENT = 0x10,
00153         MODE_RECTANGLE_DIM = 0x20,
00154         MODE_DO_NOT_REUSE_OID = 0x40
00155     };        
00156 
00157     int getVersion() { 
00158         return versionMajor*100 + versionMinor;
00159     }
00160 
00161     bool isCompatible();
00162     static int getCurrentMode();
00163 
00164     bool isInitialized() {
00165         return initialized == 1
00166             && (dirty == 1 || dirty == 0)
00167             && (curr == 1 || curr == 0)
00168             && root[curr].size > root[curr].index
00169             && root[curr].size > root[curr].shadowIndex
00170             && root[curr].size > root[curr].indexSize*sizeof(offs_t)
00171                                + root[curr].shadowIndexSize*sizeof(offs_t)
00172             && root[curr].indexSize >= root[curr].indexUsed
00173             && root[curr].indexUsed >= dbFirstUserId
00174             && root[curr].bitmapEnd > dbBitmapId;
00175     }
00176 };
00177 
00178 class dbSynthesizedAttribute;
00179 class dbInheritedAttribute;
00180 class dbDatabaseThreadContext;
00181 class dbSession;
00182 
00183 struct dbMemoryStatistic { 
00184     offs_t used;
00185     offs_t free;
00186     offs_t nHoles;
00187     offs_t minHoleSize;
00188     offs_t maxHoleSize;
00189     size_t nHolesOfSize[dbDatabaseOffsetBits];
00190 };
00191 
00192 class dbMonitor {
00193   public:
00194     dbLockType accLock; 
00195 
00196     dbDatabaseThreadContext* firstPending;
00197     dbDatabaseThreadContext* lastPending;
00198 
00199     int        nLockUpgrades;
00200 
00201     int        nReaders;
00202     int        nWriters;
00203     int        backupInProgress;
00204 
00205     void wait(dbLockType type, dbMutex& mutex, dbDatabaseThreadContext* ctx);
00206 
00207     dbMonitor() { 
00208         firstPending = lastPending = NULL;
00209         accLock = dbNoLock;
00210         backupInProgress = 0;
00211         nReaders = nWriters = 0;
00212         nLockUpgrades = 0;
00213     }
00214 };
00215 
00216 
00217 
00218 class dbAnyCursor;
00219 class dbQuery;
00220 class dbExprNode;
00221 class dbSearchContext;
00222 class dbXmlContext;
00223 class dbXmlScanner;
00224 
00225 
00226 class dbVisitedObject {
00227   public: 
00228     dbVisitedObject* next;
00229     oid_t            oid;
00230 
00231     dbVisitedObject(oid_t oid, dbVisitedObject* chain) {         
00232         this->oid = oid;
00233         next = chain;
00234     }
00235 };    
00236 
00240 class dbTransactionLogger 
00241 {
00242   public:
00251     virtual bool insert(dbTableDescriptor* table, oid_t oid, dbRecord const* dbsObj, void const* appObj) = 0;
00252 
00261     virtual bool update(dbTableDescriptor* table, oid_t oid, dbRecord const* dbsObj, void const* appObj) = 0;
00262 
00269     virtual bool remove(dbTableDescriptor* table, oid_t oid) = 0;
00270 
00275     virtual bool commitPhase1() = 0;
00276 
00280     virtual void commitPhase2() = 0;
00281 
00285     virtual void rollback() = 0;
00286 };
00287 
00291 class dbFileTransactionLogger : public dbTransactionLogger
00292 {
00293     dbOSFile log;
00294     char*    buf;
00295     size_t   used;
00296     size_t   allocated;
00297     bool     crc;
00298 
00302     enum OperationKind {
00303         opInsert, 
00304         opUpdate,
00305         opRemove
00306     };
00307     void append(OperationKind kind, dbTableDescriptor* table, oid_t oid, dbRecord const* body);
00308     char* extend(size_t size);
00309 
00310   public:
00311     virtual bool insert(dbTableDescriptor* table, oid_t oid, dbRecord const* dbsObj, void const* appObj);
00312     virtual bool update(dbTableDescriptor* table, oid_t oid, dbRecord const* dbsObj, void const* appObj);
00313     virtual bool remove(dbTableDescriptor* table, oid_t oid);
00314 
00315     virtual bool commitPhase1();
00316     virtual void commitPhase2();
00317     virtual void rollback();
00318 
00319     dbFileTransactionLogger();
00320     virtual~dbFileTransactionLogger();
00321     
00322 
00329     bool open(char_t const* path, int flags = dbFile::no_sync, bool crc = true);
00330     
00334     void close();
00335     
00336     enum RestoreStatus
00337     {
00338         rsOK,
00339         rsCRCMismatch,
00340         rsReadFailed,
00341         rsTableNotFound,
00342         rsOIDMismatch
00343     };
00344 
00351     RestoreStatus restore(dbDatabase& db, size_t& nTrans);
00352 };
00353 
00357 class GIGABASE_DLL_ENTRY dbDatabase 
00358 {
00359     friend class dbSession;
00360     friend class dbSelection;
00361     friend class dbAnyCursor;
00362     friend class dbHashTable;
00363     friend class dbQuery;
00364     friend class dbRtree;
00365     friend class dbRtreePage;
00366     friend class dbBtree;
00367     friend class dbBtreePage;
00368     friend class dbThickBtreePage;
00369     friend class dbInheritedAttribute;
00370     friend class dbParallelQueryContext;
00371     friend class dbServer;
00372     friend class dbPagePool;
00373 
00374     friend class dbBlob;
00375     friend class dbBlobIterator;
00376     friend class dbBlobReadIterator;
00377     friend class dbBlobWriteIterator;
00378     friend class dbAnyContainer;
00379 
00380     friend class dbGetTie;
00381     friend class dbPutTie;
00382 
00383     friend class dbFileTransactionLogger;
00384 
00385     friend class dbUserFunctionArgument;
00386 
00387     friend class dbCLI;
00388     friend class GiSTdb;
00389 
00390     friend class dbBtreeIterator;
00391     friend class dbRtreeIterator;
00392     friend class dbTableIterator;
00393   public:
00401     bool open(char_t const* databaseName, time_t transactionCommitDelay = 0, int openAttr = 0);
00402 
00410     bool open(dbFile* file, time_t transactionCommitDelay = 0, bool deleteFileOnClose = false);
00411 
00412     enum dbAccessType {
00413         dbReadOnly,
00414         dbAllAccess,
00415         dbMulticlientReadOnly, 
00416         dbMulticlientReadWrite
00417     };
00418 
00422     struct OpenParameters { 
00426         char_t const* databaseName;
00427 
00431         int openAttr;
00432 
00436         dbFile* file;
00437 
00441         time_t  transactionCommitDelay;
00442  
00446         bool deleteFileOnClose;
00447         
00457         bool doNotReuseOidAfterClose;
00458 
00464         bool preserveExistedIndices;
00465 
00469         dbAccessType accessType;
00470 
00477         size_t poolSize;
00478         
00482         size_t extensionQuantum;
00483 
00487         size_t initIndexSize;
00488 
00492         int nThreads;
00493  
00494 
00499         offs_t freeSpaceReuseThreshold;
00500 
00501         OpenParameters() { 
00502             databaseName = NULL;
00503             openAttr = 0;
00504             file = NULL;
00505             transactionCommitDelay = 0;
00506             deleteFileOnClose = false;
00507             accessType = dbAllAccess;
00508             poolSize = 0;
00509             extensionQuantum = dbDefaultExtensionQuantum;
00510             initIndexSize = dbDefaultInitIndexSize;
00511             nThreads = 1;
00512             freeSpaceReuseThreshold = dbDefaultExtensionQuantum;
00513             doNotReuseOidAfterClose = false;
00514             preserveExistedIndices = false;
00515         }
00516     };
00517 
00518 
00524     bool open(OpenParameters& params);
00525 
00526 
00530     virtual void close();
00531 
00535     void commit();
00536 
00540     void executeBatch();
00541 
00546     void precommit();
00547     
00551     void rollback();
00552     
00557     void attach();
00558 
00564     void attach(dbDatabaseThreadContext* ctx);
00565     
00566     enum DetachFlags { 
00567         COMMIT          = 1,
00568         DESTROY_CONTEXT = 2
00569     };
00574     void detach(int flags = COMMIT|DESTROY_CONTEXT);
00575     
00580     void lock(dbLockType type = dbExclusiveLock) { beginTransaction(type); }
00581 
00582     enum BackupFlags 
00583     {
00584         BCK_COMPACTIFY  = 1, /* all used objects will be placed together without holes */
00585         BCK_INCREMENTAL = 2, /* do no lock database (not compatible with BCK_COMPACTIFY) */
00586         BCK_HOLD_LOCK   = 4  /* do not release lock after incremental backup completion */
00587     };
00588 
00595     bool backup(char_t const* backupFileName, int flags = 0);
00596 
00604     bool backup(dbOSFile* file, int flags = 0);
00605 
00612     bool restore(char_t const* backupFileName, char_t const* databaseFileName);
00613 
00617     int  getVersion();
00618 
00623     void assign(dbTableDescriptor& desc) {
00624         assert(((void)"Table is not yet assigned to the database",
00625                 desc.tableId == 0));
00626         desc.db = this;
00627         desc.fixedDatabase = true;
00628     }
00629 
00636     dbTableDescriptor* lookupTable(dbTableDescriptor* desc);
00637 
00642     void getMemoryStatistic(dbMemoryStatistic& stat);
00643 
00651     void setConcurrency(unsigned nThreads);
00652 
00657     soffs_t getAllocatedSize() { return allocatedSize; }
00658 
00666     void allowColumnsDeletion(bool enabled = true) { 
00667         confirmDeleteColumns = enabled;
00668     }
00669 
00674     void enableInverseReferencesUpdate(bool enabled = true) { 
00675         inverseReferencesUpdate = enabled;
00676     }
00677 
00681     void disableOidReuseOnClose(bool disabled = true) {
00682         doNotReuseOidAfterClose = disabled;
00683     }
00684 
00685 
00693     bool prepareQuery(dbAnyCursor* cursor, dbQuery& query);
00694 
00698     enum dbErrorClass {
00699         NoError, 
00700         QueryError,
00701         ArithmeticError,
00702         IndexOutOfRangeError,
00703         DatabaseOpenError,
00704         FileError,
00705         OutOfMemoryError,
00706         Deadlock,
00707         NullReferenceError,
00708         FileLimitExeeded,
00709         DatabaseReadOnly,
00710         UniqueConstraintViolation,
00711         InconsistentInverseReference,  
00712         OperationNotSupported,
00713         SocketError,
00714         CursorError,       
00715         AccessToDeletedObject,
00716         IncompatibleSchemaChange,
00717         RejectedByTransactionLogger        
00718     };
00719     static char const* const errorMessage[];
00720     typedef void (*dbErrorHandler)(int error, char const* msg, int msgarg, void* context); 
00721 
00728     dbErrorHandler setErrorHandler(dbErrorHandler newHandler, void* errorHandlerContext = NULL);        
00729 
00735     void setTransactionLogger(dbTransactionLogger* logger);
00736 
00743     virtual void scheduleBackup(char_t const* fileName, time_t periodSec);
00744 
00745 
00753     virtual void handleError(dbErrorClass error, char const* msg = NULL,
00754                              int arg = 0);
00755 
00756     dbAccessType accessType;
00757     size_t extensionQuantum;
00758     size_t initIndexSize;
00759     offs_t freeSpaceReuseThreshold;
00760 
00761     static unsigned dbParallelScanThreshold;
00762     dbTableDescriptor* tableHash[dbTableHashSize];
00763 
00774     bool insertRecord(dbTableDescriptor* table, dbAnyReference* ref,
00775                       void const* record, bool batch);
00780     offs_t used();
00781 
00785     bool isOpen() const { return opened; }
00786 
00793     offs_t getDatabaseSize() { 
00794         return header->root[1-curr].size;
00795     }
00796 
00803     void setFileExtensionQuantum(offs_t quantum) { 
00804         dbFileExtensionQuantum = quantum;
00805     }
00806 
00811     void setFileSizeLimit(offs_t limit) { 
00812         dbFileSizeLimit = limit;
00813     }
00814 
00826     void createCluster(offs_t size);
00827 
00828 
00829 #ifndef NO_MEMBER_TEMPLATES
00830 
00836     template<class T>
00837     dbReference<T> insert(T const& record) {
00838         dbReference<T> ref;
00839         insertRecord(lookupTable(&T::dbDescriptor), &ref, &record, false);
00840         return ref;
00841     }
00848     template<class T>
00849     dbReference<T> batchInsert(T const& record) {
00850         dbReference<T> ref;
00851         insertRecord(lookupTable(&T::dbDescriptor), &ref, &record, true);
00852         return ref;
00853     }
00854 #endif
00855 
00861     bool isValidOid(oid_t oid) { 
00862         if (oid < dbFirstUserId || oid >= currIndexSize) {
00863             return false;
00864         }
00865         offs_t pos = getPos(oid);
00866         return !(pos & (dbFreeHandleFlag|dbPageObjectFlag));
00867     }
00868 
00870     enum SelectionMethod {
00871         sel_all,            //< just export all tables. Default
00872         sel_all_except,     //< '-' Export all tables except the named tables
00873         sel_named_only      //< '+' Only export explicitly named tables.
00874     };
00875 
00883     void exportDatabaseToXml(FILE* out, char_t const* const* tables, size_t nTables, SelectionMethod method);
00884 
00894     void exportDatabaseToXml(FILE* out, char_t const* const* tables, size_t nTables, SelectionMethod method, char_t const* encoding);
00895 
00901     bool importDatabaseFromXml(FILE* in);
00902 
00903 #ifdef PROFILE
00904 
00908     static void profile(char const* file);
00909 
00914     static void profile(FILE* file);
00915 #endif
00916 
00929     dbDatabase(dbAccessType type = dbAllAccess,
00930                size_t poolSize = 0, // autodetect size of available memory
00931                size_t dbExtensionQuantum = dbDefaultExtensionQuantum,
00932                size_t dbInitIndexSize = dbDefaultInitIndexSize,
00933                int nThreads = 1
00934                // Do not specify the last parameter - it is only for checking
00935                // that application and GigaBASE library were built with the
00936                // same compiler options (-DNO_PTHREADS is critical)
00937                // Mismached parameters should cause linker error
00938 #ifdef NO_PTHREADS
00939                , bool usePthreads = false
00940 #endif
00941                );
00942 
00946     virtual ~dbDatabase();
00947 
00954     dbTableDescriptor* findTableByName(char_t const* name);
00955 
00961     dbTableDescriptor* findTableByID(oid_t id);
00962     
00967     dbTableDescriptor* getTables() { 
00968         return tables;
00969     }
00970 
00971   protected:
00972     dbThreadContext<dbDatabaseThreadContext> threadContext;
00973 
00974     dbThreadPool threadPool;
00975 
00976     dbHeader* header;           // database header information
00977     int4*     dirtyPagesMap;    // bitmap of changed pages in current index
00978     unsigned  parThreads;
00979     bool      modified;
00980     
00981     int       curr;             // copy of header->root, used to allow read access to the database 
00982                                 // during transaction commit
00983 
00984     int       transactionId;
00985 
00986     bool      uncommittedChanges; 
00987 
00988     offs_t    dbFileExtensionQuantum; 
00989     offs_t    dbFileSizeLimit;
00990 
00991 
00992     volatile int commitInProgress;
00993     volatile int concurrentTransId;
00994 
00995     oid_t     currRBitmapPage;  //current bitmap page for allocating records
00996     size_t    currRBitmapOffs;  //offset in current bitmap page for allocating
00997                                 //unaligned records
00998     oid_t     currPBitmapPage;  //current bitmap page for allocating page objects
00999     size_t    currPBitmapOffs;  //offset in current bitmap page for allocating
01000                                 //page objects
01001 
01002     struct dbLocation { 
01003         offs_t      pos;
01004         offs_t      size;
01005         dbLocation* next;
01006     };
01007     dbLocation* reservedChain;
01008     
01009     oid_t     committedIndexSize;
01010     oid_t     currIndexSize;
01011 
01012     oid_t     updatedRecordId;
01013 
01014     dbFile*                   file;
01015     dbMutex                   mutex;
01016     dbSemaphore               writeSem;
01017     dbSemaphore               readSem;
01018     dbSemaphore               upgradeSem;
01019     dbEvent                   backupCompletedEvent;
01020     dbMonitor                 monitor;
01021     dbPagePool                pool;
01022     dbTableDescriptor*        tables;
01023 
01024     int*                      bitmapPageAvailableSpace;
01025     bool                      opened;
01026 
01027     soffs_t                   allocatedSize;
01028     offs_t                    deallocatedSize;
01029 
01030     int                       forceCommitCount;
01031     time_t                    commitDelay;     
01032     time_t                    commitTimeout;
01033     time_t                    commitTimerStarted;
01034     
01035     dbMutex                   commitThreadSyncMutex;
01036     dbMutex                   delayedCommitStartTimerMutex;
01037     dbMutex                   delayedCommitStopTimerMutex;
01038     dbEvent                   commitThreadSyncEvent;   
01039     // object used to notify delayed commit thread to schdule delayed commit
01040     dbEvent                   delayedCommitStartTimerEvent; 
01041     // object used by delaued commit thread to wait for sepcified timeout
01042     dbEvent                   delayedCommitStopTimerEvent; 
01043     dbDatabaseThreadContext*  delayedCommitContext;     // save context of delayed transaction
01044 
01045     dbMutex                   backupMutex;    
01046     dbEvent                   backupInitEvent;
01047     char_t*                   backupFileName;
01048     time_t                    backupPeriod;
01049 
01050     dbThread                  backupThread;
01051     dbThread                  commitThread;
01052 
01053     dbTableDescriptor*        batchList;
01054 
01055     int                       accessCount;
01056 
01057     dbL2List                  threadContextList;
01058     dbMutex                   threadContextListMutex;
01059 
01060     dbErrorHandler            errorHandler;
01061     void*                     errorHandlerContext;
01062 
01063     dbTransactionLogger*      logger;
01064 
01065     bool                      confirmDeleteColumns;
01066     bool                      inverseReferencesUpdate;
01067 
01068     int                       schemeVersion;
01069     dbVisitedObject*          visitedChain;
01070 
01071     int*                      btreeBuf;            
01072     bool                      deleteFile;
01073     bool                      doNotReuseOidAfterClose;
01074     bool                      preserveExistedIndices;
01075     dbXmlContext*             xmlContext;
01076 
01077     int*                      dirtyPageBitmap;
01078     size_t                    dirtyPageBitmapSize;
01079 
01080     oid_t mapId(long id);
01081     bool importField(char_t* terminator, dbFieldDescriptor* fd, byte* rec, dbXmlScanner& scanner);
01082     bool importRecord(char_t* terminator, dbFieldDescriptor* fieldList, byte* rec, dbXmlScanner& scanner);
01083     bool insertRecord(dbTableDescriptor* desc, oid_t oid, void const* record);
01084 
01085 
01091     dbTableDescriptor* loadMetaTable();
01092 
01093     void releaseFile();
01094 
01098     virtual void replicatePage(offs_t pageOffs, void* pageData);
01099 
01103     void delayedCommit();
01104 
01108     void backupScheduler();
01109 
01110     static void thread_proc delayedCommitProc(void* arg) { 
01111         ((dbDatabase*)arg)->delayedCommit();
01112     }
01113 
01114     static void thread_proc backupSchedulerProc(void* arg) { 
01115         ((dbDatabase*)arg)->backupScheduler();
01116     }
01117 
01122     void commit(dbDatabaseThreadContext* ctx);
01123 
01129     offs_t getPos(oid_t oid) {
01130         byte* p = pool.get(header->root[1-curr].index
01131                            + (offs_t)(oid / dbHandlesPerPage) * dbPageSize);
01132         offs_t pos = *((offs_t*)p + oid % dbHandlesPerPage);
01133         pool.unfix(p);
01134         return pos;
01135     }
01136 
01142     void setPos(oid_t oid, offs_t pos) {
01143         byte* p = pool.put(header->root[1-curr].index
01144                            + (offs_t)(oid / dbHandlesPerPage) * dbPageSize);
01145         *((offs_t*)p + oid % dbHandlesPerPage) = pos;
01146         pool.unfix(p);
01147     }
01148 
01155     dbRecord* getRow(dbGetTie& tie, oid_t oid) {
01156         offs_t pos = getPos(oid);
01157         if (pos & (dbFreeHandleFlag|dbPageObjectFlag)) { 
01158             handleError(dbDatabase::AccessToDeletedObject);
01159         }            
01160         tie.set(pool, pos & ~dbFlagsMask);
01161         return (dbRecord*)tie.get();
01162     }
01163 
01171     dbRecord* getRow(dbGetTie& tie, oid_t oid, size_t size) {
01172         offs_t pos = getPos(oid);
01173         if (pos & (dbFreeHandleFlag|dbPageObjectFlag)) { 
01174             handleError(dbDatabase::AccessToDeletedObject);
01175         }            
01176         tie.set(pool, pos & ~dbFlagsMask, size);
01177         return (dbRecord*)tie.get();
01178     }
01179 
01186     dbRecord* fetchRow(dbGetTie& tie, oid_t oid) {
01187         offs_t pos = getPos(oid);
01188         if (pos & (dbFreeHandleFlag|dbPageObjectFlag)) { 
01189             handleError(dbDatabase::AccessToDeletedObject);
01190         }            
01191         tie.fetch(pool, pos & ~dbFlagsMask);
01192         return (dbRecord*)tie.get();
01193     }
01194 
01200     void getHeader(dbRecord& rec, oid_t oid) {
01201         offs_t pos = getPos(oid);
01202         int offs = (int)pos & (dbPageSize-1);
01203         byte* p = pool.get(pos - offs);
01204         rec = *(dbRecord*)(p + (offs & ~dbFlagsMask));
01205         pool.unfix(p);
01206     }
01207 
01213     byte* put(oid_t oid) {
01214         offs_t pos = getPos(oid);
01215         int offs = (int)pos & (dbPageSize-1);
01216         return pool.put(pos-offs) + (offs & ~dbFlagsMask);
01217     }
01218 
01224     byte* get(oid_t oid) {
01225         offs_t pos = getPos(oid);
01226         int offs = (int)pos & (dbPageSize-1);
01227         return pool.get(pos-offs) + (offs & ~dbFlagsMask);
01228     }
01229 
01237     dbRecord* putRow(dbPutTie& tie, oid_t oid, size_t newSize);
01238 
01245     dbRecord* putRow(dbPutTie& tie, oid_t oid);
01246     
01253     byte* put(dbPutTie& tie, oid_t oid);
01254 
01259     void restoreTablesConsistency();
01260 
01266     void applyIndex(dbFieldDescriptor* field, dbSearchContext& sc);
01267     
01275     bool isIndicesApplicable(dbAnyCursor* cursor, dbExprNode* expr, bool& unique);
01276 
01292     bool applyIndices(dbAnyCursor* cursor, dbExprNode* expr, dbExprNode* topExpr, dbExprNode* filter,
01293                       dbQuery& query, dbFieldDescriptor* &indexedField, bool& truncate, bool ascent);
01294 
01302     bool isIndexApplicableToExpr(dbSearchContext& sc, dbExprNode* expr);
01303 
01307     bool followInverseReference(dbExprNode* expr, dbExprNode* andExpr,
01308                                 dbAnyCursor* cursor, oid_t iref);
01309 
01317     bool existsInverseReference(dbExprNode* expr, int nExistsClauses);
01318 
01324     bool existsIndexedReference(dbExprNode* expr);
01325 
01332     static void _fastcall execute(dbExprNode* expr,
01333                                   dbInheritedAttribute& iattr,
01334                                   dbSynthesizedAttribute& sattr);
01343     bool   evaluateBoolean(dbExprNode* expr, oid_t oid, dbTableDescriptor* table, dbAnyCursor* cursor);
01344     
01354     size_t evaluateString(dbExprNode* expr, oid_t oid, dbTableDescriptor* table, char_t* buf, size_t bufSize);
01355 
01363     void   evaluate(dbExprNode* expr, oid_t oid, dbTableDescriptor* table, dbSynthesizedAttribute& result);
01364 
01369     void select(dbAnyCursor* cursor);
01370 
01376     void select(dbAnyCursor* cursor, dbQuery& query);
01377 
01383     void traverse(dbAnyCursor* cursor, dbQuery& query);
01384 
01393     bool update(oid_t oid, dbTableDescriptor* table, void const* record);
01394     
01400     void remove(dbTableDescriptor* table, oid_t oid);
01401 
01409     offs_t allocate(offs_t size, oid_t oid = 0);
01410 
01416     void free(offs_t pos, offs_t size);
01417 
01422     void extend(offs_t size);
01423 
01430     void cloneBitmap(offs_t pos, offs_t size);
01431 
01436     oid_t allocateId();
01437     
01442     void freeId(oid_t oid);
01443 
01450     void updateCursors(oid_t oid, bool removed = false);
01451 
01456     oid_t allocatePage() {
01457         oid_t oid = allocateId();
01458         setPos(oid, allocate(dbPageSize) | dbPageObjectFlag | dbModifiedFlag);
01459         return oid;
01460     }
01461     
01466     void freePage(oid_t oid);
01467 
01475     oid_t allocateRow(oid_t tableId, size_t size,
01476                       dbTableDescriptor* desc = NULL)
01477     {
01478         oid_t oid = allocateId();
01479         allocateRow(tableId, oid, size, desc);
01480         return oid;
01481     }
01482     
01491     void allocateRow(oid_t tableId, oid_t oid, size_t size, dbTableDescriptor* desc);
01492     
01499     void freeRow(oid_t tableId, oid_t oid, dbTableDescriptor* desc = NULL);
01500 
01505     static void deleteCompiledQuery(dbExprNode* tree);
01506 
01511     void beginTransaction(dbLockType type);
01516     void endTransaction(dbDatabaseThreadContext* ctx);
01517 
01521     void initializeMetaTable();
01522     
01529     bool loadScheme();
01530 
01536     bool completeDescriptorsInitialization();
01537 
01543     void reformatTable(oid_t tableId, dbTableDescriptor* desc);
01544 
01550     void addIndices(dbTableDescriptor* desc);
01551 
01557     oid_t addNewTable(dbTableDescriptor* desc);
01558 
01565     void updateTableDescriptor(dbTableDescriptor* desc,
01566                                oid_t tableId, dbTable* table);
01567 
01568 
01574     void removeInverseReferences(dbTableDescriptor* desc, oid_t oid);
01575 
01576 
01585     void insertInverseReference(dbFieldDescriptor* desc, oid_t reverseId,
01586                                 oid_t targetId);
01587 
01596     void removeInverseReference(dbFieldDescriptor* desc,
01597                                 oid_t reverseId, oid_t targetId);
01598 
01603     void deleteTable(dbTableDescriptor* desc);
01604 
01609     void dropTable(dbTableDescriptor* desc);
01610 
01615     void createIndex(dbFieldDescriptor* fd);
01616 
01621     void createHashTable(dbFieldDescriptor* fd);
01622 
01627     void dropIndex(dbFieldDescriptor* fd);
01628 
01633     void dropHashTable(dbFieldDescriptor* fd);
01634 
01640     void linkTable(dbTableDescriptor* table, oid_t tableId);
01641 
01646     void unlinkTable(dbTableDescriptor* table);
01647 
01648 
01655     bool wasReserved(offs_t pos, offs_t size);
01656 
01665     void reserveLocation(dbLocation& location, offs_t pos, offs_t size);
01666 
01671     void commitLocation();
01672 
01678     dbTableDescriptor* findTable(char_t const* name);
01679     
01680 
01685     void cleanupOnOpenError();
01686 
01690     void setDirty();
01691 
01695     void refreshTable(dbTableDescriptor* desc);
01696 };
01697 
01698 template<class T>
01699 dbReference<T> insert(T const& record) {
01700     dbReference<T> ref;
01701     T::dbDescriptor.getDatabase()->insertRecord(&T::dbDescriptor, &ref, &record, false);
01702     return ref;
01703 }
01704 
01705 template<class T>
01706 dbReference<T> batchInsert(T const& record) {
01707     dbReference<T> ref;
01708     T::dbDescriptor.getDatabase()->insertRecord(&T::dbDescriptor, &ref, &record, true);
01709     return ref;
01710 }
01711 
01712 #ifdef NO_MEMBER_TEMPLATES
01713 template<class T>
01714 dbReference<T> insert(dbDatabase& db, T const& record) {
01715     dbReference<T> ref;
01716     db.insertRecord(db.lookupTable(&T::dbDescriptor), &ref, &record, false);
01717     return ref;
01718 }
01719 template<class T>
01720 dbReference<T> batchInsert(dbDatabase& db, T const& record) {
01721     dbReference<T> ref;
01722     db.insertRecord(db.lookupTable(&T::dbDescriptor), &ref, &record, true);
01723     return ref;
01724 }
01725 #endif
01726 
01727 class dbSearchContext {
01728   public:
01729     dbDatabase*  db;
01730     dbExprNode*  condition;
01731     dbAnyCursor* cursor;
01732     char_t*      firstKey;
01733     int          firstKeyInclusion;
01734     char_t*      lastKey;
01735     int          lastKeyInclusion;
01736     int          prefixLength;
01737     int          offs;
01738     int          probes;
01739     bool         ascent;
01740     bool         tmpKeys; // temporary keys were created for using index with LIKE operation
01741     bool         spatialSearch;
01742     bool         arraySearch;
01743 
01744     void operator = (dbSearchContext const& sc);
01745 
01746     union {
01747         bool        b;
01748         int1        i1;
01749         int2        i2;
01750         int4        i4;
01751         db_int8     i8;
01752         real4       f4;
01753         real8       f8;
01754         oid_t       oid;
01755         void*       raw;
01756         rectangle*  rect;
01757         char_t*     s;
01758         dbAnyArray* a;
01759     } literal[2];
01760 };
01761 
01762 END_GIGABASE_NAMESPACE
01763 
01764 #endif
01765 

Generated on Mon Aug 23 2010 00:04:01 for GigaBASE by  doxygen 1.7.1