11 #include "buffer/buffer_manager.h"
34 last_access_time = t.time * 1000 + t.millitm;
35 memset(
buffer_, 0,
sizeof(
char) * PAGESIZE);
41 inline void Page::setFileName(std::string file_name) {
45 inline std::string Page::getFileName()
const {
49 inline void Page::setBlockId(
int block_id) {
53 inline int Page::getBlockId()
const {
57 inline void Page::setPinCount(
int pin_count) {
61 inline int Page::getPinCount()
const {
65 inline void Page::setDirty(
bool dirty) {
69 inline bool Page::isDirty()
const {
73 inline void Page::setAvaliable(
bool avaliable) {
77 inline bool Page::getAvaliable()
const {
80 inline void Page::setTime(){
83 last_access_time = t.time * 1000 + t.millitm;
85 inline long long Page::getTime(){
86 return last_access_time;
88 inline char* Page::getBuffer() {
97 initialize(MAXFRAMESIZE);
101 initialize(frame_size);
109 for (
int i = 0;i < frame_size_;i++) {
110 std::string file_name;
116 void BufferManager::initialize(
int frame_size) {
117 Frames =
new Page[frame_size];
118 frame_size_ = frame_size;
119 current_position_ = 0;
131 int page_id =
getPageId(file_name , block_id);
133 page_id = getEmptyPageId();
134 loadDiskBlock(page_id , file_name , block_id);
136 Frames[page_id].setTime();
137 return Frames[page_id].getBuffer();
141 pageId_t page_id =
getPageId(file_name , block_id);
143 page_id = getEmptyPageId();
144 loadDiskBlock(page_id , file_name , block_id);
147 Frames[page_id].setTime();
148 return Frames[page_id].getBuffer();
156 Frames[page_id].setDirty(
true);
164 int pin_count = Frames[page_id].getPinCount();
165 Frames[page_id].setPinCount(pin_count + 1);
174 int pin_count = Frames[page_id].getPinCount();
178 Frames[page_id].setPinCount(pin_count - 1);
190 int BufferManager::loadDiskBlock(
int page_id ,
const std::string& file_name ,
int block_id) {
194 FILE* f = fopen(file_name.c_str() ,
"r");
197 throw DB_FILE_NOT_FOUND;
200 fseek(f , PAGESIZE * block_id , SEEK_SET);
202 char* buffer = Frames[page_id].getBuffer();
204 fread(buffer , PAGESIZE , 1 , f);
208 Frames[page_id].setFileName(file_name);
209 Frames[page_id].setBlockId(block_id);
210 Frames[page_id].setPinCount(0);
211 Frames[page_id].setDirty(
false);
212 Frames[page_id].setAvaliable(
false);
214 fname_page_map.emplace(Frames[page_id].getPageStrId(), page_id);
229 auto file_path = Frames[page_id].getFileName();
230 auto block_id = Frames[page_id].getBlockId();
232 auto iter = fname_page_map.find(Frames[page_id].getPageStrId());
233 if (iter == fname_page_map.end())
return -1;
236 FILE* f = fopen(file_path.c_str() ,
"r+");
239 throw DB_FILE_NOT_FOUND;
241 fseek(f , PAGESIZE * block_id , SEEK_SET);
243 char* buffer = Frames[page_id].getBuffer();
245 fwrite(buffer , PAGESIZE , 1 , f);
259 auto page_id_iter = fname_page_map.find(Page::generatePageStrId(file_name, block_id));
260 if (page_id_iter != fname_page_map.end())
return page_id_iter->second;
274 p =
getPage(file_name, block_num + 1);
276 }
while(p[0] !=
'\0');
284 pageId_t BufferManager::getEmptyPageId(){
285 for (
int i = 0;i < frame_size_;i++) {
287 if (Frames[i].getAvaliable())
291 for (
int i = 0;i < frame_size_;i++) {
292 if (Frames[i].getPinCount() == 0){
298 throw DB_ALL_PAGES_PINNED;
303 long long now = t.time * 1000 + t.millitm + 1;
304 for (
int i = 0; i < frame_size_; i++){
305 if(Frames[i].getPinCount() == 0 && Frames[i].getTime() < now){
306 current_position_ = i;
307 now = Frames[i].getTime();
310 if (Frames[current_position_].isDirty()) {
311 std::string file_name = Frames[current_position_].getFileName();
312 int block_id = Frames[current_position_].getBlockId();
316 fname_page_map.erase(Frames[current_position_].getPageStrId());
319 return current_position_;