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

📄 xkmemcoordinator.cpp

📁 简单数据库管理系统
💻 CPP
📖 第 1 页 / 共 2 页
字号:
 // 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 + -