extendible-hash-index
For 15445 Project 2.
BUG:
- 由于已经实现了 BufferPoolManager,所以在实现 ExtendibleHash 的时候,Fetch 而来的页在不需要的时候尽快释放(Drop),以免过度占用内存。
- 调用 Hash() 接口,而不是直接 hash_fn.GetHash(),要符合接口的规范,否则在某个测试中期望得到 uint32_t 类型的 hash 值,而实际得到的是 uint64_t 类型的 hash 值,导致测试失败(实际是 Hash 函数使用错误)。
- 通过 FetchPage() 获取的页,需要立刻检查其 id 是否为 INVALID_PAGE_ID,如果是,则说明分配失败。
- 注意 Page 中的 WLatch() 以及 WUnlatch() 的使用,其保护的并不是 Page 的元数据(MetaData),而是 Page "这一页"实际存储的数据 (data[PAGE_SIZE])。MetaPage 的元数据是由 BufferPoolManager 管理的,所以在使用 MetaPage 时,不需要额外的加锁,需要 BPM 的 latch 保护。
- PageGuard 中调用 UnpinPage() 的时候传入的是 PageGuard 的 is_dirty_,而不是 Page 的 is_dirty_,二者不一样,需要进行区分。
- 理解清除需求以及目标之后再实现,这很重要。
TIP:
- 并发控制:主要为 RAII 的实现,对于 FetchPage() 进行封装,返回值为 PageGuard,并且提供 FetchPageRead() 和 FetchPageWrite() 两个接口,分别用于读取和写入。在调用时就会自动加对应的锁,不需要手动加锁,并且在 PageGuard 析构时会自动释放锁。
- reinterpret_cast<>:在 C++ 中,reinterpret_cast
(...) 用于进行不同类型之间的转换,但是不会进行类型检查,所以使用时要特别小心,确保转换的类型是正确的。在这里对于只读的 Page 调用的有 const 修饰的 GetData(),此时转换的类型也要是 const 类型的。若是可写的,那么调用的是 GetDataMut(),此时转换的类型就不需要 const 修饰。
extendible-hash-index
https://github.com/Cookiecoolkid/Cookiecoolkid.github.io/2025/01/29/extendible-hash-index/