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

📄 database.cpp

📁 一个功能强大的内存数据库源代码,c++编写,有详细的注释
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		::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;	    fd->attr &= ~dbFieldDescriptor::Updated;	}	int n = nTables;	while (--n >= 0) {	    dbTable* table = (dbTable*)getRow(tableId);	    oid_t next = table->next;	    if (strcmp(desc->name, (char*)table + table->name.offs) == 0) {		if (!desc->equal(table)) { 		    if (!alter) { 			handleError(DatabaseOpenError, "Incompatible class"				    " definition in application");			return false;		    }		    modified = true;		    if (table->nRows == 0) { 			TRACE_MSG(("Replace definition of table '%s'\n", 				   desc->name));			updateTableDescriptor(desc, tableId);		    } else { 			reformatTable(tableId, desc);		    } 		} else { 		    linkTable(desc, tableId);		}		desc->setFlags();		break;	    }	    if (tableId == last) {		tableId = first;	    } else { 		tableId = next;	    }	}	if (n < 0) { // no match found	    if (accessType == dbReadOnly || accessType == dbConcurrentRead) { 		handleError(DatabaseOpenError, "New table definition can not "			    "be added to read only database");		return false;	    } else {     		TRACE_MSG(("Create new table '%s' in database\n", desc->name));		addNewTable(desc);		modified = true;	    }	}	if (accessType != dbReadOnly && accessType != dbConcurrentRead) { 	    if (!addIndices(alter, desc)) { 		handleError(DatabaseOpenError, "Failed to alter indices with"			    " active applications");		rollback();		return false;	    }	}    }	    for (desc = tables; desc != NULL; desc = desc->nextDbTable) {	if (desc->cloneOf != NULL) {	    for (dbFieldDescriptor *fd = desc->firstField; fd != NULL; fd = fd->nextField)	    {		if (fd->refTable != NULL) {		    fd->refTable = lookupTable(fd->refTable);		}	    }	}	desc->checkRelationship();    }    commit();    return true;} void dbDatabase::reformatTable(oid_t tableId, dbTableDescriptor* desc){    dbTable* table = (dbTable*)putRow(tableId);    if (desc->match(table, confirmDeleteColumns)) { 	TRACE_MSG(("New version of table '%s' is compatible with old one\n", 		   desc->name));	updateTableDescriptor(desc, tableId);    } else { 	TRACE_MSG(("Reformat table '%s'\n", desc->name));	oid_t oid = table->firstRow;	updateTableDescriptor(desc, tableId);	while (oid != 0) { 	    dbRecord* record = getRow(oid);	    size_t size = 		desc->columns->calculateNewRecordSize((byte*)record, 						     desc->fixedSize);	    offs_t offs = currIndex[oid];	    record = putRow(oid, size);	    byte* dst = (byte*)record;	    byte* src = baseAddr + offs;	    desc->columns->convertRecord(dst, src, desc->fixedSize);	    oid = record->next;	}    }} void dbDatabase::deleteTable(dbTableDescriptor* desc){    beginTransaction(dbExclusiveLock);    modified = true;    dbTable* table = (dbTable*)putRow(desc->tableId);    oid_t rowId = table->firstRow;    table->firstRow = table->lastRow = 0;    table->nRows = 0;	    while (rowId != 0) {	dbRecord* record = getRow(rowId);	oid_t nextId = record->next;	size_t size = record->size;		removeInverseReferences(desc, rowId);	if (rowId < committedIndexSize && index[0][rowId] == index[1][rowId]) {	    cloneBitmap(currIndex[rowId], size);	} else { 	    deallocate(currIndex[rowId], size);	}	freeId(rowId);	rowId = nextId;    }    dbFieldDescriptor* fd;    for (fd = desc->hashedFields; fd != NULL; fd = fd->nextHashedField) { 	dbHashTable::purge(this, fd->hashTable);    }     for (fd = desc->indexedFields; fd != NULL; fd = fd->nextIndexedField) { 	dbTtree::purge(this, fd->tTree);    } } void dbDatabase::dropHashTable(dbFieldDescriptor* fd){    beginTransaction(dbExclusiveLock);    modified = true;    dbHashTable::drop(this, fd->hashTable);    fd->hashTable = 0;    fd->indexType &= ~HASHED;    dbFieldDescriptor** fpp = &fd->defTable->hashedFields;    while (*fpp != fd) { 	fpp = &(*fpp)->nextHashedField;    }    *fpp = fd->nextHashedField;    dbTable* table = (dbTable*)putRow(fd->defTable->tableId);    dbField* field = (dbField*)((char*)table + table->fields.offs);    field[fd->fieldNo].hashTable = 0;}void dbDatabase::dropIndex(dbFieldDescriptor* fd){    beginTransaction(dbExclusiveLock);    modified = true;    dbTtree::drop(this, fd->tTree);    fd->tTree = 0;    fd->indexType &= ~INDEXED;    dbFieldDescriptor** fpp = &fd->defTable->indexedFields;    while (*fpp != fd) { 	fpp = &(*fpp)->nextIndexedField;    }    *fpp = fd->nextIndexedField;    dbTable* table = (dbTable*)putRow(fd->defTable->tableId);    dbField* field = (dbField*)((char*)table + table->fields.offs);    field[fd->fieldNo].tTree = 0;}void dbDatabase::createHashTable(dbFieldDescriptor* fd){    beginTransaction(dbExclusiveLock);    modified = true;    dbTable* table = (dbTable*)getRow(fd->defTable->tableId);    int nRows = table->nRows;    fd->hashTable = dbHashTable::allocate(this, 2*nRows);    fd->attr &= ~dbFieldDescriptor::Updated;    fd->nextHashedField = fd->defTable->hashedFields;    fd->defTable->hashedFields = fd;    fd->indexType |= HASHED;    table = (dbTable*)putRow(fd->defTable->tableId);    dbField* field = (dbField*)((char*)table + table->fields.offs);    field[fd->fieldNo].hashTable = fd->hashTable;    for (oid_t oid = table->firstRow; oid != 0; oid = getRow(oid)->next) {	dbHashTable::insert(this, fd->hashTable, oid, fd->type, fd->dbsSize, fd->dbsOffs,			    nRows);    }}void dbDatabase::createIndex(dbFieldDescriptor* fd){    beginTransaction(dbExclusiveLock);    modified = true;    fd->tTree = dbTtree::allocate(this);     fd->attr &= ~dbFieldDescriptor::Updated;    fd->nextIndexedField = fd->defTable->indexedFields;    fd->defTable->indexedFields = fd;    fd->indexType |= INDEXED;    dbTable* table = (dbTable*)putRow(fd->defTable->tableId);    dbField* field = (dbField*)((char*)table + table->fields.offs);    field[fd->fieldNo].tTree = fd->tTree;        for (oid_t oid = table->firstRow; oid != 0; oid = getRow(oid)->next) {	dbTtree::insert(this, fd->tTree, oid, fd->type, fd->dbsSize, fd->comparator, fd->dbsOffs);    }}void dbDatabase::dropTable(dbTableDescriptor* desc){    deleteTable(desc);    freeRow(dbMetaTableId, desc->tableId);    dbFieldDescriptor* fd;    for (fd = desc->hashedFields; fd != NULL; fd = fd->nextHashedField) { 	dbHashTable::drop(this, fd->hashTable);    }     for (fd = desc->indexedFields; fd != NULL; fd = fd->nextIndexedField) { 	dbTtree::drop(this, fd->tTree);    } }bool dbDatabase::addIndices(bool alter, dbTableDescriptor* desc){    dbFieldDescriptor* fd;    oid_t tableId = desc->tableId;    dbTable* table = (dbTable*)getRow(tableId);    int nRows = table->nRows;    oid_t firstId = table->firstRow;    int nNewIndices = 0;    int nDelIndices = 0;    for (fd = desc->firstField; fd != NULL; fd = fd->nextField) { 	if ((fd->indexType & HASHED) && fd->type != dbField::tpStructure) { 	    if (fd->hashTable == 0) { 		if (!alter && tableId < committedIndexSize		    && index[0][tableId] == index[1][tableId])		{		    // If there are some other active applications which 		    // can use this table, then they will not know		    // about newly created index, which leads to inconsistency		    return false;		}		fd->hashTable = dbHashTable::allocate(this, nRows);		nNewIndices += 1;		TRACE_MSG(("Create hash table for field '%s'\n", fd->name));	    }	} else if (fd->hashTable != 0) { 	    if (alter) { 		TRACE_MSG(("Remove hash table for field '%s'\n", fd->name));		nDelIndices += 1;		fd->hashTable = 0;	    } else { 		return false;	    }	}	if ((fd->indexType & INDEXED) && fd->type != dbField::tpStructure) { 	    if (fd->tTree == 0) { 		if (!alter && tableId < committedIndexSize		    && index[0][tableId] == index[1][tableId])		{		    return false;		}		fd->tTree = dbTtree::allocate(this);		nNewIndices += 1;		TRACE_MSG(("Create index for field '%s'\n", fd->name));	    }	} else if (fd->tTree != 0) { 	    if (alter) { 		nDelIndices += 1;		TRACE_MSG(("Remove index for field '%s'\n", fd->name));		fd->tTree = 0;	    } else { 		return false;	    }	}    }    if (nNewIndices > 0) { 	modified = true;	for (oid_t rowId = firstId; rowId != 0; rowId = getRow(rowId)->next) {	    for (fd = desc->hashedFields; fd != NULL; fd=fd->nextHashedField) {		if (fd->hashTable >= committedIndexSize 		    || index[0][fd->hashTable] != index[1][fd->hashTable]) 		{ 		    dbHashTable::insert(this, fd->hashTable, rowId, 					fd->type, fd->dbsSize, fd->dbsOffs, 2*nRows);		}	    }	    for (fd=desc->indexedFields; fd != NULL; fd=fd->nextIndexedField) {		if (fd->tTree >= committedIndexSize 		    || index[0][fd->tTree] != index[1][fd->tTree]) 		{ 		    dbTtree::insert(this, fd->tTree, rowId, 				    fd->type, fd->dbsSize, fd->comparator, fd->dbsOffs);		}	    }	}     }    if (nNewIndices + nDelIndices != 0) { 	table = (dbTable*)putRow(tableId);	offs_t fieldOffs = currIndex[tableId] + table->fields.offs;	for (fd = desc->firstField; fd != NULL; fd = fd->nextField) { 	    dbField* field = (dbField*)(baseAddr + fieldOffs);    	    if (field->hashTable != fd->hashTable) { 		if (field->hashTable != 0) { 		    assert(fd->hashTable == 0);		    modified = true;		    dbHashTable::drop(this, field->hashTable);		    field = (dbField*)(baseAddr + fieldOffs);		}		field->hashTable = fd->hashTable;	    }	    if (field->tTree != fd->tTree) { 		if (field->tTree != 0) { 		    assert(fd->tTree == 0);		    modified = true;		    dbTtree::drop(this, field->tTree);		    field = (dbField*)(baseAddr + fieldOffs);		}		field->tTree = fd->tTree;	    }	    fieldOffs += sizeof(dbField);	}    }    retur

⌨️ 快捷键说明

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