Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 143 additions & 20 deletions DBMS/DBMS/bufferManage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,173 @@ FileBuffer::FileBuffer(){
numPage = 0;
}

Node* FileBuffer::remove(){
if (!numPage) return NULL;
FileBuffer::~FileBuffer(){
while(numPage > 0){
pop();
}
}

void FileBuffer::pop(){
if (!numPage) return;

map<rowID, Node*>::iterator it = bufmap.end();
Node* bufPage = (--it)->second;
map<rowID, Node*>::iterator it = bufmap.begin();
Node* bufPage = it->second;

if ( bufPage->dirty ) {
//FileManage::writePageToFile(it->first.first, bufPage -> page
// , bufPage->page->header.fileId );
//FileManage::writePageToFile(it->first.first, bufPage -> page, bufPage->page->header.fileId );
FileManage::writePageToFile(it->first.first, bufPage -> page, TESTTABLEPATH );
}

bufmap.erase(it);
numPage--;
return bufPage;
}

void FileBuffer::push(rowID id, Node* buffer){
if ( numPage == DB_MAX_BUFFER_SIZE ) {
pop();
}
bufmap[id] = buffer;
numPage++;
}

void FileBuffer::push(int FileID, int PageID, Node* buffer){
push(pair<int, int>(FileID, PageID), buffer);
}

void FileBuffer::refresh(){
while(numPage > 0){
pop();
}
}

Node* FileBuffer::find(rowID id){
map<rowID, Node*>::iterator it = bufmap.find(id);
return (it==bufmap.end())?NULL:it->second;
}

Node* FileBuffer::find(int FileID, int PageID){
return find(pair<int,int>(FileID,PageID));
}

Node* FileBuffer::readPage(int pageId, char* path){
//add find rowID after finishing fileid mapping
Node* pageNode = find(TESTFILEID, pageId);
if( pageNode ){
return pageNode;
}

dbPage* newPage = new dbPage();
FileManage::readPageFromFile(pageId, newPage, path);
pageHeader* header = &(newPage->header);
if(header->fileId == 0){
delete newPage;
return NULL;
}

Node* newNode = new Node(newPage);
insert(pair<UINT,UINT>(header->fileId,header->pageId),newNode);
push(pair<UINT,UINT>(header->fileId,header->pageId),newNode);
return newNode;
}

void FileBuffer::insert(rowID id, Node* buffer){
if ( numPage == DB_MAX_BUFFER_SIZE ) {
cout << "buffer is full" << endl;
remove();
void FileBuffer::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;

//char* path = getTablePath(tablename);
char* path = TESTTABLEPATH;
Node* attrPage = readPage(0,path), *dataPage;
int fileid = attrPage->page->header.fileId;
attr* tableAttr = (attr*)(attrPage->page->data);
int pageid = 1;

while(true) {
if (tableAttr->pagenum <= pageid){
dataPage = new Node();
dataPage->dirty = true;
dataPage->page = new dbPage();
dataPage->page->header.fileId = fileid;
dataPage->page->header.firstFreeOffset = 0;
dataPage->page->header.freeCount = PAGE_SIZE;
push(fileid, pageid, dataPage);

tableAttr->pagenum++;
attrPage->dirty = true;
break;
} else {
dataPage = readPage(pageid, path);
if (dataPage->page->header.freeCount >= record.length){
dataPage->dirty = true;
break;
} else {
pageid++;
}
}
}
bufmap[id] = buffer;
numPage++;
cout << dataPage->page->header.firstFreeOffset << endl;
char* data = new char[record.length];
data = record.getRecord(&record);

char* temp = dataUtility::getbyte(dataPage->page->data, dataPage->page->header.firstFreeOffset+record.length-sizeof(int), sizeof(int));
int firstoffset = dataUtility::char2int(temp);
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 = firstoffset;
}
cout << "write into page id: " << pageid << " after update firstoffset is " << dataPage->page->header.firstFreeOffset << endl;
//cout << "************************End Insert Data**********************" << endl;
delete[] temp;
delete[] data;
}

Node* FileBuffer::find(rowID id){
map<rowID, Node*>::iterator it = bufmap.find(id);
return (it==bufmap.end())?NULL:it->second;
void FileBuffer::deleteData(char* tablename, int pageid, int offset, int recordlength) {
if (offset > PAGE_SIZE)
return;
//char* path = getTablePath(tablename);
char* path = TESTTABLEPATH;
Node* dataPage = readPage(pageid, path);
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{
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<int>(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;
}
char *offsetChar = dataUtility::data_to_char<int>(firstOffset);
dataUtility::bytefillbyte(dataPage->page->data, offsetChar, offset+recordlength-sizeof(int), sizeof(int));
delete[] offsetChar;
}
dataPage->page->header.freeCount += recordlength;
dataPage->dirty = true;
cout << " after update firstoffset is : " << dataPage->page->header.firstFreeOffset << endl;
}

Node* FileBuffer::find(UINT FileID, UINT PageID){
return find(pair<UINT,UINT>(FileID,PageID));

void FileBuffer::updateData(char* tablename, int pageid, int offset, recordEntry record) {
//char* path = getTablePath(tablename);
char*path = TESTTABLEPATH;
dbPage* pageInfo = new dbPage();
FileManage::readPageFromFile(pageid, pageInfo, path);
dataUtility::bytefillbyte(pageInfo->data, record.getRecord(&record), offset, record.length);
FileManage::writePageToFile(pageid, pageInfo, path);
}
65 changes: 57 additions & 8 deletions DBMS/DBMS/bufferManage.h
Original file line number Diff line number Diff line change
@@ -1,17 +1,62 @@
#ifndef __NODE__H__
#define __NODE__H__

#include "data_utility.h"
#include "fileManage.h"
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <map>

#define TESTTABLEPATH "./studentManage/studentinfo"
#define TESTFILEID 1

using namespace std;

typedef pair<UINT,UINT> rowID;
typedef pair<int,int> rowID;

struct recordEntry {
bool isdeleted;
bool* isNull;
char** item; //C++ byte is defined for unsigned char
int length;
int num;
int* itemlen;
int offset;
recordEntry(int num_v, int* itemlen_v){
num = num_v;
isNull = new bool[num];
item = new char*[num];
itemlen = new int[num];
length = 1+num+4;
for (int i = 0; i < num; i++) {
itemlen[i] = itemlen_v[i];
item[i] = new char[itemlen[i]];
length += itemlen[i];
}
offset = -1;
}
char* getRecord(recordEntry* record){
char* res = new char[record->length+1];
res[0] = dataUtility::bool_to_byte(record->isdeleted);
for (int i = 0; i < num; i++) {
res[1+i]=dataUtility::bool_to_byte(record->isNull[i]);
}

int index = 1+num;
for (int i = 0; i < num; i++) {
dataUtility::bytefillbyte(res, record->item[i],index);
index = index + record->itemlen[i];
}

char* freeOffset = dataUtility::data_to_char<int>(record->offset);
dataUtility::bytefillbyte(res, freeOffset, index, 4);
res[record->length] = 0;
delete[] freeOffset;
return res;
}
};

class FileBuffer;
struct Node{
bool dirty;
dbPage* page;
Expand All @@ -24,20 +69,24 @@ struct Node{
}
};


//���ÿ���ļ�һ������
class FileBuffer{
public:
FileBuffer();
~FileBuffer();
void pop();
void push(rowID id, Node* buffer);
void push(int FileID, int PageID, Node* buffer);
void refresh();
Node* find(rowID id);
Node* find(int FileID, int PageID);
Node* readPage(int pageId, char* path);
Node* remove(); //�Ӷ��е�β��ɾ��������map��ɾ����usepagenum --
void insert(rowID id, Node* buffer); //������ף�����map��usepagenum ++
Node* find(rowID id); //���ڣ����ؽڵ㣻���򣬷���NULL
Node* find(UINT FileID, UINT PageID);
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);
private:
int numPage;
map<rowID, Node*> bufmap; //�ܹ�����rowid�����ҵ�Node
map<rowID, Node*> bufmap;
};


Expand Down
3 changes: 2 additions & 1 deletion DBMS/DBMS/data_utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,12 @@ void dataUtility::bytefillbyte(char* dst, char* src, int index, int length) {
}
}
char* dataUtility::getbyte(char* src, int start, int length) {
char* data = (char*) malloc(length);
char* data = (char*) malloc(length+1);
for (int i = 0; i < length; i++)
{
data[i] = src[start+i];
}
data[length] = 0;
return data;
}

Expand Down
7 changes: 4 additions & 3 deletions DBMS/DBMS/data_utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@ class dataUtility {
public:
template<typename T>
static char* data_to_char(T ori){
char* data = (char*) malloc(sizeof(T));
char* data = (char*) malloc(sizeof(T)+1);
memcpy(data, &ori, sizeof(T));
cout << "size: " << sizeof(T) << " data size " << strlen(data)<< endl;
data[sizeof(T)] = 0;
return data;
};

template<typename T>
static char* data_to_char(T ori, int length){
char* data = (char*) malloc(length);
char* data = (char*) malloc(length+1);
memcpy(data, &ori, length);
data[length] = 0;
return data;
};

Expand Down
20 changes: 10 additions & 10 deletions DBMS/DBMS/fileManage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,28 @@ void FileManage::writePageToFile(int pageid, dbPage* pagedata, char* filename){
originfilestream = fopen(filename,"rb");
updatefilestream = fopen(updatefilename, "wb+");
if (originfilestream == NULL) {
fseek(updatefilestream, pageid*sizeof(dbPage), SEEK_SET);
fwrite(pagedata,sizeof(dbPage), 1, updatefilestream);
fseek(updatefilestream, pageid*DB_PGSIZE, SEEK_SET);
fwrite(pagedata, DB_PGSIZE, 1, updatefilestream);
} else {
int pageno = -1;
char data[sizeof(dbPage)];
memset(data, 0, sizeof(dbPage));
while(fread(data, sizeof(char), sizeof(dbPage), originfilestream)) {
char data[DB_PGSIZE];
memset(data, 0, DB_PGSIZE);
while(fread(data, sizeof(char), DB_PGSIZE, originfilestream)) {
pageno = pageno + 1;
if (pageid == pageno) {
fwrite(pagedata,sizeof(dbPage),1, updatefilestream);
fwrite(pagedata, DB_PGSIZE, 1, updatefilestream);
//cout << "update the page pageno: " << pageno << endl;
}
else {
fwrite(data, sizeof(char), sizeof(dbPage), updatefilestream);
fwrite(data, sizeof(char), DB_PGSIZE, updatefilestream);
//cout << "copy origin file pageno " << pageno << endl;
}
memset(data, 0, sizeof(dbPage));
memset(data, 0, DB_PGSIZE);
}
if (pageid > pageno)
{
fseek(updatefilestream, pageid*sizeof(dbPage), SEEK_SET);
fwrite(pagedata,sizeof(char), sizeof(dbPage), updatefilestream);
fseek(updatefilestream, pageid*DB_PGSIZE, SEEK_SET);
fwrite(pagedata, sizeof(char), DB_PGSIZE, updatefilestream);
}

fclose(originfilestream);
Expand Down
Loading