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

📄 xkmemcoordinator.cpp

📁 简单数据库管理系统
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	{
		SaveTable((*iterator_)->RID_);
	}
}
/*
 *	加载内模式中所有登记表的数据
 */
void xkMemCoordinator::LoadAll()
{
	xkTable** iterator_;
	for(iterator_ = tableset_.begin(); iterator_ < tableset_.end(); iterator_++)
	{
		LoadTable((*iterator_)->RID_);
	}
}
/*
 *	通过关键字查找所需记录
	attr_  为关键字的属性
	value_ 为关键字的值
	desired_ 存放选中记录的内容
 */
bool xkTable::GetSelectedRecord(const xkAttribute & attr_, const void* value_, void* desired_, char* mem_)
{
	if(!attr_.IsKey())
		return false;
	xkRelation* pr_ = pDict_->GetRelation(RID_);
	size_t tuplesize_ = pr_->GetTuple()->GetTupleSize();
	LPxkRecordItem pRI_ = 0;
	pRI_ = hashtable_.lookup((char*const)value_);//为什么要变为常量指针???
	//assert(pRI_ != 0);
	if(pRI_ == 0)
		return false;// not found
	memcpy(desired_, mem_ + pRI_->pageno_*PAGESIZE + tuplesize_*pRI_->recordno_, tuplesize_);
	return true;
	/*
	xkRelation* pr_ = pDict_->GetRelation(RID_);
	size_t tuplesize_ = pr_->GetTuple()->GetTupleSize();
	xkAttribute *pa_ = pr_->GetTuple()->GetAttributes();
	size_t ac_ = pr_->GetTuple()->GetAttrCount();
	size_t pos_ = 0;
	for(size_t i = 0; i < ac_; i++)
	{
		if(strcmp(attr_.GetName(), pa_[i].GetName()) == 0)
			break;
		pos_ += pa_[i].GetSize();
	}
	assert(pos_ < tuplesize_);
	if(curpage_ == 0)
		curpage_ = firstpage_;//若查找结束,则重新查找
	while(curpage_)
	{
		while(cursor_ < curpage_->record_count_)
		{
			char* p = mem_ + PAGESIZE*curpage_->pagenumber_ + cursor_*tuplesize_;
			char* attrpos_;
			memcpy(attrpos_, p + pos_, attr_.GetSize());
			if(strcmp(attrpos_, (const char*)value_) == 0)//bingo
			{
				memcpy(desired_, p, tuplesize_);
				cursor_++;
				return true;
			}
			cursor_++;
		}
		cursor_ = 0;
		curpage_ = curpage_->next_;// search the next page
	}
	*/
}
/*
 *	attr_为关键字的属性
	originalval_为关键字的原始值
	value_为记录的更新值
 */
bool xkTable::UpdateRecord(const xkAttribute & attr_, const char* originalval_, const void* value_, char* mem_)
{
	if(!attr_.IsKey())
		return false;
	xkRelation* pr_ = pDict_->GetRelation(RID_);
	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_);
	char* p = new char[pa_[i].GetSize() + 1];//get the value of key
	strcpy(p, ((const char*)value_ + pos_));

	LPxkRecordItem pRI_ = 0;
	pRI_ = hashtable_.lookup((char*const)originalval_);//为什么要变为常量指针???
	//assert(pRI_ != 0);
	if(pRI_ == 0)
		return false;// not found
	memcpy(mem_ + pRI_->pageno_*PAGESIZE + tuplesize_*pRI_->recordno_, value_, tuplesize_);
	//modify hashtable
	LPxkRecordItem pri1_ = new xkRecordItem;
	pri1_->pageno_ = pRI_->pageno_;
	pri1_->recordno_ = pRI_->recordno_;
	hashtable_.erase((char*const)originalval_);
	//delete pRI_;
	//delete[] originalval_;将导致内存泄漏
	hashtable_.insert(p, pri1_);
	return true;
}
/*
 *	attr_为关键字的属性
	originalval_为关键字的原始值
 */
bool xkTable::DeleteRecord(const xkAttribute & attr_, const char* originalval_, char* mem_)
{
	if(!attr_.IsKey())
		return false;
	xkRelation* pr_ = pDict_->GetRelation(RID_);
	size_t tuplesize_ = pr_->GetTuple()->GetTupleSize();
	LPxkRecordItem pRI_ = 0;
	pRI_ = hashtable_.lookup((char*const)originalval_);
	if(pRI_ == 0)
		return false;// not found
	//delete the record
	char* p = mem_ + pRI_->pageno_*PAGESIZE + tuplesize_*pRI_->recordno_;
//	memset(mem_ + pRI_->pageno_*PAGESIZE + tuplesize_*pRI_->recordno_, '#', tuplesize_);
	memmove(p, p + tuplesize_, PAGESIZE - tuplesize_ * (pRI_->recordno_ + 1));
	pr_->SetTupleCount(pr_->GetTupleCount() - 1);// update data dictionary information
	pr_->SetRelationSize(pr_->GetRelationSize() - tuplesize_);

	LPxkPageItem prev_ = 0,link_ = firstpage_;
	while (link_)
	{
		if(link_->pagenumber_ == pRI_->pageno_)
			break;
		prev_ = link_;
		link_ = link_->next_;
	}
	assert(link_ != 0);
	
	//修改删除记录后面的记录的hashtable数据
	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_);
	char* key_ = new char[pa_[i].GetLength() + 1];//get the value of key
//	strcpy(p, ((const char*)source_ + pos_));
	size_t rpos_ = pRI_->recordno_;
	while(rpos_ < link_->record_count_ - 1)
	{
		strcpy(key_, mem_ + pRI_->pageno_*PAGESIZE + rpos_*tuplesize_ + pos_);
		LPxkRecordItem pri1_ = 0;
		pri1_ = hashtable_.lookup(key_);
		if(pri1_ != 0)
			pri1_->recordno_--;	
		rpos_++;
	}
	delete[] key_;
	///////////////////

	if(link_->record_count_ == 1)//only one record in this page,so reallocate this page
	{
		pMem_->SetFreePage(link_->pagenumber_);
		if(prev_)
		{
			prev_->next_ = link_->next_;
			delete link_;
		}
		else
		{
			firstpage_ = link_->next_;
			delete link_;
		}
		this->allocated_pages_--;
	}
	else
	{
		link_->record_count_--;
	}
	if(firstpage_ == 0)//如果文件删空
	{
		firstpage_ = new xkPageItem;
		firstpage_->pagenumber_ = pMem_->GetPage();
		firstpage_->record_count_ = 0;
		cursor_ = 0;
		curpage_ = firstpage_;
		allocated_pages_ = 1;
	}
	hashtable_.erase((char*const)originalval_);
//	delete pRI_;
	//delete[] originalval_;将导致内存泄漏
	pMem_->SaveTable(RID_);//将修改的内容存入外存
	return true;
}
/*
 *	source_为新纪录的值
	size_为新记录的大小
 */
bool xkTable::InsertRecord(const void* source_, const size_t size_, char* mem_)
{
	xkRelation* pr_ = pDict_->GetRelation(RID_);
	size_t tuplesize_ = pr_->GetTuple()->GetTupleSize();
	assert(size_ == tuplesize_);
	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_);
	char* p = new char[pa_[i].GetLength() + 1];//get the value of key
	strcpy(p, ((const char*)source_ + pos_));

	if(hashtable_.isExist(p))
	{
		AfxMessageBox("此关键字已经存在!");
		return false;
	}

	LPxkPageItem prev_ = 0, link_ = firstpage_;
	size_t count_in_a_page_ = PAGESIZE/(pr_->GetTuple()->GetTupleSize());
	while(link_)
	{
		if(link_->record_count_ < count_in_a_page_)//insert here
		{		
			memcpy(mem_ + PAGESIZE*link_->pagenumber_ + tuplesize_*link_->record_count_, source_, tuplesize_);
			LPxkRecordItem pRI_ = new xkRecordItem;
			pRI_->pageno_ = link_->pagenumber_;
			pRI_->recordno_ = link_->record_count_;
			link_->record_count_++;
			assert(hashtable_.insert(p, pRI_) == true);		
			pr_->SetRelationSize(pr_->GetRelationSize() + tuplesize_);
			pr_->SetTupleCount(pr_->GetTupleCount() + 1);
			return true;
		}
		prev_ = link_;
		link_ = link_->next_;
	}// allocate a new page to insert the record
	assert(prev_ != 0);
	prev_->next_ = new xkPageItem;
	link_ = prev_->next_;
	link_->pagenumber_ = (size_t)pMem_->GetPage();
	assert(link_->pagenumber_ != -1);
	allocated_pages_++;
	memcpy(mem_ + PAGESIZE*link_->pagenumber_, source_, tuplesize_);//insert here
	LPxkRecordItem pRI_ = new xkRecordItem;
	pRI_->pageno_ = link_->pagenumber_;
	pRI_->recordno_ = link_->record_count_;
	link_->record_count_++;
	assert(hashtable_.insert(p, pRI_) == true);
	pr_->SetRelationSize(pr_->GetRelationSize() + tuplesize_);
	pr_->SetTupleCount(pr_->GetTupleCount() + 1);
//	pMem_->SaveTable(RID_);//保存数据到外存
	return true;
	//delete[] p; 将导致内存泄漏
}
/*
 *	每调用一次就 返回一个记录,返回值为非零
	结束返回值为零
 */
char* xkTable::GetTableAllRecords(char* mem_)
{
	xkRelation* pr_ = pDict_->GetRelation(RID_);
	size_t tuplesize_ = pr_->GetTuple()->GetTupleSize();
	if(pr_->GetTupleCount() == 0)
		return false;
	while(curpage_ && rcount_ < pr_->GetTupleCount())
	{
		char* tmp_ = new char[tuplesize_ + 1]; 
		memcpy(tmp_, mem_ + curpage_->pagenumber_*PAGESIZE + cursor_*tuplesize_, tuplesize_);
		tmp_[tuplesize_] = '\0';
		cursor_++;
		rcount_++;
		if(cursor_ == curpage_->record_count_)
		{
			curpage_ = curpage_->next_;
			cursor_ = 0;
		}
		return tmp_;
	}
	curpage_ = firstpage_;
	cursor_ = 0;
	rcount_ = 0;
	return 0;
}

char* xkMemCoordinator::GetTableAllRecords(const size_t rid_)
{
	xkTable* pt_ = GetTable(rid_);
	return	pt_->GetTableAllRecords(GetMem());
}

void xkTable::DeleteAllRecords()
{
	//update dict information
	xkRelation* pr_ = pDict_->GetRelation(RID_);
	pr_->SetRelationSize(0);
	pr_->SetTupleCount(0);
	//destroy all records in memory	
	LPxkPageItem prev_ = 0, link_ = firstpage_;
	while(link_)
	{
		pMem_->SetFreePage(link_->pagenumber_);
		link_->record_count_ = 0;
		prev_ = link_;
		link_ = link_->next_;
		delete prev_;
	}
	//delete all information in hashtable
	hashtable_.clear();
	//update information of object
	firstpage_ = new xkPageItem;
	firstpage_->pagenumber_ = pMem_->GetPage();
	firstpage_->record_count_ = 0;
	cursor_ = 0;
	curpage_ = firstpage_;
	allocated_pages_ = 1;
	//destroy all records in disk
	char* tname_ = new char[strlen(sysdir_) + strlen("\\") + strlen(tablename_) + 1];
	strcpy(tname_, sysdir_);
	strcat(tname_, "\\");
	strcat(tname_, tablename_);
	FILE *fp;
	fp = fopen(tname_, "wb+");
	if(fp == NULL)
	{
		AfxMessageBox("无法删除表记录!");
		return;
	}
	delete[] tname_;
	fclose(fp);
}

void xkMemCoordinator::DeleteAllRecords(const size_t rid_)
{
	xkTable* pt_ = GetTable(rid_);
	pt_->DeleteAllRecords();
}

⌨️ 快捷键说明

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