CMU15445 踩坑指南-PROJECT #1- BUFFER POOL
PROJECT #1 - BUFFER POOL
TASK 1 LRU REPLACER
这里需要完成src/include/buffer/lru_replacer.h
和src/buffer/lru_replacer.cpp
LRU(Least Recently Used)算法可以使用一个双向链表和一个unordered_map
实现,双向链表用于快速将最近使用的页移动至表头,map可以根据page_id
找到链表节点(节点存储的frame_id
).具体可以参考LRU算法
注意!!! 双向链表删除节点时一定要记得回收内存,project1的内存检查不是很严格,可能查不出来,但后面的project要求会更高!
实现以下函数
Victim(frame_id_t*)
: 找到最久没使用的一页,记录在传递的参数中,即frame_id
,返回true
,如果lru_replacer
为空,返回false
.Pin(frame_id_t)
: 标记一个页,使它不会被删除,也就是把这页从lru_replacer
中删除.Unpin(frame_id_t)
: 解除某页的标记,即把这一页插入lru_replacer
中.Size()
: 返回可用的frame数.
注意细节和内存回收,这个task很简单.
TASK 2 BUFFER POOL MANAGER INSTANCE
bpm里存了一个数组pages_
,通过数组的索引(frame_id
)来获取page
,page_table
记录了page_id
与其所在位置(frame_id
)的映射关系,free_list
记录哪些位置为空,这个实验给了非常详细的注释,按照注释的步骤就可以完成了.
实现以下函数
-
FetchPgImp(page_id)
:- 从先从内存里找(也就是page_table_里);
- 找到后pin_count_自增,从lru_replace里删掉这个frame_id_;
- 如果内存里没有,就去磁盘找,然后在内存里腾一个空位;
- 腾空位的逻辑是先找从free_list_找,找不到就用lru_replacer_淘汰一个;
- 使用lru淘汰page时要检查这个page是不是被修改过,修改过的需要先写回磁盘._
-
UnpinPgImp(page_id, is_dirty)
:解除标记,也就告诉bpm这个page已经用完了;- 根据page_id找到这个page;
- pin_count自减;
- 如果pin_count_为0,将这个frame加入lru_replacer;
- 更新is_dirty_标记.
这里有个小坑,不能简单的
p->is_dirty_ = is_dirty;
,这样可能会出现前一个释放的事务将is_dirty_改为true,但是这次释放的线程又将is_dirty_改为了false,这样是不正确的. -
FlushPgImp(page_id)
:把对应的page写回磁盘; -
NewPgImp(page_id)
:创建一个新page,并写回磁盘里;- 类似
FetchPgImp()
的步骤,先在内存里找个空frame; - 创建新page,代码类似这样:
*page_id = AllocatePage(); pages_[f_id].ResetMemory(); pages_[f_id].page_id_ = *page_id; pages_[f_id].pin_count_ = 1; pages_[f_id].is_dirty_ = false;
- 写回内存(is_dirty_设false应该就可以了,可以不写回磁盘,我没有试过,但是逻辑应该没问题)
- 类似
-
DeletePgImp(page_id)
:这里的删除是把page从内存里回收,不是真删了这个page,还是之前的方法,检查is_dirty_,该写回的写回,内存清掉,replacer里面删掉这个frame,并加入free_list_; -
FlushAllPagesImpl()
:把page_table_里的所有page都写回磁盘里.
TASK 3 PARALLEL BUFFER POOL MANAGER
现在还需要考虑到并发,所以给task2写的那些函数加上锁,建议使用std::lock_guard<std::mutex>
,可以自动释放.
使用轮询调度(RoundRobin)来调用实例,功能直接调用之前写好的函数就可以了.
提交
交这些文件,检查代码格式.
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