-
Notifications
You must be signed in to change notification settings - Fork 1
/
buffer_manager.cpp
150 lines (131 loc) · 4.5 KB
/
buffer_manager.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include "buffer_manager.h"
using namespace std;
//CBufferManager m_ptheblocks[MAX_BLOCKS];
CBufferManager* CBufferManager::m_ptheblocks = NULL;
/*初始化buffer区,但不分配内存*/
void CBufferManager::initiate_blocks()
{
m_ptheblocks = new CBufferManager [MAX_BLOCKS];
for(int 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()
{
fstream DBfile;
const char* file_name = m_name.c_str();
DBfile.open(file_name,ios::binary|ios::out|ios::in|ios::ate);
if(m_is_written && m_index_table) {
DBfile.seekp(BLOCK_SIZE*m_offset_number,ios::beg);
DBfile.write(m_address,BLOCK_SIZE);
DBfile.close();
}
}
/*为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();
for(p=m_ptheblocks[number].m_address;p<m_ptheblocks[number].m_address+BLOCK_SIZE;p++)
*p='$';
}
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, string filename, unsigned int offset_number)
{
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);
const char*file_name = filename.c_str();
fstream DBfile(file_name,ios::binary|ios::in);
DBfile.seekg(BLOCK_SIZE*offset_number, ios::beg);
DBfile.read(m_ptheblocks[mark].m_address,BLOCK_SIZE);
DBfile.close();
using_block(mark);
return mark;
}
void CBufferManager::buffer_clear(string filename,short int index_table){
int i;
for(i=0;i<MAX_BLOCKS;i++) {
if(m_ptheblocks[i].m_index_table==index_table && m_ptheblocks[i].m_name == filename ) { //表示在buffer中找到了该块
m_ptheblocks[i].m_index_table=0;
m_ptheblocks[i].m_name = "";
m_ptheblocks[i].m_address = NULL;
}
}
}
/*
int main(){
CBufferManager buffer;
buffer.initiate_blocks();
string filename = "buffer_test.txt";
int block_num = buffer.get_block(TABLE, filename,0);
for(char* text = buffer.m_ptheblocks[block_num].m_address; text <buffer.m_ptheblocks[block_num].m_address+BLOCK_SIZE;text++){
cout<< *text;
}
return 0;
}
*/