📄 buffer.cpp
字号:
size_t length = strlen(this->FileName);
char fname1[256],fname2[256];
strcpy(fname1,this->FileName);
fname1[length-3]='\0';
int temp = 0,i = 1,temp2 = 0;
_M_File* tempFile = 0;
while(1)
{
temp = this->uiFileID - i;
if( temp > 0 )
{
tempFile = Buffer[temp];
if( tempFile )
{
strcpy(fname2,tempFile->FileName);
fname2[length-3]='\0';
if( !strcmp(fname1,fname2) )
break;
}
}
temp2 = this->uiFileID + i;
if( temp2 > (int)Buffer.uiFileCount && temp < 1)
{
temp = 0;
break;
}
else
{
temp = temp2;
tempFile = Buffer[temp];
if( tempFile )
{
strcpy(fname2,tempFile->FileName);
fname2[length-3]='\0';
if( !strcmp(fname1,fname2) )
break;
}
}
i++;
}
return temp;
}
//-------------------------------------------------------
// 析构,关闭文件
void _M_File::Deconstruct()
{
if(this->Ptr2File)
close(this->Ptr2File);
}
//-------------------------------------------------------
// 关闭文件,同时属于该文件的内存页改写回的写回.为保证一致性,同时关闭关联文件
void _M_File::Close()
{
Buffer.CloseTable(this->uiFileID);
}
//-------------------------------------------------------
// 根据页号取得属于该文件的内存页
_M_PageInfo* _M_File::GetPageInfo(unsigned long filepageid) const
{
return Buffer.MemPageClock->GetTargetPage(this->uiFileID,filepageid);
}
//-------------------------------------------------------
// 取得目前总的页数
unsigned long _M_File::GetPageTotal() const
{
return this->ulPageTotal;
}
//-------------------------------------------------------
// 取得文件内记录删除维护信息
_F_FileAddr _M_File::GetDelListCond() const
{
_F_FileAddr temp;
temp.ulFilePageID = 0;
temp.uiOffset = SizeOfPageHead;
return temp;
}
//-------------------------------------------------------
// 取得Catalog模块在文件中可写的第一个位置
_F_FileAddr _M_File::GetCataPoint() const
{
_F_FileAddr temp;
temp.ulFilePageID = 0;
temp.uiOffset = SizeOfPageHead + sizeof(_TB_FILECOND);
return temp;
}
//-------------------------------------------------------
// 取得Catalog模块在文件中可写的第一个位置
_F_FileAddr _M_File::GetIdxPoint() const
{
_F_FileAddr temp;
temp.ulFilePageID = 0;
temp.uiOffset = SizeOfPageHead + sizeof(_TB_FILECOND);
return temp;
}
//-------------------------------------------------------
// Buffer初始化
void _M_Buffer::Start()
{
if( FILE_PAGESIZE < 3) throw 1033; // 至少要求有 3 页,2页头信息(目录管理和索引管理各一页),另外 1 页记录存取
this->_F_First = 0;
this->_F_Last = 0;
this->_F_Current = 0;
this->uiFileCount = 0;
this->MemPageClock = new _M_Clock();
}
//-------------------------------------------------------
// Buffer结束,写回内存页,关闭文件
void _M_Buffer::End()
{
delete this->MemPageClock;
this->_F_Last = 0;
this->uiFileCount = 0;
_M_File* temp = this->_F_First;
this->_F_First = 0;
_M_File* temp2 = 0;
while(temp)
{
temp2 = temp->_F_Next;
temp->Deconstruct();
temp = temp2;
}
}
//-------------------------------------------------------
// 根据文件编号返回内存文件对象是否为新建
bool _M_Buffer::GetIsNew(unsigned int fileid) const
{
return (*this)[fileid]->IsNew;
}
//-------------------------------------------------------
// 根据文件编号设置内存文件对象是否为新建
void _M_Buffer::SetIsNew(unsigned int fileid,bool isnew)
{
(*this)[fileid]->IsNew = isnew;
}
//-------------------------------------------------------
// 根据文件编号返回内存文件对象总页数
unsigned long _M_Buffer::GetPageTotal(unsigned int fileid) const
{
return (*this)[fileid]->ulPageTotal;
}
//-------------------------------------------------------
// 根据文件编号色设置内存文件对象的总页数
void _M_Buffer::AddPageTotal(unsigned int fileid,int add)
{
(*this)[fileid]->ulPageTotal += add;
}
//-------------------------------------------------------
// 根据文件编号返回内存文件对象的文件指针
int _M_Buffer::GetPtr2File(unsigned int fileid) const
{
return (*this)[fileid]->Ptr2File;
}
//-------------------------------------------------------
// 根据文件编号返回内存文件对象
_M_File* _M_Buffer::operator [](unsigned int fileid) const
{
//Error Dispatch 0< fileid <= Buffer->uiFileCount
_M_File* temp = 0;
_M_File* temp2 = this->_F_First;
while( temp2 )
{
if( temp2->uiFileID == fileid ){
temp = temp2;
break;
}
temp2 = temp2->_F_Next;
}
return temp;
}
//-------------------------------------------------------
// 根据文件编号关闭内存文件对象
void _M_Buffer::CloseFile(unsigned int fileid)
{
this->MemPageClock->CloseFilePages(fileid);
_M_File* temp = this->_F_First;
_M_File* temp2 = 0;
while(temp->uiFileID != fileid)
{
temp2 = temp;
temp = temp->_F_Next;
}
if( temp == this->_F_First )
this->_F_First = this->_F_First->_F_Next;
else
temp2->_F_Next = temp->_F_Next;
temp->Deconstruct();
}
//-------------------------------------------------------
// 根据文件编号关闭内存文件对象及其关联内存文件对象
void _M_Buffer::CloseTable(unsigned int fileid)
{
unsigned int tempfileid = (*this)[fileid]->GetRelativeFileID();
if( tempfileid )
this->CloseFile(tempfileid);
this->CloseFile(fileid);
}
//-------------------------------------------------------
// 根据文件名称返回内存文件对象
_M_File _M_Buffer::operator [](const char* filename)
{
if( this->_F_Current && strcmp(filename,this->_F_Current->FileName)==0)
return *(this->_F_Current);
_M_File* temp = this->_F_First ;
while(temp)
{
if(strcmp(filename,temp->FileName)==0){
this->_F_Current = temp;
return *temp;
}
temp = temp->_F_Next;
}
temp = new _M_File(filename,++this->uiFileCount);
if(!this->_F_First) this->_F_First = this->_F_Last = temp;
else
{
this->_F_Last->_F_Next = temp;
this->_F_Last = temp;
}
this->_F_Current = temp;
if( temp->IsNew )
this->MemPageClock->GetTargetPage(temp->uiFileID,0);
else
temp->ulPageTotal = this->MemPageClock->GetTargetPage(temp->uiFileID,0)->GetPtr2FileCond()->ulPageTotal;
return *temp;
}
//-------------------------------------------------------
//**根据页编号和偏移量,取出当前文件该地址在内存中的地址,同时测试页偏移量是否溢出
void* _F_FileAddr::MemAddr() const
{
if( this->ulFilePageID==0 && this->uiOffset==0 )return NULL;
return (void*)((char*)Buffer._F_Current->GetPageInfo(this->ulFilePageID)->Ptr2Page->Ptr2PageBegin + this->uiOffset);
}
//-------------------------------------------------------
//**根据页编号和偏移量,取出文件该地址在内存中的地址,同时测试页偏移量是否溢出
void* _F_FileAddr::MemAddr(_M_File& target) const
{
if( this->ulFilePageID==0 && this->uiOffset==0 )return NULL;
return (void*)((char*)target.GetPageInfo(this->ulFilePageID)->Ptr2Page->Ptr2PageBegin + this->uiOffset);
}
//-------------------------------------------------------
//**根据页编号和偏移量,取出文件该地址在内存中的地址,同时测试页偏移量是否溢出
void* _F_FileAddr::MemAddr(_M_File* target) const
{
if( this->ulFilePageID==0 && this->uiOffset==0 )return NULL;
return (void*)((char*)target->GetPageInfo(this->ulFilePageID)->Ptr2Page->Ptr2PageBegin + this->uiOffset);
}
//-------------------------------------------------------
// _F_FileAddr >= 操作
bool _F_FileAddr::operator>=(_F_FileAddr& other) const
{
if( (this->ulFilePageID > other.ulFilePageID) || (this->uiOffset >= other.uiOffset && this->ulFilePageID >= other.ulFilePageID))
return 1;
return 0;
}
//-------------------------------------------------------
// _F_FileAddr > 操作
bool _F_FileAddr::operator> (_F_FileAddr& other) const
{
if( (this->ulFilePageID > other.ulFilePageID) || (this->uiOffset > other.uiOffset && this->ulFilePageID >= other.ulFilePageID))
return 1;
return 0;
}
//-------------------------------------------------------
// _F_FileAddr == 操作
bool _F_FileAddr::operator==(_F_FileAddr& other) const
{
if((this->ulFilePageID == other.ulFilePageID) && (this->uiOffset == other.uiOffset))
return 1;
return 0;
}
//-------------------------------------------------------
// _F_FileAddr != 操作
bool _F_FileAddr::operator!=(_F_FileAddr& other) const
{
if((this->ulFilePageID != other.ulFilePageID) || (this->uiOffset != other.uiOffset))
return 1;
return 0;
}
//-------------------------------------------------------
// _F_FileAddr == const int 操作
bool _F_FileAddr::operator==(const int zero) const
{
if(!zero) throw 1032; //overloading of == over const int only server ZERO
if( this->ulFilePageID || this->uiOffset )
return 0;
return 1;
}
//-------------------------------------------------------
//**在当前页中滑动offset量(可正可负)
void _F_FileAddr::ShiftOffset(int offset)
{
this->uiOffset += offset;
}
//-------------------------------------------------------
// 初始化 (0,0)
void _F_FileAddr::Initialize()
{
this->ulFilePageID = 0;
this->uiOffset = 0;
}
//-------------------------------------------------------
/*****************************************************************
** 函数名: MemWrite
** 输 入: const void*,size_t,_F_FileAddr*
** const void* --- 欲写入buffer的对象(数据)的内存地址
** size_t --- 数据总长度
** _F_FileAddr* ---文件内地址,测试判断后,若越界、跨块等情
况下,将自动修正为最终写入文件的地址
** 输 出: _F_FileAddr --- 文件内地址,为下一个文件末尾可写的地址
** 功能描述: 根据欲写入的文件地址,把其他模块内存中的数据写
入buffer中,最终自动写入文件中
** 全局变量: 无
**********************************************************/
_F_FileAddr MemWrite(const void* source,size_t length,_F_FileAddr* dest)
{
if( (int)(FILE_PAGESIZE - dest->uiOffset) - (int)length < 0) // 判断是否溢出
{
dest->ulFilePageID = Buffer._F_Current->GetPageTotal(); // 若溢出修正 dest
dest->uiOffset = SizeOfPageHead;
}
memcpy(dest->MemAddr(),source,length);
Buffer.MemPageClock->SetPageModified();
_F_FileAddr end = *dest;
end.ShiftOffset((int)length);
return end;
}
//-------------------------------------------------------
/*****************************************************************
** 函数名: MemWriteTest
** 输 入: const void*,size_t,_F_FileAddr*
** const void* --- 欲写入buffer的对象(数据)的内存地址
** size_t --- 数据总长度
** _F_FileAddr* ---文件内地址,测试判断后,若越界、跨块等情
况下,将自动修正为最终写入文件的地址
** 输 出: _F_FileAddr --- 文件内地址,为下一个文件末尾可写的地址
** 功能描述: 根据欲写入的文件地址,测试把其他模块内存中的数据写入
实际未写入。用于当整个数据对象不能跨快写的时候又不能
一次写入(如链表结构(各字段)的一条记录,在内存中不连
续)的场合。
*****************************************************************/
_F_FileAddr MemWriteTest(size_t length,_F_FileAddr* dest)
{
if((int)(FILE_PAGESIZE - dest->uiOffset) - (int)length < 0) // 判断是否溢出
{
dest->ulFilePageID = Buffer._F_Current->GetPageTotal(); // 若溢出修正 dest
dest->uiOffset = SizeOfPageHead;
}
_F_FileAddr end = *dest;
end.ShiftOffset((int)length);
return end;
}
//-------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -