CMU-15-445 Lab1记录
LRU REPLACEMENT POLICY
这个task是做lru替换类,负责跟踪buffer pool中的page
思路
- LRU的思可以参考leetcode中的lru的实现,双向链表+map,实现增删改查都是O(1)的操作
- 其他的跟着TASK1中的描述就可以了
Task 2 BUFFER POOL MANAGER INSTANCE
这个task 需要是实现一个buffer pool manager(BufferPoolManagerInstance
),BufferPoolManagerInstance
是负责将database page从DiskManager
取出来并将它们放到内存中的一个类。BufferPoolManagerInstance
也可以将脏页写回到磁盘以此来给page腾出地方。
在内存中的pges都是由Page
类来管理的,每个Page
都包含DiskManager
从物理磁盘中读取出来的一块大小的数据。BufferPoolManagerInstance
会重复使用Page
对象,所以同一个Page
可能会包含不同的内容。Page由page_id来表明包含的物理页是哪个。如果Page
对象没有包含一个物理页,就将其page_id
设置为IINVALID_PAGE_ID
每一个Page
对象都包含一个计数器,表明有多少个线程Pinned了这个page。所以BufferPoolManagerInstance
是不允许free一个被Pinned的Page
。每个Page
还表明当前的页是否是Dirty的。BufferPoolManagerInstance
当要重用包含脏页的Page
的时候,必须先写回。BufferPoolManagerInstance
需要使用刚才实现的LRUReplacer
。
思路
FechPgImg(page_id)
- 这个函数基本跟着cpp文件中的提示来就行,如果在replacer获取到的page是脏页,需要flush一下,并且记得更新page的page_id,pin_count等参数
UnpinPgImg(page_id, is_dirty)
- 先执行pin_count–的操作,还要更新is_dirty_,最后如果pin_count为0的话,调用
replacer->Unpin(frame_id)
,将page调回replacer中
- 先执行pin_count–的操作,还要更新is_dirty_,最后如果pin_count为0的话,调用
FlushPgImg(page_id)
- 调用disk_manager->WritePage即可
FlushAllPagesImpl()
- 同上
NewPgImp(page_id)
- 跟着提示来,如果获取的页是dirty的,就flush
DeletePgImg(page_id)
- 跟着提示来,如果脏页就刷新,如果确定要删除这个页,需要调用replacer->Pin(frame_id),将这个page对应的frame删除,再放入free_list中,否则会造成replacer和free_list中同时存在的情况
Task 3 PARALLEL BUFFER POOL MANAGER
这个task需要将buffer pool实现为线程安全。ParallelBufferPoolManager
是一个有多个BufferPoolManagerInstance
的类,每个操作都会让ParallelBufferPoolManager
选择一个BufferPoolManagerInstance
进行操作。
当给出page id的时候,需要通过取模的方式选择一个BufferPoolManagerInstance
,方法是page_id mod num_instances
。
思路
首先个刚才实现的BUFFER POOL MANAGER INSTANCE加锁,可以直接使用它自身带的latch_,加锁方式可以使用c++17中的scoped_lock
。
剩下的就没啥可注意的了
CMU-15-445 Lab1记录