📄 buffermanager.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 + -