⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 database.cpp

📁 FastDb是高效的内存数据库系统
💻 CPP
📖 第 1 页 / 共 5 页
字号:
{    return false;}void dbDatabase::initializeMetaTable(){    static struct {         char const* name;        int         type;        int         size;        int         offs;    } metaTableFields[] = {         { "name", dbField::tpString, sizeof(dbVarying),           offsetof(dbTable, name)},        { "fields", dbField::tpArray, sizeof(dbVarying),           offsetof(dbTable, fields)},        { "fields[]", dbField::tpStructure, sizeof(dbField), 0},        { "fields[].name", dbField::tpString, sizeof(dbVarying),           offsetof(dbField, name)},        { "fields[].tableName",dbField::tpString,sizeof(dbVarying),           offsetof(dbField, tableName)},        { "fields[].inverse", dbField::tpString, sizeof(dbVarying),           offsetof(dbField, inverse)},//        { "fields[].type", dbField::tpInt4, 4, offsetof(dbField, type)},        { "fields[].type", dbField::tpInt4, 4, offsetof(dbField, offset)-4},        { "fields[].offset", dbField::tpInt4, 4, offsetof(dbField, offset)},        { "fields[].size", dbField::tpInt4, 4, offsetof(dbField, size)},        { "fields[].hashTable", dbField::tpReference, sizeof(oid_t),           offsetof(dbField, hashTable)},        { "fields[].tTree", dbField::tpReference, sizeof(oid_t),           offsetof(dbField, tTree)},        { "fixedSize", dbField::tpInt4, 4, offsetof(dbTable, fixedSize)},        { "nRows", dbField::tpInt4, 4, offsetof(dbTable, nRows)},        { "nColumns", dbField::tpInt4, 4, offsetof(dbTable, nColumns)},        { "firstRow", dbField::tpReference, sizeof(oid_t), offsetof(dbTable, firstRow)},        { "lastRow", dbField::tpReference, sizeof(oid_t), offsetof(dbTable, lastRow)} #ifdef AUTOINCREMENT_SUPPORT       ,{ "count", dbField::tpInt4, 4, offsetof(dbTable, count)} #endif    };    unsigned i;    size_t varyingSize = strlen(dbMetaTableName)+1;    for (i = 0; i < itemsof(metaTableFields); i++) {         varyingSize += strlen(metaTableFields[i].name) + 3;            }    offs_t metaTableOffs = allocate(sizeof(dbTable)                                    + sizeof(dbField)*itemsof(metaTableFields)                                    + varyingSize);    index[0][dbMetaTableId] = metaTableOffs;    dbTable* table = (dbTable*)(baseAddr + metaTableOffs);    table->size = sizeof(dbTable) + sizeof(dbField)*itemsof(metaTableFields)                + varyingSize;    table->next = table->prev = 0;    int offs = sizeof(dbTable) + sizeof(dbField)*itemsof(metaTableFields);    table->name.offs = offs;    table->name.size = strlen(dbMetaTableName)+1;    strcpy((char*)table + offs, dbMetaTableName);    offs += table->name.size;    table->fields.offs = sizeof(dbTable);    table->fields.size = itemsof(metaTableFields);    table->fixedSize = sizeof(dbTable);    table->nRows = 0;    table->nColumns = 5;    table->firstRow = 0;    table->lastRow = 0;#ifdef AUTOINCREMENT_SUPPORT    table->count = 0;#endif    dbField* field = (dbField*)((char*)table + table->fields.offs);    offs -= sizeof(dbTable);    for (i = 0; i < itemsof(metaTableFields); i++) {         field->name.offs = offs;        field->name.size = strlen(metaTableFields[i].name) + 1;        strcpy((char*)field + offs, metaTableFields[i].name);        offs += field->name.size;        field->tableName.offs = offs;        field->tableName.size = 1;        *((char*)field + offs++) = '\0';                field->inverse.offs = offs;        field->inverse.size = 1;        *((char*)field + offs++) = '\0';                field->flags = 0;        field->type = metaTableFields[i].type;        field->size = metaTableFields[i].size;        field->offset = metaTableFields[i].offs;        field->hashTable = 0;        field->tTree = 0;        field += 1;        offs -= sizeof(dbField);    }}void dbDatabase::cleanup(dbInitializationMutex::initializationStatus status, int step) {    switch (step) {       case 9:        if (status == dbInitializationMutex::NotYetInitialized) {                     file.close();        }        // no break      case 8:        if (accessType == dbConcurrentUpdate || accessType == dbConcurrentRead) {             mutatorCS.close();        }        // no break      case 7:        if (delayedCommitEventsOpened) {             delayedCommitStopTimerEvent.close();            delayedCommitStartTimerEvent.close();            commitThreadSyncEvent.close();            delayedCommitEventsOpened = false;        }        // no break      case 6:        cs.close();        // no break      case 5:        backupCompletedEvent.close();        // no break      case 4:        upgradeSem.close();        // no break      case 3:        readSem.close();        // no break      case 2:        writeSem.close();        // no break      case 1:        shm.close();        // no break      default:        if (status == dbInitializationMutex::NotYetInitialized) {                     initMutex.done();        }        initMutex.close();    }}bool dbDatabase::open(char const* dbName, char const* fiName,                       time_t waitLockTimeoutMsec, time_t commitDelaySec){    dbWaitLockTimeout = waitLockTimeoutMsec;    delete[] databaseName;    delete[] fileName;    commitDelay = 0;    commitTimeout = 0;    commitTimerStarted = 0;    delayedCommitEventsOpened = false;    backupFileName = NULL;    backupPeriod = 0;    opened = false;    stopDelayedCommitThread = false;    databaseNameLen = strlen(dbName);    char* name = new char[databaseNameLen+16];    sprintf(name, "%s.in", dbName);    databaseName = name;    if (fiName == NULL) {         fileName = new char[databaseNameLen + 5];        sprintf(fileName, "%s.fdb", dbName);    } else {         fileName = new char[strlen(fiName)+1];        strcpy(fileName, fiName);    }    dbInitializationMutex::initializationStatus status = initMutex.initialize(name);    if (status == dbInitializationMutex::InitializationError) {         handleError(DatabaseOpenError,                     "Failed to start database initialization");        return false;    }    sprintf(name, "%s.dm", dbName);    if (!shm.open(name)) {         handleError(DatabaseOpenError, "Failed to open database monitor");        cleanup(status, 0);        return false;    }    monitor = shm.get();    sprintf(name, "%s.ws", dbName);    if (!writeSem.open(name)) {         handleError(DatabaseOpenError,                     "Failed to initialize database writers semaphore");        cleanup(status, 1);        return false;    }    sprintf(name, "%s.rs", dbName);    if (!readSem.open(name)) {         handleError(DatabaseOpenError,                     "Failed to initialize database readers semaphore");        cleanup(status, 2);        return false;    }    sprintf(name, "%s.us", dbName);    if (!upgradeSem.open(name)) {         handleError(DatabaseOpenError,                     "Failed to initialize database upgrade semaphore");        cleanup(status, 3);        return false;    }    sprintf(name, "%s.bce", dbName);    if (!backupCompletedEvent.open(name)) {         handleError(DatabaseOpenError,                     "Failed to initialize database backup completed event");        cleanup(status, 4);        return false;    }        if (commitDelaySec != 0) {         sprintf(name, "%s.dce", dbName);        delayedCommitEventsOpened = true;        if (!delayedCommitStopTimerEvent.open(name)) {             handleError(DatabaseOpenError,                         "Failed to initialize delayed commit event");            cleanup(status, 5);            return false;        }            delayedCommitStartTimerEvent.open();        commitThreadSyncEvent.open();    }    backupInitEvent.open();    backupFileName = NULL;    allocatedSize = 0;    size_t indexSize = initIndexSize < dbFirstUserId         ? size_t(dbFirstUserId) : initIndexSize;    indexSize = DOALIGN(indexSize, dbHandlesPerPage);                size_t fileSize = initSize ? initSize : dbDefaultInitDatabaseSize;    if (fileSize < indexSize*sizeof(offs_t)*4) {        fileSize = indexSize*sizeof(offs_t)*4;    }    fileSize = DOALIGN(fileSize, dbBitmapSegmentSize);#ifdef DISKLESS_CONFIGURATION    mmapSize = fileSize;#else    mmapSize = 0;#endif    for (int i = dbBitmapId + dbBitmapPages; --i >= 0;) {         bitmapPageAvailableSpace[i] = INT_MAX;    }    currRBitmapPage = currPBitmapPage = dbBitmapId;    currRBitmapOffs = currPBitmapOffs = 0;    reservedChain = NULL;    tables = NULL;    modified = false;    selfId = 0;    maxClientId = 0;    threadContextList.reset();    attach();    if (status == dbInitializationMutex::NotYetInitialized) {         sprintf(name, "%s.cs", dbName);        if (!cs.create(name, &monitor->sem)) {             handleError(DatabaseOpenError, "Failed to initialize database monitor");            cleanup(status, 6);            return false;        }        if (accessType == dbConcurrentUpdate || accessType == dbConcurrentRead) {             sprintf(name, "%s.mcs", dbName);            if (!mutatorCS.create(name, &monitor->mutatorSem)) {                 handleError(DatabaseOpenError,                            "Failed to initialize database monitor");                cleanup(status, 7);                return false;            }        }        readSem.reset();        writeSem.reset();        upgradeSem.reset();        monitor->nReaders = 0;        monitor->nWriters = 0;        monitor->nWaitReaders = 0;        monitor->nWaitWriters = 0;        monitor->waitForUpgrade = false;        monitor->version = version = 1;        monitor->users = 0;        monitor->backupInProgress = 0;        monitor->forceCommitCount = 0;        monitor->lastDeadlockRecoveryTime = 0;        monitor->delayedCommitContext = NULL;        monitor->concurrentTransId = 1;        monitor->commitInProgress = false;        monitor->uncommittedChanges = false;        monitor->clientId = 0;        monitor->upgradeId = 0;        monitor->modified = false;        monitor->exclusiveLockOwner = 0;        memset(monitor->dirtyPagesMap, 0, dbDirtyPageBitmapSize);        memset(monitor->sharedLockOwner, 0, sizeof(monitor->sharedLockOwner));            sprintf(databaseName, "%s.%d", dbName, version);        int rc = file.open(fileName, databaseName,                            accessType == dbReadOnly || accessType == dbConcurrentRead, fileSize, false);        if (rc != dbFile::ok)        {            char msgbuf[64];            file.errorText(rc, msgbuf, sizeof msgbuf);            TRACE_MSG(("File open error: %s\n", msgbuf));            handleError(DatabaseOpenError, "Failed to create database file");            cleanup(status, 8);            return false;        }        baseAddr = (byte*)file.getAddr();        fileSize = file.getSize();        header = (dbHeader*)baseAddr;        updatedRecordId = 0;                if ((unsigned)header->curr > 1) {             handleError(DatabaseOpenError, "Database file was corrupted: "                        "invalid root index");            cleanup(status, 9);            return false;        }        if (header->initialized != 1) {            if (accessType == dbReadOnly || accessType == dbConcurrentRead) {                 handleError(DatabaseOpenError, "Can not open uninitialized "                            "file in read only mode");                cleanup(status, 9);                return false;            }            monitor->curr = header->curr = 0;            header->size = fileSize;            size_t used = dbPageSize;            header->root[0].index = used;            header->root[0].indexSize = indexSize;            header->root[0].indexUsed = dbFirstUserId;            header->root[0].freeList = 0;            used += indexSize*sizeof(offs_t);            header->root[1].index = used;            header->root[1].indexSize = indexSize;            header->root[1].indexUsed = dbFirstUserId;            header->root[1].freeList = 0;            used += indexSize*sizeof(offs_t);            header->root[0].shadowIndex = header->root[1].index;            header->root[1].shadowIndex = header->root[0].index;            header->root[0].shadowIndexSize = indexSize;            header->root[1].shadowIndexSize = indexSize;                        header->majorVersion= FASTDB_MAJOR_VERSION;            header->minorVersion = FASTDB_MINOR_VERSION;            header->mode = dbHeader::getCurrentMode();            index[0] = (offs_t*)(baseAddr + header->root[0].index);            index[1] = (offs_t*)(baseAddr + header->root[1].index);            index[0][dbInvalidId] = dbFreeHandleMarker;            size_t bitmapPages =                 (used + dbPageSize*(dbAllocationQuantum*8-1) - 1)                / (dbPageSize*(dbAllocationQuantum*8-1));            memset(baseAddr+used, 0xFF, (used + bitmapPages*dbPageSize)                                        / (dbAllocationQuantum*8));            size_t i;            for (i = 0; i < bitmapPages; i++) {                 index[0][dbBitmapId + i] = used + dbPageObjectMarker;                used += dbPageSize;            }            while (i < dbBitmapPages) {                 index[0][dbBitmapId+i] = dbFreeHandleMarker;                i += 1;            }            currIndex = index[0];            currIndexSize = dbFirstUserId;            committedIndexSize = 0;            initializeMetaTable();            header->dirty = true;            memcpy(index[1], index[0], currIndexSize*sizeof(offs_t));            file.markAsDirty(0, used);            file.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -