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

📄 buffermanager.cpp

📁 我们自己写的miniSQL代码
💻 CPP
字号:
// BufferManager.cpp: implementation of the BufferManager class.
//
//////////////////////////////////////////////////////////////////////

#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
#include <string.h>

#include "BufferManager.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

BufferManager::BufferManager()
{

}

BufferManager::~BufferManager()
{

}

char *BufferManager::readBlock(int blockNum)
{
	if(blockTable[blockNum].inMemLocation <= IN_MEM_BLOCKS - 1)
		return buffer + blockTable[blockNum].inMemLocation * BLOCK_SIZE;

	long fileSize = getFileSize();
	long offset;

	if(fileSize == -1) 
		return NULL;

	offset = blockNum * BLOCK_SIZE;
	if( offset > fileSize)
		return NULL;

	if(offset == fileSize)
		if(_chsize(fileDesc, fileSize + BLOCK_SIZE) == -1) 
			return NULL;
	
	if(seekBlock(blockNum) == -1) 
		return NULL;

	int inMem;

	if(isQueueFull())
	{
		if((inMem = removeBlock()) == -1)
			return NULL;
	}
	else
	{
		for(inMem = 0; usedTable[inMem] >= 0; inMem++)
			;
		if(inMem >= IN_MEM_BLOCKS)
			return NULL;
	}

	if(seekBlock(blockNum) == -1)
		return NULL;

	if(_read(fileDesc, buffer + inMem * BLOCK_SIZE, BLOCK_SIZE) == -1)
		return NULL;

	if(bringBlock(blockNum, inMem) == -1)
		return NULL;

	enqueue(blockNum);

	return buffer + inMem * BLOCK_SIZE;
}

long BufferManager::getFileSize()
{
	struct _stat buf;

	if(_fstat(fileDesc, &buf) == -1) 
		return -1;

	return buf.st_size;
}

bool BufferManager::isQueueFull()
{
	return qsize >= IN_MEM_BLOCKS;
}

bool BufferManager::isQueueEmpty()
{
	return qsize == 0;
}

int BufferManager::removeBlock()
{
	int toReplace = findReplacement();
	if(toReplace == -1)
		return -1;
	BlockEntry &block = blockTable[toReplace];
	if(block.dirtyFlag)
		if(flushBlock(toReplace) == -1)
			return -1;

	int inMem = block.inMemLocation;
	block.inMemLocation = IN_MEM_BLOCKS;
	dequeue();

	return inMem;
}

int BufferManager::flushBlock(int blockNum)
{
	if(seekBlock(blockNum) == -1) 
		return -1;
	if(_write(fileDesc, buffer + blockTable[blockNum].inMemLocation * BLOCK_SIZE, BLOCK_SIZE) == -1)
		return -1;

	return 0;
}

int BufferManager::seekBlock(int blockNum)
{
	return _lseek(fileDesc, blockNum * BLOCK_SIZE, SEEK_SET);
}

int BufferManager::initialize(char *dataFile)
{
	if((fileDesc = _open(dataFile, _O_CREAT | _O_BINARY | _O_RDWR, _S_IREAD | _S_IWRITE)) == -1)
		return -1;

	buffer = new char [IN_MEM_BLOCKS * BLOCK_SIZE];
	blockTable = new BlockEntry [BLOCK_TABLE_SIZE];
	inMemQueue = new int [IN_MEM_BLOCKS];
	usedTable = new int [IN_MEM_BLOCKS];
	memset((char *)buffer, 0, IN_MEM_SIZE);
	memset(blockTable, 0, BLOCK_TABLE_SIZE * sizeof(BlockEntry));
	memset(inMemQueue, 0, sizeof(int) * IN_MEM_BLOCKS);
	memset(usedTable, -1, sizeof(int) * IN_MEM_BLOCKS);

	front = rear = qsize = 0;
	for(int i = 0; i < BLOCK_TABLE_SIZE; i++)
		blockTable[i].inMemLocation = IN_MEM_BLOCKS;

	return 0;
}

int BufferManager::bringBlock(int blockNum, int inMem)
{
	BlockEntry &block = blockTable[blockNum];
	block.dirtyFlag = 0;
	block.lockedFlag = 0;
	block.inMemLocation = inMem;
	usedTable[inMem] = blockNum;
	return 0;
}

int BufferManager::writeBlock(int blockNum)
{
	BlockEntry &block = blockTable[blockNum];
	if(block.inMemLocation >= IN_MEM_BLOCKS)
		return -1;
	block.dirtyFlag = 1;
	return 0;
}

int BufferManager::finalize()
{
	int i, j;
	for(i = 0; i < IN_MEM_BLOCKS; i++)
		if((j = usedTable[i]) >= 0)
			if(blockTable[j].dirtyFlag)
				if(flushBlock(j) == -1)
					return -1;

	delete [] buffer;
	delete [] blockTable;
	delete [] inMemQueue;
	delete [] usedTable;
	return _close(fileDesc);
}

int BufferManager::lockBlock(int blockNum)
{
	BlockEntry &block = blockTable[blockNum];
	if(block.inMemLocation >= IN_MEM_BLOCKS)
		return -1;
	block.lockedFlag = 1;
	return 0;
}

void BufferManager::enqueue(int blockNum)
{
	inMemQueue[rear] = blockNum;
	rear = (rear + 1) % IN_MEM_BLOCKS;
	qsize++;
}

void BufferManager::dequeue()
{
		front = (front + 1) % IN_MEM_BLOCKS;
		qsize--;
}

int BufferManager::findReplacement()
{
	int toReplace;

	while(!isQueueEmpty())
	{
		toReplace = inMemQueue[front];
		if(!blockTable[toReplace].lockedFlag)
			break;
		else dequeue();
	}

	if(isQueueEmpty())
	{
		qsize = IN_MEM_BLOCKS;
		return -1;
	}

	rear = front;
	qsize = IN_MEM_BLOCKS;

	return toReplace;
}

int BufferManager::unlockBlock(int blockNum)
{
	BlockEntry &block = blockTable[blockNum];
	if(block.inMemLocation >= IN_MEM_BLOCKS)
		return -1;
	block.lockedFlag = 0;
	return 0;
}

⌨️ 快捷键说明

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