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

📄 buffer.cpp

📁 实现一个精简型单用户SQL引擎(DBMS)MiniSQL
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    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 + -