📄 database.h
字号:
//-< DATABASE.H >----------------------------------------------------*--------*
// FastDB Version 1.0 (c) 1999 GARRET * ? *
// (Main Memory Database Management System) * /\| *
// * / \ *
// Created: 20-Nov-98 K.A. Knizhnik * / [] \ *
// Last update: 23-Dec-98 K.A. Knizhnik * GARRET *
//-------------------------------------------------------------------*--------*
// Database management
//-------------------------------------------------------------------*--------*
#ifndef __DATABASE_H__
#define __DATABASE_H__
#include "class.h"
#include "reference.h"
#include "file.h"
/**
* Default size of memory mapping object for the database (bytes)
*/
#ifdef DISKLESS_CONFIGURATION
// In diskless confiuration database can not be reallocated
const size_t dbDefaultInitDatabaseSize = 32*1024*1024;
#else
const size_t dbDefaultInitDatabaseSize = 1024*1024;
#endif
/**
* Default initial index size (number of objects)
*/
const size_t dbDefaultInitIndexSize = 512*1024;
/**
* Quantum of extension of allocated memory
*/
const size_t dbDefaultExtensionQuantum = 4*1024*1024;
/**
* Maximal number of threads which can be spawned to perform parallel sequentila search
*/
const unsigned dbMaxParallelSearchThreads = 64;
/**
* Internal objects tags
*/
enum dbInternalObject {
dbTableRow,
dbPageObjectMarker,
dbTtreeMarker,
dbTtreeNodeMarker,
dbHashTableMarker,
dbHashTableItemMarker,
dbHArrayPageMarker,
dbInternalObjectMarker = 7 // mask for internals object markers
};
const offs_t dbFreeHandleMarker = (offs_t)1 << (sizeof(offs_t)*8 - 1);
const size_t dbAllocationQuantumBits = 4;
const size_t dbAllocationQuantum = 1 << dbAllocationQuantumBits;
const size_t dbPageBits = 12;
const size_t dbPageSize = 1 << dbPageBits;
const size_t dbIdsPerPage = dbPageSize / sizeof(oid_t);
const size_t dbHandlesPerPage = dbPageSize / sizeof(offs_t);
const size_t dbHandleBits = 1 + sizeof(offs_t)/4; // log(sizeof(offs_t))
const size_t dbBitmapSegmentBits = dbPageBits + 3 + dbAllocationQuantumBits;
const size_t dbBitmapSegmentSize = 1 << dbBitmapSegmentBits;
const size_t dbBitmapPages = 1 << (dbDatabaseOffsetBits-dbBitmapSegmentBits);
const size_t dbDirtyPageBitmapSize = 1 << (dbDatabaseOidBits-dbPageBits+dbHandleBits-3);
const size_t dbDefaultSelectionLimit = 2000000000;
const int dbBMsearchThreshold = 512;
const char dbMatchAnyOneChar = '_';
const char dbMatchAnySubstring = '%';
/**
* Predefined object identifiers
*/
enum dbPredefinedIds {
dbInvalidId,
dbMetaTableId,
dbBitmapId,
dbFirstUserId = dbBitmapId + dbBitmapPages
};
/**
* Database header
*/
class dbHeader
{
public:
offs_t size; // database file size
int4 curr; // current root
int4 dirty; // database was not closed normally
int4 initialized; // database is initilaized
int4 pad;
struct
{
offs_t index; // offset to object index
offs_t shadowIndex; // offset to shadow index
oid_t indexSize; // size of object index
oid_t shadowIndexSize; // size of object index
oid_t indexUsed; // used part of the index
oid_t freeList; // L1 list of free descriptors
}
root[2];
int4 majorVersion;
int4 minorVersion;
};
union dbSynthesizedAttribute;
struct dbInheritedAttribute;
class dbDatabaseThreadContext;
class dbAnyCursor;
class dbQuery;
class dbExprNode;
class dbMonitor
{
public:
sharedsem_t sem;
sharedsem_t mutatorSem;
int nReaders;
int nWriters;
int nWaitReaders;
int nWaitWriters;
int waitForUpgrade;
int forceCommitCount;
int backupInProgress;
int uncommittedChanges;
int curr; // copy of header->root, used to allow read access
// to the database during transaction commit
int commitInProgress;
int concurrentTransId;
unsigned lastDeadlockRecoveryTime;
int version;
int users;
dbProcessId ownerPid;
dbDatabaseThreadContext* delayedCommitContext; // save context of delayed transaction
int4 dirtyPagesMap[dbDirtyPageBitmapSize/4];
};
/**
* Double linked list
*/
class FASTDB_DLL_ENTRY dbL2List
{
public:
dbL2List* next;
dbL2List* prev;
void link(dbL2List* elem)
{
elem->prev = this;
elem->next = next;
next = next->prev = elem;
}
void unlink()
{
next->prev = prev;
prev->next = next;
next = prev = this;
}
bool isEmpty()
{
return next == this;
}
void reset()
{
next = prev = this;
}
dbL2List()
{
next = prev = this;
}
~dbL2List()
{
unlink();
}
};
class dbVisitedObject
{
public:
dbVisitedObject* next;
oid_t oid;
dbVisitedObject(oid_t oid, dbVisitedObject* chain)
{
this->oid = oid;
next = chain;
}
};
/**
* Database class
*/
template<class T>
class dbHArray;
class FASTDB_DLL_ENTRY dbDatabase
{
friend class dbSelection;
friend class dbAnyCursor;
friend class dbHashTable;
friend class dbQuery;
friend class dbTtree;
friend class dbTtreeNode;
friend class dbParallelQueryContext;
friend class dbServer;
friend class dbColumnBinding;
friend class dbUserFunctionArgument;
friend class dbAnyContainer;
friend class dbFile;
friend class dbCLI;
friend class GiSTdb;
#ifdef HAS_TEMPLATE_FRIENDS
template<class T>
friend class dbHArray;
#else
friend class dbAnyHArray;
#endif
friend class dbXmlIo;
public:
/**
* Open database
* @param databaseName database name
* @param fielName path to the database file
* (if null, then file name daatbaseName + ".fdb" will be used)
* @param waitLockTimeoutMsec timeout for waiting locks, by default disabled
* @param commitDelaySec delayed commit timeout, by default disabled
* @return <code>true</code> if database was successfully opened
*/
bool open(char const* databaseName,
char const* fileName = NULL,
time_t waitLockTimeoutMsec = INFINITE,
time_t commitDelaySec = 0);
/**
* Close database
*/
void close();
/**
* Commit transaction
*/
void commit();
/**
* Release all locks hold by transaction allowing other clients to proceed
* but do not flush changes to the disk
*/
void precommit();
/**
* Rollback transaction
*/
void rollback();
/**
* Schedule backup
* @param fileName path to backup file. If name ends with '?', then
* each backup willbe placed in seprate file with '?' replaced with current timestamp
* @param periodSec preiod of performing backups in seconds
*/
void scheduleBackup(char const* fileName, time_t periodSec);
/**
* Attach current thread to the database. This method should be executed
* for all threads except one which opened the database.
*/
void attach();
enum DetachFlags {
COMMIT = 1,
DESTROY_CONTEXT = 2
};
/**
* Detach thread from the database.
* @param flags mask of DetachFlags COMMIT and DESTROY_CONTEXT
*/
void detach(int flags = COMMIT|DESTROY_CONTEXT);
/**
* Exclusivly lock the database.
*/
void lock()
{
beginTransaction(dbExclusiveLock);
}
/**
* Perform backup to the specified file
* @param file path to the backup file
* @param comactify if true then databae will be compactificated during backup -
* i.e. all used objects will be placed together without holes; if false then
* backup is performed by just writting memory mapped object to the backup file.
* @return whether backup was succeseful or not
*/
bool backup(char const* file, bool compactify);
/**
* Assign table to the database
* @param desc table descriptor
*/
void assign(dbTableDescriptor& desc)
{
assert(((void)"Table is not yet assigned to the database",
desc.tableId == 0));
desc.db = this;
desc.fixedDatabase = true;
}
/**
* Set concurrency level for sequential search and sort operations.
* By default, FastDB tries to detect number of CPUs in system and create
* the same number of threads.
* @param nThreads maximal number of threads to be created for
* perfroming cincurrent sequential search and sorting.
*/
void setConcurrency(unsigned nThreads);
/**
* Get size allocated in the database since open
* @return delta between size of allocated and deallocated data
*/
long getAllocatedSize()
{
return allocatedSize;
}
/**
* Get size of the database file
* @return database file size
*/
long getDatabaseSize()
{
return header->size;
}
/**
* Get number of threads accessing database in shared mode (readonly)
* @return number of granted shared locks
*/
int getNumberOfReaders()
{
return monitor->nReaders;
}
/**
* Get number of threads accessing database in exclusiveh mode (for update)
* @return number of granted exclusive locks (can be either 0 either 1)
*/
int getNumberOfWriters()
{
return monitor->nWriters;
}
/**
* Get number of threads blocked while starting read-only transaction
* @return number of threads which shared lock request was blocked
*/
int getNumberOfBlockedReaders()
{
return monitor->nReaders;
}
/**
* Get number of threads blocked while starting update transaction
* @return number of threads which exclusive lock request was blocked
*/
int getNumberOfBlockedWriters()
{
return monitor->nWriters;
}
/**
* Get number of processes attached to the database
* @return number of processes openned the database
*/
int getNumberOfUsers()
{
return monitor->users;
}
/**
* Enable deletion of columns from the table when correspondent fields
* are renamed from class descriptor. By default it is switched of
* and database allows to delete fields only from empty table (to prevent
* unindented loose of data).
* @param enabled true to enable column deletion in non empty tables
*/
void allowColumnsDeletion(bool enabled = true)
{
confirmDeleteColumns = enabled;
}
enum dbErrorClass {
NoError,
QueryError,
ArithmeticError,
IndexOutOfRangeError,
DatabaseOpenError,
FileError,
OutOfMemoryError,
Deadlock,
NullReferenceError,
LockRevoked,
FileLimitExeeded,
InconsistentInverseReference,
DatabaseReadOnly
};
typedef void (*dbErrorHandler)(int error, char const* msg, int msgarg);
/**
* Set error handler. Handler should be no-return function which perform stack unwind.
* @param newHandler new error handler
* @return previous handler
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -