📄 xkmemcoordinator.cpp
字号:
{
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 + -