📄 database.h
字号:
dbErrorHandler setErrorHandler(dbErrorHandler newHandler);
/**
* Error handler.
* It can be redifined by application to implement application specific error handling.
* @param error class of the error
* @param msg error message
* @param arg optional argument
*/
virtual void handleError(dbErrorClass error, char const* msg = NULL,
int arg = 0);
/**
* Insert record in the database
* @param table table descriptor
* @param ref [out] pointer to the references where ID of created object will be stored
* @param record pointer to the transient object to be inserted in the table
*/
void insertRecord(dbTableDescriptor* table, dbAnyReference* ref,
void const* record);
/**
* Check if database is opened
*/
bool isOpen() const
{
return opened;
}
/**
* Get database version
*/
int getVersion();
/**
* Specify database file size limit. Attempt to exeed this limit cause database error.
* @param limit maximal file size in bytes
*/
void setFileSizeLimit(size_t limit)
{
dbFileSizeLimit = limit;
}
#ifndef NO_MEMBER_TEMPLATES
/**
* Insert record in the database
* @param record transient object to be insrted in the database
* @return reference to the created object
*/
template<class T>
dbReference<T> insert(T const& record)
{
dbReference<T> ref;
insertRecord(lookupTable(&T::dbDescriptor), &ref, &record);
return ref;
}
#endif
/**
* Find cloned table desciptor assigned to this database
* @param des static unassigned table descriptor
* @return clone of this table descriptor assigned to this databae or NULL
* if not found.
*/
dbTableDescriptor* lookupTable(dbTableDescriptor* desc);
enum dbAccessType {
dbReadOnly = 0,
dbAllAccess = 1,
dbConcurrentRead = 2,
dbConcurrentUpdate = 3
};
/**
* Database constructor
* @param type access type: <code>dbDatabase::dbReadOnly</code> or <code>dbDatabase::dbAllAcces</code>
* @param dbInitSize initial size of the database. If FastDB is compiled with
* DISKLESS_CONFIGURATION option, then in this parameter <B>MAXIMAL</B> size of the
* database should be specified (in this mode database can not be reallocated)
* @param dbExtensionQuantum quentum for extending memory allocation bitmap
* @param dbInitIndexSize initial index size (objects)
* @param nThreads concurrency level for sequential search and sort operations
* @see setConcurrency(unsigned nThreads)
*/
dbDatabase(dbAccessType type = dbAllAccess,
size_t dbInitSize = dbDefaultInitDatabaseSize,
size_t dbExtensionQuantum = dbDefaultExtensionQuantum,
size_t dbInitIndexSize = dbDefaultInitIndexSize,
int nThreads = 1
// Do not specify the last parameter - it is only for checking
// that application and GigaBASE library were built with the
// same compiler options (-DNO_PTHREADS is critical)
// Mismached parameters should cause linker error
#ifdef NO_PTHREADS
, bool usePthreads = false
#endif
);
/**
* Database detructor
*/
virtual ~dbDatabase();
const dbAccessType accessType;
const size_t initSize;
const size_t extensionQuantum;
const size_t initIndexSize;
static unsigned dbParallelScanThreshold;
protected:
static size_t internalObjectSize[];
dbThreadPool threadPool;
dbThreadContext<dbDatabaseThreadContext> threadContext;
byte* baseAddr; // base address of database file mapping
dbHeader* header; // base address of database file mapping
offs_t* currIndex; // current database object index
offs_t* index[2];
unsigned parThreads;
bool modified;
size_t currRBitmapPage; //current bitmap page for allocating records
size_t currRBitmapOffs; //offset in current bitmap page for allocating
//unaligned records
size_t currPBitmapPage; //current bitmap page for allocating page objects
size_t currPBitmapOffs; //offset in current bitmap page for allocating
//page objects
struct dbLocation
{
offs_t pos;
size_t size;
dbLocation* next;
};
dbLocation* reservedChain;
char* databaseName;
int databaseNameLen;
char* fileName;
int version;
size_t mmapSize;
size_t committedIndexSize;
size_t currIndexSize;
oid_t updatedRecordId;
unsigned dbWaitLockTimeout;
size_t dbFileSizeLimit;
bool uncommittedChanges;
dbFile file;
dbSharedObject<dbMonitor> shm;
dbGlobalCriticalSection cs;
dbGlobalCriticalSection mutatorCS;
dbInitializationMutex initMutex;
dbSemaphore writeSem;
dbSemaphore readSem;
dbSemaphore upgradeSem;
dbEvent backupCompletedEvent;
dbMonitor* monitor;
dbTableDescriptor* tables;
int* bitmapPageAvailableSpace;
bool opened;
long allocatedSize;
time_t commitDelay;
time_t commitTimeout;
time_t commitTimerStarted;
dbMutex delayedCommitStartTimerMutex;
dbMutex delayedCommitStopTimerMutex;
dbLocalEvent delayedCommitStartTimerEvent;
dbEvent delayedCommitStopTimerEvent;
dbLocalEvent commitThreadSyncEvent;
dbMutex backupMutex;
dbLocalEvent backupInitEvent;
char* backupFileName;
time_t backupPeriod;
bool stopDelayedCommitThread;
dbThread backupThread;
dbThread commitThread;
int accessCount;
dbL2List threadContextList;
dbMutex threadContextListMutex;
dbErrorHandler errorHandler;
int schemeVersion;
dbVisitedObject* visitedChain;
bool confirmDeleteColumns;
void delayedCommit();
void backupScheduler();
static void thread_proc delayedCommitProc(void* arg)
{
((dbDatabase*)arg)->delayedCommit();
}
static void thread_proc backupSchedulerProc(void* arg)
{
((dbDatabase*)arg)->backupScheduler();
}
/**
* Commit transaction
* @param ctx thread context
*/
void commit(dbDatabaseThreadContext* ctx);
/**
* Restore consistency of table list of rows (last record should contain null reference
* in next field). This method is used during recovery after crash and during rollback.
*/
void restoreTablesConsistency();
/**
* Get table row
* @param oid object indentifier
* @return object with this oid
*/
dbRecord* getRow(oid_t oid)
{
assert(!(currIndex[oid]&(dbFreeHandleMarker|dbInternalObjectMarker)));
return (dbRecord*)(baseAddr + currIndex[oid]);
}
/**
* Prepare for row insertion or update. If record with such OID
* not exists or it is first time when it was changed during this transaction or
* size of recrod is changed, than new record is alocated in the database.
* Otherwisepointer to existed recordis returned.
* @param oid object indetifier
* @param newSize size of new object
* @return pointer inside database where object should should be stored
*/
dbRecord* putRow(oid_t oid, size_t newSize);
/**
* Prepare for object update ithout changing its size
* @param oid object indetifier
* @return pointer inside database where object should should be stored
*/
dbRecord* putRow(oid_t oid)
{
if (oid < committedIndexSize && index[0][oid] == index[1][oid])
{
size_t size = getRow(oid)->size;
size_t pageNo = oid/dbHandlesPerPage;
monitor->dirtyPagesMap[pageNo >> 5] |= 1 << (pageNo & 31);
cloneBitmap(currIndex[oid], size);
allocate(size, oid);
}
return (dbRecord*)(baseAddr + currIndex[oid]);
}
/**
* Get record by OID
* @param oid object identifier
* @return pointer to the record inside database
*/
byte* get
(oid_t oid)
{
return baseAddr + (currIndex[oid] & ~dbInternalObjectMarker);
}
/**
* Prepare for update of internal object.
* @param oid internal object identifier
* @return pointer to the record inside database
*/
byte* put(oid_t oid)
{
if (oid < committedIndexSize && index[0][oid] == index[1][oid])
{
offs_t offs = currIndex[oid];
size_t size = internalObjectSize[offs & dbInternalObjectMarker];
size_t pageNo = oid/dbHandlesPerPage;
monitor->dirtyPagesMap[pageNo >> 5] |= 1 << (pageNo & 31);
allocate(size, oid);
cloneBitmap(offs & ~dbInternalObjectMarker, size);
}
return baseAddr + (currIndex[oid] & ~dbInternalObjectMarker);
}
/**
* Check whether search dan be performed using indices
* @param expr evaluated expression
* @param andExpr if not null, then it is used as filter to all records selected by
* index search
* @param indexedFile [out] used to return information about which field was used
* to perfrom index search and so order in which selected records are sorted.
* If this order is the same as requested by "order by" clause, then no extra sorting
* is needed.
* @return true if search was performed using indeices, false if index is not applicable
* and sequential search is required
*/
bool isIndexApplicable(dbAnyCursor* cursor,
dbExprNode* expr, dbExprNode* andExpr,
dbFieldDescriptor* &indexedField);
/**
* Check whether expression can be evaluated unsing index.
* If index is applicable, than index search is performed and result
* is stored in the cursor.
* @param cursor result set
* @param expr evaluated expression
* @param andExpr if not null, then it is used as filter to all records selected by
* index search
* @return true if expression was evaluated using index, false if index is not applicable
* and sequential search is required
*/
bool isIndexApplicable(dbAnyCursor* cursor,
dbExprNode* expr, dbExprNode* andExpr);
/**
* If query predicate contains operands from other tables (accessed by references)
* and inverse references exists, then FastDB performs
* indexed search in referenced table and then go back using inverse referenced to
* query table. followInverseReference method performs this backward traversal of inverse
* references.
* @param expr evaluated expression
* @param andExpr if not null, then it is used as filter to all records selected by
* index search
* @param cursor cursor to collect selected records
* @param iref OID of the selected records in referenced table
*/
bool followInverseReference(dbExprNode* expr, dbExprNode* andExpr,
dbAnyCursor* cursor, oid_t iref);
/**
* Check if there is inverse reference in the table rerefrenced from search predicate.
* @param expr evaluated expression
* @param nExistsClause number of exists clauses in search wrapping this expression
* @return true if inverse reference(s) exists and it is possible to perform backward
* traversal
*/
bool existsInverseReference(dbExprNode* expr, int nExistsClauses);
/**
* Execute expression. This method is most frequently recursivly called during
* evaluation of search predicate.
* @param expr expression to be executed
* @param iattr inherited attributes - attributes passed top-down
* (information like cursor, current record, ...)
* @param sattr synthesized attribute - sttributes passed down-top
* (value of expression)
*/
static void _fastcall execute(dbExprNode* expr,
dbInheritedAttribute& iattr,
dbSynthesizedAttribute& sattr);
/**
* Evaluate epression. This method initialie initiainherited attributes and invoke
* execute method
* @param expr expression to be evaluated
* @param oid OID of the inspected record
* @param seaqched table
* @param cursor result set
* @return true if this record match search condition, false otherwise
*/
bool evaluate(dbExprNode* expr, oid_t oid, dbTable* table, dbAnyCursor* cursor);
/**
* Select all records from the table
* @param cursor result set
*/
void select(dbAnyCursor* cursor);
/**
* Execute select query
* @param cursor result set
* @param query query expression
*/
void select(dbAnyCursor* cursor, dbQuery& query);
/**
* Perform table traverse: execute queries with "start from (follow by)" clause
* @param cursor result set
* @param query query expression
*/
void traverse(dbAnyCursor* cursor, dbQuery& query);
/**
* Update record
* @param oid record identifier
* @param table descriptor of the table to which record belongs
* @param record updated image of the record
*/
void update(oid_t oid, dbTableDescriptor* table, void const* record);
/**
* Remove record from the database
* @param table descriptor of the table to which record belongs
* @param oid record identifier
*/
void remove
(dbTableDescriptor* table, oid_t oid);
/**
* Allocate object in the database
* e@param size size of alocated object
* @param oid if oid is not 0, then allocated region position is stored in correcpondent
* cell of object index (needed for allocation of bitmap pages)
* @return position of allcoated region
*/
offs_t allocate(size_t size, oid_t oid = 0);
/**
* Deallocate region
* @param pos start position of region
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -