BUFFER POOL
文章目录
本文记录了 PROJECT #1 - BUFFER POOL 的实验过程
PROJECT #1 - BUFFER POOL
实现存储管理的
buffer pool
- 查看
lru_replace.h和buffer_pool_manager.h中需要实现的函数 - 查看
Page,DiskManager类的一些成员变量和函数
TASK #1 - LRU REPLACEMENT POLICY
实现页面替换的 LRU 策略,即优先替换最近最少使用的页面
思路
- 使用
std::list<frame_id_t> lru双链表的数据结构来添加可以被淘汰的页面 - 使用
std::unordered_map<frame_id_t, std::list<frame_id_t>::iterator> mp来加速frame的查找和删除 - 使用
std::mutex latch_;来支持多线程
使用 std::lock_guard<std::mutex> guard(latch_); 语句,在构造 guard 时会自动调用 latch_.lock() 加锁,并且在 guard 析构的时候自动调用 latch_.unlock() 释放锁。
Victim
- 当
Size()为 0 时返回false - 取
lru的头部元素给frame_id,删除头部元素,并且在mp中删除frame_id
Pin
- 当
frame_id在mp中时,我们需要在lru链表和mp字典中删除frame_id这个元素 - 因为
mp中已经保存了frame_id的迭代器,因此从lru中删除它的时间复杂度为 $O(1)$
Unpin
- 如果
frame_id已经在mp中了,那么直接返回 - 否则的话将
frame_id添加到lru的末尾,然后在mp中保存这个frame_id和它的迭代器(--lru.end())
TASK #2 - BUFFER POOL MANAGER
在实现
buffer_pool_manager时,应该看一下Page对象的一些成员变量;各个函数如何实现已经详细给出了。
注意
page_id表示的是磁盘上的页page_table_可以根据page_id找到对应的frame_idpages_指向了一个Page数组,我们会用frame_id来找到某一个Page对象- 在
UnpinPageImpl函数中,如果page_id不在page_table_中,我们应该返回true,而不是false;还有就是只有当is_dirty为true时,我们才设置Page的is_dirty_ - 在
DeletePageImpl(page_id_t page_id)中,除了把page_id对应的页从page_table_移除,还需要调用Pin将该页从replacer_中移除
测试
1 | make lru_replacer_test |
1 | make buffer_pool_manager_test |
代码格式验证
1 | make format |
打包
- 打包
1 | zip project1-submission.zip src/include/buffer/lru_replacer.h src/buffer/lru_replacer.cpp src/include/buffer/buffer_pool_manager.h src/buffer/buffer_pool_manager.cpp |
- 然后前往 https://www.gradescope.com 提交代码