diff --git a/src/storage/buffer_pool_manager.cpp b/src/storage/buffer_pool_manager.cpp index 0a95e0a654b052e935fe26c22ace18e05e6546bc..e55a3ac9a143713e83c335c887d254240d0e0203 100644 --- a/src/storage/buffer_pool_manager.cpp +++ b/src/storage/buffer_pool_manager.cpp @@ -19,14 +19,15 @@ bool BufferPoolManager::find_victim_page(frame_id_t* frame_id) { // Todo: // 1 使用BufferPoolManager::free_list_判æ–ç¼“å†²æ± æ˜¯å¦å·²æ»¡éœ€è¦æ·˜æ±°é¡µé¢ // 1.1 未满获得frame - if(!free_list_.empty()){ + // 1.2 已满使用lru_replacerä¸çš„æ–¹æ³•é€‰æ‹©æ·˜æ±°é¡µé¢ + // std::scoped_lock lock{latch_}; + if (!free_list_.empty()) + { *frame_id = free_list_.front(); free_list_.pop_front(); return true; - }else{ - // 1.2 已满使用lru_replacerä¸çš„æ–¹æ³•é€‰æ‹©æ·˜æ±°é¡µé¢ - return replacer_->victim(frame_id); } + return replacer_->victim(frame_id); } /** @@ -38,17 +39,19 @@ bool BufferPoolManager::find_victim_page(frame_id_t* frame_id) { void BufferPoolManager::update_page(Page *page, PageId new_page_id, frame_id_t new_frame_id) { // Todo: // 1 如果是è„页,写回ç£ç›˜ï¼Œå¹¶ä¸”把dirty置为false - if(page->is_dirty()){ - disk_manager_->write_page(page->get_page_id().fd,page->get_page_id().page_no,page->get_data(),PAGE_SIZE); + // 2 æ›´æ–°page table + // 3 é‡ç½®pageçš„data,更新page id + if (page->is_dirty()) + { + disk_manager_->write_page(page->get_page_id().fd, page->get_page_id().page_no, page->get_data(), PAGE_SIZE); page->is_dirty_ = false; } - // 2 æ›´æ–°page table - page_table_.erase(page->id_); + page_table_.erase(page->get_page_id()); page_table_[new_page_id] = new_frame_id; - // 3 é‡ç½®pageçš„data,更新page id - page->get_page_id() = new_page_id; + page->id_ = new_page_id; page->reset_memory(); page->pin_count_ = 0; + } /** @@ -63,33 +66,31 @@ Page* BufferPoolManager::fetch_page(PageId page_id) { // 1. 从page_table_䏿œå¯»ç›®æ ‡é¡µ // 1.1 è‹¥ç›®æ ‡é¡µæœ‰è¢«page_table_记录,则将其所在frame固定(pin)ï¼Œå¹¶è¿”å›žç›®æ ‡é¡µã€‚ // 1.2 å¦åˆ™ï¼Œå°è¯•调用find_victim_page获得一个å¯ç”¨çš„frame,若失败则返回nullptr - frame_id_t frame_id; - + // 2. 若获得的å¯ç”¨frameå˜å‚¨çš„为dirty page,则须调用updata_pageå°†page写回到ç£ç›˜ + // 3. 调用disk_manager_çš„read_page读å–ç›®æ ‡é¡µåˆ°frame + // 4. å›ºå®šç›®æ ‡é¡µï¼Œæ›´æ–°pin_count_ + // 5. è¿”å›žç›®æ ‡é¡µ std::scoped_lock lock{latch_}; - if(page_table_.find(page_id) != page_table_.end()){ - frame_id = page_table_[page_id]; - Page& page_des = pages_[frame_id]; - page_des.pin_count_++; + auto it = page_table_.find(page_id); + if (it != page_table_.end()) + { + frame_id_t frame_id = it->second; + pages_[frame_id].pin_count_++; replacer_->pin(frame_id); - return &page_des; + return &pages_[frame_id]; } - frame_id = -1; - if(!find_victim_page(&frame_id)){ + frame_id_t frame_id = -1; + if (!find_victim_page(&frame_id)) + { return nullptr; } - - // 2. 若获得的å¯ç”¨frameå˜å‚¨çš„为dirty page,则须调用updata_pageå°†page写回到ç£ç›˜ - Page& page_des = pages_[frame_id]; - if(page_des.is_dirty_){ - update_page(&page_des,page_id,frame_id); - } - // 3. 调用disk_manager_çš„read_page读å–ç›®æ ‡é¡µåˆ°frame - disk_manager_->read_page(page_id.fd,page_id.page_no,page_des.data_,PAGE_SIZE); - // 4. å›ºå®šç›®æ ‡é¡µï¼Œæ›´æ–°pin_count_ - page_des.pin_count_ = 1; + Page &page = pages_[frame_id]; + update_page(&page, page_id, frame_id); + disk_manager_->read_page(page_id.fd, page_id.page_no, page.get_data(), PAGE_SIZE); + page.pin_count_ = 1; replacer_->pin(frame_id); - // 5. è¿”å›žç›®æ ‡é¡µ - return &page_des; + return &page; + } /** @@ -101,30 +102,35 @@ Page* BufferPoolManager::fetch_page(PageId page_id) { bool BufferPoolManager::unpin_page(PageId page_id, bool is_dirty) { // Todo: // 0. lock latch - std::scoped_lock lock{latch_};; - // 1. å°è¯•在page_table_䏿œå¯»page_id对应的页P - auto it = page_table_.find(page_id); + // 1. å°è¯•在page_table_䏿œå¯»page_id对应的页P // 1.1 P在页表ä¸ä¸å˜åœ¨ return false - if(it == page_table_.end()){ - return false; - } // 1.2 P在页表ä¸å˜åœ¨ï¼ŒèŽ·å–å…¶pin_count_ - frame_id_t frame_id = it -> second; // 2.1 è‹¥pin_count_å·²ç»ç‰äºŽ0,则返回false - if(pages_[frame_id].pin_count_ == 0){ - return false; - } // 2.2 è‹¥pin_count_大于0,则pin_count_自å‡ä¸€ - pages_[frame_id].pin_count_--; // 2.2.1 若自å‡åŽç‰äºŽ0,则调用replacer_çš„Unpin - if(pages_[frame_id].pin_count_ == 0){ - replacer_->unpin(frame_id); - } // 3 æ ¹æ®å‚æ•°is_dirty,更改Pçš„is_dirty_ - if(is_dirty){ - pages_[frame_id].is_dirty_ = true; + std::scoped_lock lock{latch_}; + auto it = page_table_.find(page_id); + if (it == page_table_.end()) + { + return false; + } + Page &page = pages_[it->second]; + if (page.pin_count_ == 0) + { + return false; + } + page.pin_count_--; + if (page.pin_count_ == 0) + { + replacer_->unpin(it->second); + } + if (is_dirty) + { //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!这里和å¦å§é€»è¾‘ä¸ä¸€æ ·ï¼ + page.is_dirty_ = true; } return true; + } /** @@ -135,19 +141,21 @@ bool BufferPoolManager::unpin_page(PageId page_id, bool is_dirty) { bool BufferPoolManager::flush_page(PageId page_id) { // Todo: // 0. lock latch - std::scoped_lock lock{latch_};; // 1. 查找页表,å°è¯•获å–ç›®æ ‡é¡µP - auto it = page_table_.find(page_id); // 1.1 ç›®æ ‡é¡µP没有被page_table_记录 ,返回false - if(it == page_table_.end()){ - return false; - } // 2. æ— è®ºP是å¦ä¸ºè„都将其写回ç£ç›˜ã€‚ - frame_id_t frame_id = it->second; - disk_manager_->write_page(page_id.fd,page_id.page_no,pages_[frame_id].data_,PAGE_SIZE); // 3. æ›´æ–°Pçš„is_dirty_ - pages_[frame_id].is_dirty_ = false; + std::scoped_lock lock{latch_}; + auto it = page_table_.find(page_id); + if (it == page_table_.end()) + { + return false; + } + Page &page = pages_[it->second]; + disk_manager_->write_page(page_id.fd, page_id.page_no, page.get_data(), PAGE_SIZE); + page.is_dirty_ = false; return true; + } /** @@ -157,21 +165,23 @@ bool BufferPoolManager::flush_page(PageId page_id) { */ Page* BufferPoolManager::new_page(PageId* page_id) { // 1. 获得一个å¯ç”¨çš„frameï¼Œè‹¥æ— æ³•èŽ·å¾—åˆ™è¿”å›žnullptr + // 2. 在fd对应的文件分é…一个新的page_id + // 3. å°†frame的数æ®å†™å›žç£ç›˜ + // 4. 固定frame,更新pin_count_ + // 5. 返回获得的page + std::scoped_lock lock{latch_}; frame_id_t frame_id = -1; - std::scoped_lock lock{latch_};; - if(!find_victim_page(&frame_id)){ + if (!find_victim_page(&frame_id)) + { return nullptr; } - //page_table_.erase(pages_[frame_id].id_); - // 2. 在fd对应的文件分é…一个新的page_id page_id->page_no = disk_manager_->allocate_page(page_id->fd); - // 3. å°†frame的数æ®å†™å›žç£ç›˜ - update_page(&pages_[frame_id],*page_id,frame_id); - // 4. 固定frame,更新pin_count_ - pages_[frame_id].pin_count_++; + Page &page = pages_[frame_id]; + update_page(&page, *page_id, frame_id); + page.pin_count_ = 1; replacer_->pin(frame_id); - // 5. 返回获得的page - return &pages_[frame_id]; + return &page; + } /** @@ -181,25 +191,26 @@ Page* BufferPoolManager::new_page(PageId* page_id) { */ bool BufferPoolManager::delete_page(PageId page_id) { // 1. 在page_table_䏿Ÿ¥æ‰¾ç›®æ ‡é¡µï¼Œè‹¥ä¸å˜åœ¨è¿”回true - std::scoped_lock lock{latch_};; + // 2. è‹¥ç›®æ ‡é¡µçš„pin_countä¸ä¸º0,则返回false + // 3. å°†ç›®æ ‡é¡µæ•°æ®å†™å›žç£ç›˜ï¼Œä»Žé¡µè¡¨ä¸åˆ é™¤ç›®æ ‡é¡µï¼Œé‡ç½®å…¶å…ƒæ•°æ®ï¼Œå°†å…¶åŠ å…¥free_list_,返回true + std::scoped_lock lock{latch_}; auto it = page_table_.find(page_id); - if(it == page_table_.end()){ + if (it == page_table_.end()) + { return true; } - frame_id_t frame_id = page_table_[page_id]; - // 2. è‹¥ç›®æ ‡é¡µçš„pin_countä¸ä¸º0,则返回false - if(pages_[frame_id].pin_count_ > 0){ + Page &page = pages_[it->second]; + if (page.pin_count_ != 0) + { return false; } - // 3. å°†ç›®æ ‡é¡µæ•°æ®å†™å›žç£ç›˜ï¼Œä»Žé¡µè¡¨ä¸åˆ é™¤ç›®æ ‡é¡µï¼Œé‡ç½®å…¶å…ƒæ•°æ®ï¼Œå°†å…¶åŠ å…¥free_list_,返回true - - flush_page(page_id); - page_table_.erase(page_id); - pages_[frame_id].reset_memory(); - pages_[frame_id].id_.fd = -1; - pages_[frame_id].id_.page_no = INVALID_PAGE_ID; - free_list_.push_back(frame_id); + disk_manager_->write_page(page_id.fd, page_id.page_no, page.get_data(), PAGE_SIZE); + page_table_.erase(it); + page.reset_memory(); + page.is_dirty_ = false; + free_list_.push_back(it->second); return true; + } /** @@ -207,9 +218,14 @@ bool BufferPoolManager::delete_page(PageId page_id) { * @param {int} fd æ–‡ä»¶å¥æŸ„ */ void BufferPoolManager::flush_all_pages(int fd) { - for(size_t frame_id = 0;frame_id < pool_size_;frame_id++) + std::scoped_lock lock{latch_}; + for (auto &entry : page_table_) { - if(pages_[frame_id].id_.fd == fd && pages_[frame_id].id_.page_no != INVALID_PAGE_ID) - flush_page(pages_[frame_id].id_); - } + Page &page = pages_[entry.second]; + if (page.id_.fd == fd) + { + disk_manager_->write_page(fd, page.get_page_id().page_no, page.get_data(), PAGE_SIZE); + page.is_dirty_ = false; + } + } } \ No newline at end of file