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

📄 database.cpp

📁 fastdb-2.92的源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    sprintf(name, "%s.us", dbName);    if (!upgradeSem.open(name)) {         handleError(DatabaseOpenError,                     "Failed to initialize database upgrade semaphore");        return false;    }    sprintf(name, "%s.bce", dbName);    if (!backupCompletedEvent.open(name)) {         handleError(DatabaseOpenError,                     "Failed to initialize database backup completed event");        return false;    }        if (commitDelaySec != 0) {         sprintf(name, "%s.dce", dbName);        if (!delayedCommitStopTimerEvent.open(name)) {             handleError(DatabaseOpenError,                         "Failed to initialize delayed commit event");            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;    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");            return false;        }        if (accessType == dbConcurrentUpdate) {             sprintf(name, "%s.mcs", dbName);            if (!mutatorCS.create(name, &monitor->mutatorSem)) {                 handleError(DatabaseOpenError,                            "Failed to initialize database monitor");                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;        memset(monitor->dirtyPagesMap, 0, dbDirtyPageBitmapSize);            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");            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");            return false;        }        if (header->initialized != 1) {            if (accessType == dbReadOnly || accessType == dbConcurrentRead) {                 handleError(DatabaseOpenError, "Can not open uninitialized "                            "file in read only mode");                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;            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.flush(true);            header->initialized = true;            file.markAsDirty(0, sizeof(dbHeader));            file.flush(true);        } else {            monitor->curr = header->curr;            if (header->dirty) {                 TRACE_MSG(("Database was not normally closed: "                           "start recovery\n"));                if (accessType == dbReadOnly || accessType == dbConcurrentRead) {                     handleError(DatabaseOpenError,                                "Can not open dirty file in read only moode");                    return false;                }                recovery();                TRACE_MSG(("Recovery completed\n"));            } else {                 if (file.getSize() != header->size) {                     handleError(DatabaseOpenError, "Database file was "                                "corrupted: file size in header differs "                                "from actual file size");                    return false;                }            }               }        if (!loadScheme(true)) {             return false;        }        initMutex.done();    } else {         sprintf(name, "%s.cs", dbName);        if (!cs.open(name, &monitor->sem)) {             handleError(DatabaseOpenError, "Failed to open shared semaphore");            return false;        }        if (accessType == dbConcurrentUpdate) {             sprintf(name, "%s.mcs", dbName);            if (!mutatorCS.open(name, &monitor->mutatorSem)) {                 handleError(DatabaseOpenError, "Failed to open shared semaphore");                return false;            }        }        version = 0;        if (!loadScheme(false)) {             return false;        }    }    cs.enter();                monitor->users += 1;    cs.leave();    opened = true;    if (commitDelaySec != 0) {         dbCriticalSection cs(delayedCommitStartTimerMutex);        commitTimeout = commitDelay = commitDelaySec;        commitThread.create((dbThread::thread_proc_t)delayedCommitProc, this);        commitThreadSyncEvent.wait(delayedCommitStartTimerMutex);    }    return true;}void dbDatabase::scheduleBackup(char const* fileName, time_t period){    if (backupFileName == NULL) {         backupFileName = new char[strlen(fileName) + 1];        strcpy(backupFileName, fileName);        backupPeriod = period;        backupThread.create((dbThread::thread_proc_t)backupSchedulerProc, this);    }} void dbDatabase::backupScheduler() {     backupThread.setPriority(dbThread::THR_PRI_LOW);    dbCriticalSection cs(backupMutex);     while (true) {         time_t timeout = backupPeriod;        if (backupFileName[strlen(backupFileName)-1] != '?') {            struct stat st;            if (::stat(backupFileName, &st) == 0) {                 time_t howOld = time(NULL) - st.st_atime;                if (timeout < howOld) {                     timeout = 0;                } else {                     timeout -= howOld;                }            }        }                backupInitEvent.wait(backupMutex, timeout*1000);                if (backupFileName != NULL) {             if (backupFileName[strlen(backupFileName)-1] == '?') {                time_t currTime = time(NULL);                char* fileName = new char[strlen(backupFileName) + 32];                struct tm* t = localtime(&currTime);                sprintf(fileName, "%.*s-%04d.%02d.%02d_%02d.%02d.%02d",                         (int)strlen(backupFileName)-1, backupFileName,                        t->tm_year + 1900, t->tm_mon+1, t->tm_mday,                         t->tm_hour, t->tm_min, t->tm_sec);                backup(fileName, false);                delete[] fileName;            } else {                 char* newFileName = new char[strlen(backupFileName) + 5];                sprintf(newFileName,"%s.new", backupFileName);                backup(newFileName, false);                ::remove(backupFileName);                ::rename(newFileName, backupFileName);                delete[] newFileName;            }        } else {             return;        }    }}    void dbDatabase::recovery(){    int curr = header->curr;    header->size = file.getSize();    header->root[1-curr].indexUsed = header->root[curr].indexUsed;     header->root[1-curr].freeList = header->root[curr].freeList;     header->root[1-curr].index = header->root[curr].shadowIndex;    header->root[1-curr].indexSize =         header->root[curr].shadowIndexSize;    header->root[1-curr].shadowIndex = header->root[curr].index;    header->root[1-curr].shadowIndexSize =         header->root[curr].indexSize;        offs_t* dst = (offs_t*)(baseAddr+header->root[1-curr].index);    offs_t* src = (offs_t*)(baseAddr+header->root[curr].index);    currIndex = dst;    for (int i = 0, n = header->root[curr].indexUsed; i < n; i++) {         if (dst[i] != src[i]) {             dst[i] = src[i];            file.markAsDirty(header->root[1-curr].index + i*sizeof(offs_t), sizeof(offs_t));        }    }    //    // Restore consistency of table rows l2-list     //    restoreTablesConsistency();    file.markAsDirty(0, sizeof(dbHeader));}void dbDatabase::restoreTablesConsistency(){    dbTable* table = (dbTable*)getRow(dbMetaTableId);    oid_t lastId = table->lastRow;    if (lastId != 0) {         dbRecord* record = getRow(lastId);        if (record->next != 0) {             record->next = 0;            file.markAsDirty(currIndex[lastId], sizeof(dbTable));        }    }    oid_t tableId = table->firstRow;    while (tableId != 0) {         table = (dbTable*)getRow(tableId);        lastId = table->lastRow;        if (lastId != 0) {             dbRecord* record = getRow(lastId);            if (record->next != 0) {                 record->next = 0;                file.markAsDirty(currIndex[lastId], sizeof(dbTable));            }        }        tableId = table->next;    }}void dbDatabase::setConcurrency(unsigned nThreads){    if (nThreads == 0) { // autodetect number of processors        nThreads = dbThread::numberOfProcessors();    }     if (nThreads > dbMaxParallelSearchThreads) {         nThreads = dbMaxParallelSearchThreads;    }    parThreads = nThreads;}bool dbDatabase::loadScheme(bool alter) {    if (!beginTransaction(accessType != dbReadOnly && accessType != dbConcurrentRead                          ? dbExclusiveLock : dbSharedLock))     {         return false;    }    dbTableDescriptor *desc, *next;    dbTable* metaTable = (dbTable*)getRow(dbMetaTableId);    oid_t first = metaTable->firstRow;    oid_t last = metaTable->lastRow;    int nTables = metaTable->nRows;    oid_t tableId = first;    for (desc = dbTableDescriptor::chain; desc != NULL; desc = next) {        next = desc->next;        if (desc->db != NULL && desc->db != DETACHED_TABLE && desc->db != this) {             continue;        }        if (desc->db == DETACHED_TABLE) {            desc = desc->clone();        }        dbFieldDescriptor* fd;        for (fd = desc->firstField; fd != NULL; fd = fd->nextField) {            fd->tTree = 0;            fd->hashTable = 0;

⌨️ 快捷键说明

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