CMU 15-445 (2024 fall) Project #1 - Buffer Pool Manager
封面来源:@psychoron
Project #1 - Buffer Pool Manager | CMU 15-445/645 :: Intro to Database Systems (Fall 2024)
实现的 BusTub 是面向磁盘的 DBMS,数据存储在 non-volatile disk 中。
BusTub 的 page 是固定大小 4 KB,
缓存池管理器 Buffer Pool Manager 存储 store 页到固定大小的 buffer 中,称为 frame。
把逻辑页 logical page 存储到物理固定帧 physical fixed frame 中。
作为 cache 也作为提供 DBMS 支持大于内存大小的数据库的管理。
实现需要是线程安全的,使用 latches 来保证。
和 OS 的 lock 的区别大概是保护内部数据的关键部分,且不需要支持回滚 rollback change。
Task #1 - LRU-K Replacement Policy
size_t 是 unsigned 默认值不要赋 -1。
别的就正常实现,线程安全,先都加大锁,后面再考虑优化。
Task #2 - Disk Scheduler
了解 std::promise 和 std::future,简单理解是线程之间更加方便传递数据的方式。
关于 std::promise 和 std::future 的使用方式:
线程一,创建 promise 和 future,把 promise 传递给线程二(ref / move);
线程一,获取值(等待,堵塞);线程二,future 返回值,线程一继续。
另一个相关的是 std::async,对 std::future 和 std::thread (和 std::packaged_task)的封装。
std::packaged_task 也是类似。
值得注意的是,std::future.get() 的时候,会自动调用 wait,且只能调用一次 get()。
std::async 有不同的启动模式
std::launch::async异步std::launch::deferred在get(),wait()的再去延迟执行std::launch::async | std::launch::deferred默认,都可以,取决于编译器 / 操作系统(?)
如果 std::future 关联的 std::promise 在未被使用的时候,被释放了,会报错。
多个线程等待同一个执行结果时,可以使用 std::shared_future。
| |
C++之future和promise - PKICA - 博客园
C++ 并发三剑客future, promise和async | 恋恋风辰的个人博客
虽然讲了很多,不过只要用一点点就行了。
Task #3 - Buffer Pool Manager
主要调试的点:
(其实跟着 test case 就能出来)
Frame和Page的数据同步问题- 同一个
Frame,读写的同步问题 - 逐出状态是跟着
frame_id走的,构建时需要重置下 - 在
frame的访问次数小于k时的比较方式和网页描述疑似不一致,是按照 FIFO 的方式? - 就算是
assert有使用到需要用锁的参数,也需要包含在锁的范围内,如LRUKReplacer::SetEvictable。或者只在必要时才调用来缓解(不过应该不算彻底解决,但同时加上也是更合理的写法)。具体也不算搞清楚原因,just work… - 试着让
bpm和page_guard的职责分开。 frame的rw_latch需不需要锁。
| |
感觉是错哪改哪,后续还应该再去整理一遍的样子。
提交结果

Leaderboard 顺带贴一下吧,还没有做额外修改,也还没做 bonus 部分。

