Commit c4653a89 authored by 一二三四队's avatar 一二三四队
Browse files

Replace buffer_pool_manager.cpp

parent cad1abd7
No related merge requests found
Showing with 131 additions and 4 deletions
+131 -4
......@@ -20,8 +20,14 @@ bool BufferPoolManager::find_victim_page(frame_id_t* frame_id) {
// 1 使用BufferPoolManager::free_list_判断缓冲池是否已满需要淘汰页面
// 1.1 未满获得frame
// 1.2 已满使用lru_replacer中的方法选择淘汰页面
if (!free_list_.empty()) {
*frame_id = free_list_.front();
free_list_.pop_front();
return true;
}
return false;
return replacer_->victim(frame_id);
//return false;
}
/**
......@@ -35,6 +41,15 @@ void BufferPoolManager::update_page(Page *page, PageId new_page_id, frame_id_t n
// 1 如果是脏页,写回磁盘,并且把dirty置为false
// 2 更新page table
// 3 重置page的data,更新page id
if (page->IsDirty()) {
disk_manager_->WritePage(page->GetPageId(), page->GetData());
page->SetDirty(false);
}
page_table_.erase(page->GetPageId());
page_table_.insert({new_page_id, new_frame_id});
page->ResetMemory();
page->SetPageId(new_page_id);
}
......@@ -54,7 +69,35 @@ Page* BufferPoolManager::fetch_page(PageId page_id) {
// 3. 调用disk_manager_的read_page读取目标页到frame
// 4. 固定目标页,更新pin_count_
// 5. 返回目标页
return nullptr;
std::unique_lock<std::mutex> latch(latch_);
auto iter = page_table_.find(page_id);
if (iter != page_table_.end()) {
frame_id_t frame_id = iter->second;
Page* page = &pages_[frame_id];
page->pin_count_++;
return page;
}
frame_id_t frame_id;
if (!find_victim_page(&frame_id)) {
return nullptr; // 无可用的帧页
}
Page* page = &pages_[frame_id];
if (page->IsDirty()) {
disk_manager_->WritePage(page->GetPageId(), page->GetData());
page->SetDirty(false);
}
disk_manager_->ReadPage(page_id, page->GetData());
page_table_.erase(page->GetPageId());
page_table_.insert({page_id, frame_id});
page->SetPageId(page_id);
page->pin_count_ = 1;
return page;
//return nullptr;
}
/**
......@@ -73,6 +116,27 @@ bool BufferPoolManager::unpin_page(PageId page_id, bool is_dirty) {
// 2.2 若pin_count_大于0,则pin_count_自减一
// 2.2.1 若自减后等于0,则调用replacer_的Unpin
// 3 根据参数is_dirty,更改P的is_dirty_
std::scoped_lock latch(latch_);
auto iter = page_table_.find(page_id);
if (iter == page_table_.end()) {
return false; // 目标页不存在于页表中
}
Page* page = &pages_[iter->second];
int pin_count = page->pin_count_;
if (pin_count <= 0) {
return false; // 目标页的pin_count已经为0
}
page->pin_count_--;
if (page->pin_count_ == 0) {
replacer_->Unpin(iter->second);
}
page->SetDirty(is_dirty);
return true;
}
......@@ -89,6 +153,17 @@ bool BufferPoolManager::flush_page(PageId page_id) {
// 2. 无论P是否为脏都将其写回磁盘。
// 3. 更新P的is_dirty_
std::scoped_lock latch(latch_);
auto iter = page_table_.find(page_id);
if (iter == page_table_.end()) {
return false; // 目标页不存在于页表中
}
Page* page = &pages_[iter->second];
disk_manager_->WritePage(page->GetPageId(), page->GetData());
page->SetDirty(false);
return true;
}
......@@ -103,7 +178,27 @@ Page* BufferPoolManager::new_page(PageId* page_id) {
// 3. 将frame的数据写回磁盘
// 4. 固定frame,更新pin_count_
// 5. 返回获得的page
return nullptr;
std::unique_lock<std::mutex> latch(latch_);
frame_id_t frame_id;
if (!find_victim_page(&frame_id)) {
return nullptr; // 无可用的帧页
}
Page* page = &pages_[frame_id];
if (page->IsDirty()) {
disk_manager_->WritePage(page->GetPageId(), page->GetData());
page->SetDirty(false);
}
*page_id = disk_manager_->AllocatePage();
page->SetPageId(*page_id);
page_table_.insert({*page_id, frame_id});
page->ResetMemory();
page->pin_count_ = 1;
return page;
//return nullptr;
}
/**
......@@ -116,6 +211,28 @@ bool BufferPoolManager::delete_page(PageId page_id) {
// 2. 若目标页的pin_count不为0,则返回false
// 3. 将目标页数据写回磁盘,从页表中删除目标页,重置其元数据,将其加入free_list_,返回true
std::scoped_lock latch(latch_);
auto iter = page_table_.find(page_id);
if (iter == page_table_.end()) {
return true; // 目标页不存在于页表中,可认为已经删除成功
}
Page* page = &pages_[iter->second];
int pin_count = page->pin_count_;
if (pin_count != 0) {
return false; // 目标页的pin_count不为0,无法删除
}
if (page->IsDirty()) {
disk_manager_->WritePage(page->GetPageId(), page->GetData());
page->SetDirty(false);
}
page_table_.erase(page->GetPageId());
page->ResetMemory();
free_list_.push_back(iter->second);
return true;
}
......@@ -124,5 +241,15 @@ bool BufferPoolManager::delete_page(PageId page_id) {
* @param {int} fd 文件句柄
*/
void BufferPoolManager::flush_all_pages(int fd) {
std::scoped_lock latch(latch_);
for (auto& pair : page_table_) {
PageId page_id = pair.first;
Page* page = &pages_[pair.second];
if (page->IsDirty()) {
disk_manager_->WritePage(page_id, page->GetData());
page->SetDirty(false);
}
}
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment