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

📄 buffer_manager.cpp

📁 设计并实现一个精简型单用户SQL引擎(DBMS)MiniSQL
💻 CPP
字号:

#include "stdafx.h"
#include "buffer_manager.h"

using namespace std;

//CBufferManager m_ptheblocks[MAX_BLOCKS];
CBufferManager* CBufferManager::m_ptheblocks = NULL;


/*初始化buffer区,但不分配内存*/
void CBufferManager::initiate_blocks()
{
	unsigned int i;
	m_ptheblocks = new CBufferManager [MAX_BLOCKS];
	for(i=0;i<MAX_BLOCKS;i++){//对每一块的参数初始化
		m_ptheblocks[i].m_address = NULL;
		m_ptheblocks[i].m_index_table=0;
		m_ptheblocks[i].m_is_written=0;
		m_ptheblocks[i].m_being_used=0;
		m_ptheblocks[i].m_count=0;
	}
}

/*退出时调用,将所有需要写回的块数据写回相应文件,并释放buffer区*/
void CBufferManager::flush_all_blocks(){   
	for(int i=0;i<MAX_BLOCKS;i++){
		m_ptheblocks[i].flush_block();
		if(m_ptheblocks[i].m_address != NULL)
			delete [] m_ptheblocks[i].m_address;
	}
}

/*使用块函数,buffer内部函数*/
void CBufferManager::using_block(unsigned int number)
{
	unsigned int i;
	m_ptheblocks[number].m_being_used=1;
	for(i=0;i<MAX_BLOCKS;i++){
		if(i!=number && !m_ptheblocks[number].m_being_used)
			m_ptheblocks[i].m_count++;  //所有没正在使用的块count加1
		else if(i==number)
			m_ptheblocks[i].m_count=0;  //正在使用的块count置0,使正在被使用的块不被换出
	}
}

/*找到count值最大的块号(即近似LRU算法中要求替换出的块),buffer内部函数*/	
unsigned int CBufferManager::max_count_number()
{
	unsigned int i;
	unsigned int max_count=m_ptheblocks[0].m_count;
	unsigned int block_number=0;
	for(i=0;i<MAX_BLOCKS;i++)
		if(m_ptheblocks[i].m_count>max_count){
			max_count=m_ptheblocks[i].m_count;
			block_number=i;
		}
	return block_number;
}

/*若该块需要写回,将该块的数据写回相应文件,换出时和退出时调用,buffer内部函数*/
void CBufferManager::flush_block()
{
	FILE *fp;
	if(m_is_written && m_index_table) {
		if(fp=fopen((LPCTSTR)m_name,"rb+")){  
			fseek(fp,BLOCK_SIZE*m_offset_number,0);
			fwrite(m_address,BLOCK_SIZE,1,fp);
			fclose(fp);
		}
	}
}

/*为record manager和index manager提供块(写),在其初始建立时调用*/
unsigned int CBufferManager::get_blank_block(short int index_table)
{
	unsigned int number;
	unsigned int i;
	char *p;
	for(i=0;i<MAX_BLOCKS;i++)
		if(!m_ptheblocks[i].m_index_table && !m_ptheblocks[i].m_being_used)
			break;
	if(i<MAX_BLOCKS) { //表示有空块
		number=i;
		m_ptheblocks[number].m_address = new char [BLOCK_SIZE];	

        for(p=m_ptheblocks[number].m_address;p<m_ptheblocks[number].m_address+BLOCK_SIZE;p++)
		   *p='$';
	}
	else{ //表示无空块,须判断换出哪个块和是否有必要写回文件
		number=max_count_number();
		m_ptheblocks[number].flush_block();
	}
	using_block(number);
	m_ptheblocks[number].m_index_table=index_table;
	return number;
}

/*为record manager和index manager提供块(读或改),若在buffer中找不到则调用get_blank_block为其分配空间并做标记*/
unsigned int CBufferManager::get_block(short int index_table, CString filename, unsigned int offset_number)
{
	FILE *fp;
	unsigned int number;
	unsigned int i,mark;
	
	for(i=0;i<MAX_BLOCKS;i++) {
		if(m_ptheblocks[i].m_index_table==index_table && m_ptheblocks[i].m_name == filename && 
			m_ptheblocks[i].m_offset_number==offset_number) { //表示在buffer中找到了该块
			number=i;
			using_block(number);
			return number;
		}
	}

	mark=get_blank_block(index_table);//未找到该块则调用get_blank_block为其分配空间并做标记
	m_ptheblocks[mark].mark_block(filename,offset_number);
	
	fp = fopen((LPCTSTR)filename, "rb");
	fseek(fp,BLOCK_SIZE*offset_number, 0);
	fread(m_ptheblocks[mark].m_address,BLOCK_SIZE,1,fp);
	fclose(fp);

	using_block(mark);
	return mark;
}

⌨️ 快捷键说明

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