diff --git a/DBMS/DBMS/bufferManage.cpp b/DBMS/DBMS/bufferManage.cpp index 4bc09ff..f435c3b 100644 --- a/DBMS/DBMS/bufferManage.cpp +++ b/DBMS/DBMS/bufferManage.cpp @@ -10,6 +10,10 @@ FileBuffer::~FileBuffer(){ } } +int FileBuffer::size(){ + return bufmap.size(); +} + void FileBuffer::pop(){ if (!numPage) return; @@ -18,10 +22,11 @@ void FileBuffer::pop(){ if ( bufPage->dirty ) { //need amendments after finishing SysObject (linking fileID and file name) - //FileManage::writePageToFile(it->first.first, bufPage -> page, bufPage->page->header.fileId ); - FileManage::writePageToFile(it->first.first, bufPage -> page, TESTTABLEPATH ); + //FileManage::writePageToFile(it->first.second, bufPage -> page, bufPage->page->header.fileId ); + FileManage::writePageToFile(it->first.second, bufPage->page, TESTTABLEPATH ); } + delete bufPage->page; bufmap.erase(it); numPage--; } @@ -44,17 +49,18 @@ void FileBuffer::flush(){ } } -Node* FileBuffer::find(rowID id){ +Node* FileBuffer::findPage(rowID id){ map::iterator it = bufmap.find(id); return (it==bufmap.end())?NULL:it->second; } -Node* FileBuffer::find(int FileID, int PageID){ - return find(pair(FileID,PageID)); +Node* FileBuffer::findPage(int FileID, int PageID){ + return findPage(pair(FileID,PageID)); } Node* FileBuffer::readPage(int pageId, char* path){ - Node* pageNode = find(TESTFILEID, pageId); + //need amendments after finishing SysObject (linking fileID and file name) + Node* pageNode = findPage(TESTFILEID, pageId); if( pageNode ){ return pageNode; } @@ -68,7 +74,7 @@ Node* FileBuffer::readPage(int pageId, char* path){ } Node* newNode = new Node(newPage); - push(pair(header->fileId,header->pageId),newNode); + push(pair(header->fileId,header->pageId),newNode); return newNode; } @@ -86,20 +92,21 @@ void FileBuffer::insertData(char* tablename, recordEntry record) { char* path = TESTTABLEPATH; Node* attrPage = readPage(0,path), *dataPage; int fileid = attrPage->page->header.fileId; - attr* tableAttr = (attr*)(attrPage->page->data); + tableAttr* tableAttribute = (tableAttr*)(attrPage->page->data); int pageid = 1; while(true) { - if (tableAttr->pagenum <= pageid){ + if (tableAttribute->pagenum <= pageid){ dataPage = new Node(); dataPage->dirty = true; dataPage->page = new dbPage(); + dataPage->page->header.pageId = pageid; //庆姐给你跪了=.= dataPage->page->header.fileId = fileid; dataPage->page->header.firstFreeOffset = 0; dataPage->page->header.freeCount = PAGE_SIZE; push(fileid, pageid, dataPage); - tableAttr->pagenum++; + tableAttribute->pagenum++; attrPage->dirty = true; break; } else { @@ -112,7 +119,6 @@ void FileBuffer::insertData(char* tablename, recordEntry record) { } } } - cout << dataPage->page->header.firstFreeOffset << endl; char* data = new char[record.length]; data = record.getRecord(&record); @@ -121,9 +127,10 @@ void FileBuffer::insertData(char* tablename, recordEntry record) { dataUtility::bytefillbyte(dataPage->page->data, data, dataPage->page->header.firstFreeOffset, record.length); dataPage->page->header.freeCount -= record.length; if (firstoffset == -1) { - dataPage->page->header.firstFreeOffset = PAGE_SIZE - dataPage->page->header.freeCount; if (dataPage->page->header.freeCount < record.length) dataPage->page->header.firstFreeOffset = -1; + else + dataPage->page->header.firstFreeOffset = PAGE_SIZE - dataPage->page->header.freeCount; } else { dataPage->page->header.firstFreeOffset = firstoffset; } @@ -139,23 +146,30 @@ void FileBuffer::deleteData(char* tablename, int pageid, int offset, int recordl //char* path = getTablePath(tablename); need amendments after finishing SysObject (linking fileID and file name) char* path = TESTTABLEPATH; Node* dataPage = readPage(pageid, path); + if( dataPage == NULL ){ + cout << "************Error in reading page with pageID: " << pageid << " and Action aborted**************" << endl; + return; + } int firstOffset = dataPage->page->header.firstFreeOffset; if( firstOffset == -1 ){ //Full page dataPage->page->header.firstFreeOffset = offset; } else { if( firstOffset < offset ){ //Handle linked list sequence int linkedOffset; - do{ + while ( firstOffset < offset && firstOffset != -1 ){ char* srcTemp = dataUtility::getbyte(dataPage->page->data, firstOffset+recordlength-sizeof(int), sizeof(int)); linkedOffset = firstOffset; firstOffset = dataUtility::char2int(srcTemp); delete[] srcTemp; - } while ( firstOffset < offset && firstOffset != -1 ); + }; char *offsetChar = dataUtility::data_to_char(offset); dataUtility::bytefillbyte(dataPage->page->data, offsetChar, linkedOffset+recordlength-sizeof(int), sizeof(int)); delete[] offsetChar; } else { //Removed data become first free slot dataPage->page->header.firstFreeOffset = offset; + if( firstOffset == PAGE_SIZE - dataPage->page->header.freeCount ){ + firstOffset = -1; + } } char *offsetChar = dataUtility::data_to_char(firstOffset); dataUtility::bytefillbyte(dataPage->page->data, offsetChar, offset+recordlength-sizeof(int), sizeof(int)); @@ -166,10 +180,10 @@ void FileBuffer::deleteData(char* tablename, int pageid, int offset, int recordl cout << " after update firstoffset is : " << dataPage->page->header.firstFreeOffset << endl; } - void FileBuffer::updateData(char* tablename, int pageid, int offset, recordEntry record) { //char* path = getTablePath(tablename); need amendments after finishing SysObject (linking fileID and file name) char*path = TESTTABLEPATH; Node* dataPage = readPage(pageid, path); dataUtility::bytefillbyte(dataPage->page->data, record.getRecord(&record), offset, record.length); + dataPage->dirty = true; } \ No newline at end of file diff --git a/DBMS/DBMS/bufferManage.h b/DBMS/DBMS/bufferManage.h index 0850e10..7f23801 100644 --- a/DBMS/DBMS/bufferManage.h +++ b/DBMS/DBMS/bufferManage.h @@ -73,16 +73,18 @@ class FileBuffer{ public: FileBuffer(); ~FileBuffer(); + int size(); void pop(); void push(rowID id, Node* buffer); void push(int FileID, int PageID, Node* buffer); void flush(); - Node* find(rowID id); - Node* find(int FileID, int PageID); + Node* findPage(rowID id); + Node* findPage(int FileID, int PageID); Node* readPage(int pageId, char* path); void insertData(char* tablename, recordEntry record); void deleteData(char* tablename, int pageid, int offset, int recordlength); void updateData(char* tablename, int pageid, int offset, recordEntry record); + void searchData(char* tablename); private: int numPage; map bufmap; diff --git a/DBMS/DBMS/main.cpp b/DBMS/DBMS/main.cpp index 8b0455d..f78e082 100644 --- a/DBMS/DBMS/main.cpp +++ b/DBMS/DBMS/main.cpp @@ -7,29 +7,29 @@ int main() // test buffer FileBuffer fb; DBStorage testdb("studentManage", 0, 1); - attr tableAttr(3); + tableAttr tableAttribute(3); - tableAttr.coltype[0] = 0; - tableAttr.coltype[1] = 5; - tableAttr.coltype[2] = 5; + tableAttribute.coltype[0] = 0; + tableAttribute.coltype[1] = 5; + tableAttribute.coltype[2] = 5; - tableAttr.collen[0] = 4; //int(10) 10 is the max show length - tableAttr.collen[1] = 100; - tableAttr.collen[2] = 3; + tableAttribute.collen[0] = 4; //int(10) 10 is the max show length + tableAttribute.collen[1] = 100; + tableAttribute.collen[2] = 3; - tableAttr.colname[0] = "id"; - tableAttr.colname[1] = "name"; - tableAttr.colname[2] = "nation"; + tableAttribute.colname[0] = "id"; + tableAttribute.colname[1] = "name"; + tableAttribute.colname[2] = "nation"; - tableAttr.colIsNull[0] = false; - tableAttr.colIsNull[1] = false; - tableAttr.colIsNull[2] = true; + tableAttribute.colIsNull[0] = false; + tableAttribute.colIsNull[1] = false; + tableAttribute.colIsNull[2] = true; - tableAttr.primaryId = 0; - tableAttr.pagenum = 1; - testdb.createTable("studentinfo", "studentManage", tableAttr); + tableAttribute.primaryId = 0; + tableAttribute.pagenum = 1; + testdb.createTable("studentinfo", "studentManage", tableAttribute); - recordEntry onedata(3, tableAttr.collen); + recordEntry onedata(3, tableAttribute.collen); onedata.isdeleted = 0; onedata.isNull[0] = 0; onedata.isNull[1] = 0; @@ -43,15 +43,15 @@ int main() cout << onedata.item[2] << endl; // test data from insert to delete - for(int i = 0; i < 50; i++) { + for(int i = 0; i < 80; i++) { cout << "first insert index data: " << i < using namespace std; +class tableAttr{ +public: + int num; + int primaryId; + int pagenum; + string *colname; + int* coltype; //0-int 1-double 2-float 3-char 4-string 5-varchar 6-boolean + int* collen; + bool* colIsNull; + tableAttr(int num_v){ + num = num_v; + pagenum = 0; //first attr page is also a count + colname = new string[num]; + coltype = new int[num]; + collen = new int[num]; + colIsNull = new bool[num]; + }; +}; + class pageHeader { public: int pageId; @@ -28,23 +47,4 @@ class dbPage { strcpy(data,src); } }; - -class attr{ -public: - int num; - int primaryId; - int pagenum; - string *colname; - int* coltype; //0-int 1-double 2-float 3-char 4-string 5-varchar 6-boolean - int* collen; - bool* colIsNull; - attr(int num_v){ - num = num_v; - pagenum = 0; //first attr page is also a count - colname = new string[num]; - coltype = new int[num]; - collen = new int[num]; - colIsNull = new bool[num]; - }; -}; #endif \ No newline at end of file diff --git a/DBMS/DBMS/recordManage.cpp b/DBMS/DBMS/recordManage.cpp index 0cdce3e..cb09ecb 100644 --- a/DBMS/DBMS/recordManage.cpp +++ b/DBMS/DBMS/recordManage.cpp @@ -12,15 +12,16 @@ DBStorage::~DBStorage() { } char* DBStorage::getTablePath(char* tablename) { - char* path = new char[strlen(tablename) + dbname.size() + 3]; + char* path = new char[strlen(tablename) + dbname.size() + 4]; strcpy(path,"./"); strcat(path,dbname.c_str()); strcat(path,"/"); strcat(path,tablename); + strcat(path,"\0"); return path; } -void DBStorage::createTable(char* filename, char* databasename, attr tableinfo) { +void DBStorage::createTable(char* filename, char* databasename, tableAttr tableinfo) { /* * for a simple example @@ -31,19 +32,16 @@ void DBStorage::createTable(char* filename, char* databasename, attr tableinfo) dbPage test; test.header.pageId = 0; test.header.fileId = filenum+1; - test.header.firstFreeOffset = sizeof(attr)+1; // the offset for the first free room. - test.header.freeCount = PAGE_SIZE-sizeof(attr); //the size of page free + test.header.firstFreeOffset = sizeof(tableAttr); // the offset for the first free room (no need to +1). + test.header.freeCount = PAGE_SIZE-sizeof(tableAttr); //the size of page free test.header.rowCount =0; char* path = getTablePath(filename); - memcpy(test.data, &tableinfo, sizeof(attr)); + memcpy(test.data, &tableinfo, sizeof(tableAttr)); FileManage::writePageToFile(test.header.pageId, &test, path); this->filenum++; - - dbPage* result = new dbPage(); - FileManage::readPageFromFile(0, result, path); - + delete[] path; cout << "************************End Create Table**********************" << endl; } @@ -51,144 +49,6 @@ void DBStorage::createDataBase(char* databasename) { FileManage::createFileFolder(databasename); } -void DBStorage::insertData(char* tablename, recordEntry record) { - /* - *INSERT INTO publisher VALUES - *(100008,'Oxbow Books Limited','PRC'); - */ - - //cout << "************************Start Insert Data**********************" << endl; - //cout << "insertData--data length: " << record.length << endl; - //cout << "Data length" << record.length << endl; - - dbPage* attrPageInfo = new dbPage(); - dbPage* pageInfo = new dbPage(); - char* path = getTablePath(tablename); - - FileManage::readPageFromFile(0, attrPageInfo, path); - int fileid = attrPageInfo->header.fileId; - attr* tableAttr = dataUtility::char_to_class(attrPageInfo->data); - int pageid = 1; - - while(true) { - //cout << " 1page num: " << tableAttr->pagenum << endl; - if (tableAttr->pagenum <= pageid) - { - pageInfo->header.fileId = fileid; - pageInfo->header.firstFreeOffset = 0; - pageInfo->header.freeCount = PAGE_SIZE; - //cout << "new page id: " << pageid << endl; - - tableAttr->pagenum++; - //cout << " 2page num: " << tableAttr->pagenum << endl; - - memcpy(attrPageInfo->data, tableAttr, sizeof(attr)); - FileManage::writePageToFile(0, attrPageInfo, path); - tableAttr = dataUtility::char_to_class(attrPageInfo->data); - //cout << " 3pagenum: " << tableAttr->pagenum << endl; - break; - } else { - FileManage::readPageFromFile(pageid, pageInfo, path); - if (pageInfo->header.freeCount >= record.length) - { - //cout << "exist page id: " << pageid << " freecount: " << pageInfo->header.freeCount << endl; - break; - } else { - //cout << "into the next page" << endl; - pageid++; - FileManage::readPageFromFile(pageid, pageInfo, path); - } - } - } - cout << pageInfo->header.firstFreeOffset << endl; - char* data = new char[record.length]; - data = record.getRecord(&record); - - - char* temp = dataUtility::getbyte(pageInfo->data, pageInfo->header.firstFreeOffset+record.length-sizeof(int), sizeof(int)); - int firstoffset = dataUtility::char2int(temp); - dataUtility::bytefillbyte(pageInfo->data, data, pageInfo->header.firstFreeOffset, record.length); - cout << "firstoffset next list node: " << firstoffset << endl; - pageInfo->header.freeCount -= record.length; - if (firstoffset == -1) { - pageInfo->header.firstFreeOffset = PAGE_SIZE - pageInfo->header.freeCount; - if (pageInfo->header.freeCount < record.length) - pageInfo->header.firstFreeOffset = -1; - } else { - pageInfo->header.firstFreeOffset = firstoffset; - } - FileManage::writePageToFile(pageid, pageInfo, path); - dbPage* readtest = new dbPage(); - FileManage::readPageFromFile(pageid, readtest, path); - cout << "write into page id: " << pageid << " after update firstoffset is " << pageInfo->header.firstFreeOffset << endl; - //cout << "************************End Insert Data**********************" << endl; - delete attrPageInfo; - delete pageInfo; - delete readtest; - delete[] temp; - delete[] data; -} - -void DBStorage::deleteData(char* tablename, int pageid, int offset, int recordlength) { - if (offset > PAGE_SIZE) - return; - char* path = getTablePath(tablename); - dbPage* pageInfo = new dbPage(); - FileManage::readPageFromFile(pageid, pageInfo, path); - - int firstOffset = pageInfo->header.firstFreeOffset; - if( firstOffset == -1 ){ //Full page - pageInfo->header.firstFreeOffset = offset; - } else { - if( firstOffset < offset ){ //Handle linked list sequence - int linkedOffset; - do{ - char* srcTemp = dataUtility::getbyte(pageInfo->data, firstOffset+recordlength-sizeof(int), sizeof(int)); - linkedOffset = firstOffset; - firstOffset = dataUtility::char2int(srcTemp); - delete[] srcTemp; - } while ( firstOffset < offset && firstOffset != -1 ); - char *offsetChar = dataUtility::data_to_char(offset); - dataUtility::bytefillbyte(pageInfo->data, offsetChar, linkedOffset+recordlength-sizeof(int), sizeof(int)); - delete[] offsetChar; - } else { //Removed data become first free slot - pageInfo->header.firstFreeOffset = offset; - } - char *offsetChar = dataUtility::data_to_char(firstOffset); - dataUtility::bytefillbyte(pageInfo->data, offsetChar, offset+recordlength-sizeof(int), sizeof(int)); - delete[] offsetChar; - } - pageInfo->header.freeCount += recordlength; - FileManage::writePageToFile(pageid, pageInfo, path); - - /*//最后的从来没有写过数据的offset一定在offset链表的最后,因为每次insert都会先插deleted=1的地方 - if (!dataUtility::char_to_bool(pageInfo->data[offset])) { - pageInfo->data[offset] = '1'; - dataUtility::bytefillbyte(pageInfo->data, dataUtility::int_to_char(pageInfo->header.firstFreeOffset), - offset+recordlength-sizeof(int), sizeof(int)); - pageInfo->header.firstFreeOffset = offset; - cout << "delete data " << endl; - pageInfo->header.freeCount += recordlength; - FileManage::writePageToFile(pageid, pageInfo, path); - printFreeList(tablename, pageid, recordlength); - }*/ - - cout << " after update firstoffset is : " << pageInfo->header.firstFreeOffset << endl; - delete pageInfo; -} - - -void DBStorage::updateData(char* tablename, int pageid, int offset, recordEntry record) { - char* path = getTablePath(tablename); - dbPage* pageInfo = new dbPage(); - FileManage::readPageFromFile(pageid, pageInfo, path); - dataUtility::bytefillbyte(pageInfo->data, record.getRecord(&record), offset, record.length); - FileManage::writePageToFile(pageid, pageInfo, path); -} - -void DBStorage::searchData(char* tablename) { -} - void DBStorage::printFreeList(char* tablename, int pageid, int recordlength) { char* path = getTablePath(tablename); dbPage* pageInfo = new dbPage(); @@ -201,4 +61,5 @@ void DBStorage::printFreeList(char* tablename, int pageid, int recordlength) { offset = *temp; } cout << endl; + delete pageInfo; } \ No newline at end of file diff --git a/DBMS/DBMS/recordManage.h b/DBMS/DBMS/recordManage.h index 94dc3df..690f163 100644 --- a/DBMS/DBMS/recordManage.h +++ b/DBMS/DBMS/recordManage.h @@ -10,13 +10,9 @@ class DBStorage{ UINT filenum; DBStorage(string dbname, UINT dbid, bool isCreate); ~DBStorage(); - void createTable(char* filename,char* databasename, attr tableinfo); + void createTable(char* filename,char* databasename, tableAttr tableinfo); void createDataBase(char* databasename); - void insertData(char* tablename, recordEntry record); - void deleteData(char* tablename, int pageid, int offset, int recordlength); - void updateData(char* tablename, int pageid, int offset, recordEntry record); void printFreeList(char* tablename, int pageid, int recordlength); - void searchData(char* tablename); char* getTablePath(char* tablename); }; diff --git a/DBMS/DBMS/studentManage/studentinfo b/DBMS/DBMS/studentManage/studentinfo index 21a628e..13c0ba1 100644 Binary files a/DBMS/DBMS/studentManage/studentinfo and b/DBMS/DBMS/studentManage/studentinfo differ