📄 xkmemcoordinator.cpp
字号:
// xkMemCoordinator.cpp: implementation of the xkMemCoordinator class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "xkDBMS.h"
#include "xkMemCoordinator.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
extern xkDict *pDict_;
extern const char* sysdir_;
extern xkMemCoordinator *pMem_;
/*
bool operator == (const char* lhs_, const char* rhs_)
{
if(strlen(lhs_) != strlen(rhs_))
return false;
return strcmp(lhs_, rhs_) ? false : true;
}
*/
xkMemCoordinator::~xkMemCoordinator()
{
SaveAll();
for(size_t i = 0; i < tableset_.size(); i++)
if(tableset_[i])
delete tableset_[i];
}
int xkMemCoordinator::GetPage()
{
if(freepages_ == 0)
return -1;
int i;
for(i = 0; i < PAGECOUNT; i++)
{
if(pagemap_[i] == 0)
{
pagemap_[i] = 1;//used
freepages_--;
break;
}
}
if(i == PAGECOUNT)
return -1;
return i;
}
xkTable* xkMemCoordinator::GetTable(const size_t RID_)
{
xkTable ** iterator_;
for(iterator_ = tableset_.begin(); iterator_ != tableset_.end(); iterator_++)
{
if((*iterator_)->RID_ == RID_)
{
return *iterator_;
}
}
return 0;
}
/*
* 为数据字典中的关系建立内模式映射
即在内模式中登记该表信息
*/
void xkMemCoordinator::CreateTable(const size_t RID_)
{
xkRelation* pr_ = pDict_->GetRelation(RID_);
xkTable *pt_ = new xkTable;
pt_->RID_ = RID_;
pt_->tablename_ =new char[strlen(pr_->GetRelationName())+1];
strcpy(pt_->tablename_, pr_->GetRelationName());
pt_->firstpage_ = new xkPageItem;
pt_->firstpage_->pagenumber_ = GetPage();
pt_->firstpage_->record_count_ = 0;
pt_->allocated_pages_ = 1;
pt_->curpage_ = pt_->firstpage_;
pt_->cursor_ = 0;
pt_->rcount_ = 0;
tableset_.push_back(pt_);
if(pr_->GetTupleCount() != 0)
LoadTable(RID_);
}
/*
* 释放内存中该表的空间,并删除该表的登记信息
*/
void xkMemCoordinator::DropTable(const size_t RID_)
{
xkTable* pt_ = 0;
pt_ = GetTable(RID_);
if(pt_ == 0)
return;//内存中不存在该表,则返回
// xkRelation* pr_ = pDict_->GetRelation(RID_);
// assert(pr_ != 0);
// pr_->SetOpened(false);//表示该关系没有打开
LPxkPageItem prev_, p = pt_->firstpage_;
while (p)
{
SetFreePage(p->pagenumber_);
prev_ = p;
p = p->next_;
delete prev_;
prev_ = 0;
}
//delete this table from xkMemCoordinator
xkTable ** iterator_;
for(iterator_ = tableset_.begin(); iterator_ != tableset_.end(); iterator_++)
{
if((*iterator_)->RID_ == RID_)
{
tableset_.erase(iterator_);
break;
}
}
delete pt_;
}
/*
* 调用之前该表已在内模式中登记过了
从数据字典中获取该表的信息,
将表数据从外存装入内存
*/
void xkMemCoordinator::LoadTable(const size_t RID_)
{
xkRelation* pr_ = pDict_->GetRelation(RID_);
assert(pr_ != 0);
xkTable * pt_ = GetTable(RID_);
assert(pt_ != 0);
char* tname_ = pr_->GetRelationName();
char* tablename_ = new char[strlen(sysdir_) + strlen("\\") + strlen(tname_) + 1];
strcpy(tablename_, sysdir_);
strcat(tablename_, "\\");
strcat(tablename_, tname_);
FILE *fp;
fp = fopen(tablename_, "rb");//写入为wb+时,这里必须是rb选项,否则会出错
if(fp == NULL)
{
AfxMessageBox("无法打开表文件!");
return;
}
size_t tuplesize_ = pr_->GetTuple()->GetTupleSize();
xkAttribute *pa_ = pr_->GetTuple()->GetAttributes();
size_t ac_ = pr_->GetTuple()->GetAttrCount();
size_t pos_ = 0;
size_t i;
for(i = 0; i < ac_; i++)
{
if(pa_[i].IsKey())
break;
pos_ += pa_[i].GetLength();
}
assert(pos_ < tuplesize_);//pos_ is the position of keyword
//load data from disk
size_t recordcount_; //表的记录数
size_t pages_; //所需的内存页数
size_t count_in_a_page_; //一页能存的记录数
recordcount_ = pr_->GetTupleCount();
count_in_a_page_ = PAGESIZE/(pr_->GetTuple()->GetTupleSize());
pages_ = recordcount_/count_in_a_page_ + 1;
if(freepages_ < pages_)
return;// no enough pages to allocate
if(recordcount_ <= count_in_a_page_)//need only a page
{
char* tmp_ = new char[tuplesize_ + 1];
for(size_t k = 0; k < recordcount_; k++)
{
int fcount_ = 0;
fcount_ = fread(tmp_, 1, tuplesize_, fp);
if(feof(fp))
return;
if(fcount_ != tuplesize_)
return;
tmp_[tuplesize_] = '\0';
memcpy(mem_ + PAGESIZE*pt_->firstpage_->pagenumber_ + k*tuplesize_, tmp_, tuplesize_);
pt_->firstpage_->record_count_++;
//insert hashtable
char* p = new char[pa_[i].GetLength() + 1];//get the value of key
strcpy(p, ((const char*)tmp_ + pos_));
LPxkRecordItem pRI_ = new xkRecordItem;
pRI_->pageno_ = pt_->firstpage_->pagenumber_;
pRI_->recordno_ = k;
assert(pt_->hashtable_.insert(p, pRI_) == true);
}
delete[] tmp_;
/*
int block_ = pr_->GetTuple()->GetTupleSize()*recordcount_;
fread(mem_ + PAGESIZE * pt_->firstpage_->pagenumber_, block_, 1, fp);
pt_->firstpage_->record_count_ = recordcount_;
pt_->allocated_pages_++;
pt_->curpage_ = pt_->firstpage_;
*/
}
else
{
char* tmp_ = new char[tuplesize_ + 1];
for(size_t k = 0; k < count_in_a_page_; k++)
{
int fcount_ = 0;
fcount_ = fread(tmp_, 1, tuplesize_, fp);
if(feof(fp))
return;
if(fcount_ != tuplesize_)
return;
tmp_[tuplesize_] = '\0';
memcpy(mem_ + PAGESIZE*pt_->firstpage_->pagenumber_ + k*tuplesize_, tmp_, tuplesize_);
pt_->firstpage_->record_count_++;
//insert hashtable
char* p = new char[pa_[i].GetLength() + 1];//get the value of key
strcpy(p, ((const char*)tmp_ + pos_));
LPxkRecordItem pRI_ = new xkRecordItem;
pRI_->pageno_ = pt_->firstpage_->pagenumber_;
pRI_->recordno_ = k;
assert(pt_->hashtable_.insert(p, pRI_) == true);
}
delete[] tmp_;
/*
int block_ = pr_->GetTuple()->GetTupleSize()*count_in_a_page_;
fread(mem_ + PAGESIZE * pt_->firstpage_->pagenumber_, block_, 1, fp);
pt_->firstpage_->record_count_ = count_in_a_page_;
pt_->allocated_pages_++;
pt_->curpage_ = pt_->firstpage_;
*/
LPxkPageItem link_ = pt_->firstpage_;
for(size_t i = 1; i < pages_; i++)
{
link_->next_ = new xkPageItem;
link_ = link_->next_;
link_->pagenumber_ = (size_t)GetPage();
if((recordcount_ - i*count_in_a_page_) > count_in_a_page_)
{
char* tmp_ = new char[tuplesize_ + 1];
for(size_t k = 0; k < count_in_a_page_; k++)
{
int fcount_ = 0;
fcount_ = fread(tmp_, 1, tuplesize_, fp);
if(feof(fp))
return;
if(fcount_ != tuplesize_)
return;
tmp_[tuplesize_] = '\0';
memcpy(mem_ + PAGESIZE*link_->pagenumber_ + k*tuplesize_, tmp_, tuplesize_);
link_->record_count_++;
//insert hashtable
char* p = new char[pa_[i].GetLength() + 1];//get the value of key
strcpy(p, ((const char*)tmp_ + pos_));
LPxkRecordItem pRI_ = new xkRecordItem;
pRI_->pageno_ = link_->pagenumber_;
pRI_->recordno_ = k;
assert(pt_->hashtable_.insert(p, pRI_) == true);
}
delete[] tmp_;
/*
int block_ = pr_->GetTuple()->GetTupleSize()*count_in_a_page_;
fread(mem_ + PAGESIZE * link_->pagenumber_, block_, 1, fp);
link_->record_count_ = count_in_a_page_;
pt_->allocated_pages_++;
*/
}
else//the last page
{
char* tmp_ = new char[tuplesize_ + 1];
for(size_t k = 0; k < (recordcount_ - i*count_in_a_page_); k++)
{
int fcount_ = 0;
fcount_ = fread(tmp_, 1, tuplesize_, fp);
if(feof(fp))
return;
if(fcount_ != tuplesize_)
return;
tmp_[tuplesize_] = '\0';
memcpy(mem_ + PAGESIZE*link_->pagenumber_ + k*tuplesize_, tmp_, tuplesize_);
link_->record_count_++;
//insert hashtable
char* p = new char[pa_[i].GetLength() + 1];//get the value of key
strcpy(p, ((const char*)tmp_ + pos_));
LPxkRecordItem pRI_ = new xkRecordItem;
pRI_->pageno_ = link_->pagenumber_;
pRI_->recordno_ = k;
assert(pt_->hashtable_.insert(p, pRI_) == true);
}
delete[] tmp_;
/*
int block_ = pr_->GetTuple()->GetTupleSize()*(recordcount_ - i*count_in_a_page_);
fread(mem_ + PAGESIZE * link_->pagenumber_, block_, 1, fp);
link_->record_count_ = recordcount_ - i*count_in_a_page_;
pt_->allocated_pages_++;
*/
}
}
}
fclose(fp);
pr_->SetOpened(true);//说明该关系已经打开
delete[] tablename_;
return;
}
/*
* 将该表从内存保存到外存
*/
void xkMemCoordinator::SaveTable(const size_t RID_)
{
xkRelation* pr_ = pDict_->GetRelation(RID_);
assert(pr_ != 0);
if(pr_->GetTupleCount() == 0)
return;
xkTable* pt_ = GetTable(RID_);
assert(pt_ != 0);
char* tname_ = pt_->tablename_;
char* tablename_ = new char[strlen(sysdir_) + strlen("\\") + strlen(tname_) + 1];
strcpy(tablename_, sysdir_);
strcat(tablename_, "\\");
strcat(tablename_, tname_);
FILE *fp;
fp = fopen(tablename_, "wb+");
if(fp == NULL)
{
AfxMessageBox("无法打开表文件!");
return;
}
LPxkPageItem link_ = pt_->firstpage_;
size_t tuplesize_ = pr_->GetTuple()->GetTupleSize();
while (link_)
{
//for(size_t i = 0; i < link_->record_count_; i++)
//{
// fwrite(mem_ + PAGESIZE * link_->pagenumber_ + tuplesize_ * i, tuplesize_, 1, fp);
//}
// fwrite(mem_ + PAGESIZE * link_->pagenumber_, tuplesize_*link_->record_count_, 1, fp);
int fcount_ = 0;
fcount_ = fwrite(mem_ + PAGESIZE * link_->pagenumber_, 1, tuplesize_*link_->record_count_, fp);
if(fcount_ != tuplesize_*link_->record_count_)
return;
link_ = link_->next_;
}
fclose(fp);
delete[] tablename_;
return;
}
/*
* 保存内模式中所有登记表的数据
*/
void xkMemCoordinator::SaveAll()
{
xkTable** iterator_;
for(iterator_ = tableset_.begin(); iterator_ < tableset_.end(); iterator_++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -