📄 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"
BEGIN_FASTDB_NAMESPACE
/**
* 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;
const int dbDefaultParallelScanThreshold = 1000;
const int dbDefaultPollInterval = 10*1000; // milliseconds
const int dbWaitReadyTimeout = 60*1000; // milliseconds
const int dbWaitStatusTimeout = 60*1000; // milliseconds
const int dbRecoveryConnectionAttempts = 3;
const int dbStartupConnectionAttempts = 60;
const int dbReplicationWriteTimeout = 60*1000; // milliseconds
const int dbMaxAsyncRecoveryIterations = 1000;
/**
* Internal objects tags
*/
enum dbInternalObject {
dbTableRow,
dbPageObjectMarker,
dbTtreeMarker,
dbTtreeNodeMarker,
dbHashTableMarker,
dbHashTableItemMarker,
dbRtreeMarker,
dbRtreePageMarker,
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 = '%';
const int dbMaxReaders = 64; // maximal number of readers concurrently accessing the database
/**
* 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
#if dbDatabaseOffsetBits > 32 && defined(ALIGN_HEADER)
int4 pad;
#endif
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;
int4 mode;
enum {
MODE_OID_64 = 0x01,
MODE_OFFS_64 = 0x02,
MODE_AUTOINCREMENT = 0x04,
MODE_RECTANGLE_DIM = 0x08
};
int getVersion() {
return majorVersion*100 + minorVersion;
}
bool isCompatible();
static int getCurrentMode();
};
union dbSynthesizedAttribute;
struct dbInheritedAttribute;
class dbDatabaseThreadContext;
class dbAnyCursor;
class dbQuery;
class dbExprNode;
struct dbMemoryStatistic {
offs_t used;
offs_t free;
offs_t nHoles;
offs_t minHoleSize;
offs_t maxHoleSize;
size_t nHolesOfSize[dbDatabaseOffsetBits];
};
class FixedSizeAllocator
{
struct Hole {
Hole* next;
offs_t offs;
};
size_t minSize;
size_t maxSize;
size_t quantum;
size_t nChains;
size_t bufSize;
Hole** chains;
Hole* vacant;
Hole* holes;
public:
size_t hits;
size_t faults;
size_t retries;
FixedSizeAllocator();
~FixedSizeAllocator();
void init(size_t minSize, size_t maxSize, size_t quantum, size_t bufSize);
void reset();
offs_t allocate(size_t size) {
if (size - minSize <= maxSize - minSize) {
size_t i = (size - minSize + quantum - 1) / quantum;
Hole* hole = chains[i];
if (hole != NULL) {
hits += 1;
chains[i] = hole->next;
hole->next = vacant;
vacant = hole;
return hole->offs;
}
faults += 1;
}
return 0;
}
bool free(offs_t offs, size_t size) {
if (vacant != NULL && size - minSize <= maxSize - minSize) {
size_t i = (size - minSize + quantum - 1) / quantum;
Hole* hole = vacant;
vacant = hole->next;
hole->next = chains[i];
chains[i] = hole;
hole->offs = offs;
return true;
}
return false;
}
};
class dbMonitor {
public:
sharedsem_t sem;
sharedsem_t mutatorSem;
int nReaders;
int nWriters;
int nConcurrentWriters;
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
offs_t size; // database size
int commitInProgress;
int concurrentTransId;
unsigned lastDeadlockRecoveryTime;
int version;
int users;
dbProcessId ownerPid;
dbDatabaseThreadContext* delayedCommitContext; // save context of delayed transaction
int4 dirtyPagesMap[dbDirtyPageBitmapSize/4];
int sharedLockOwner[dbMaxReaders];
int exclusiveLockOwner;
int clientId;
int upgradeId;
int modified;
};
/**
* 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;
}
};
#ifdef AUTO_DETECT_PROCESS_CRASH
struct dbWatchDogContext : dbL2List {
dbThread thread;
dbWatchDog watchDog;
int clientId;
dbDatabase* db;
dbMutex* mutex;
};
#endif
template<class T>
class dbHArray;
typedef unsigned (*dbHashFunction)(byte* key, int type, int keylen);
/**
* Database class
*/
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 dbRtree;
friend class dbRtreePage;
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
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);
enum dbAccessType {
dbReadOnly,
dbAllAccess,
dbConcurrentRead,
dbConcurrentUpdate
};
/**
* Structure to specify database open parameters
*/
struct OpenParameters {
/**
* Database name
*/
char const* databaseName;
/**
* Database file path
*/
char const* databaseFilePath;
/**
* Transaction commit delay
*/
time_t transactionCommitDelay;
/**
* Deadlock detection timeout (after expiration of this timeout a lokc is revoked)
*/
time_t waitLockTimeoutMsec;
/**
* Database access type
*/
dbAccessType accessType;
/**
* Initial database file size
*/
size_t initSize;
/**
* Quantum for extending memory allocation bitmap
*/
size_t extensionQuantum;
/**
* Initial database index size
*/
size_t initIndexSize;
/**
* Concurrency level for sequential search and sort operations
*/
int nThreads;
/**
* Threshold for amount of deallocated space after which allocation bitmap is
* scanned from the very beginning reusing deallocated object
*/
offs_t freeSpaceReuseThreshold;
/**
* Minimal number of records in the table when performing sequential search in parallel makes sense
*/
int parallelScanThreshold;
/**
* Replicated database node id
*/
int nodeId;
/**
* Replicated database node addresses
*/
char** nodeAddresses;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -