CMU 15445 2023 fall PROJECT #1

写在前面

总算是过了,以为之前已经reset回23fall的commit了,结果发现buffer_pool_manager.h还是24spring的,估计还得抽时间为这个忙活一下。

task1对于不足k次的是采用FIFO的策略才能通过测试,一开始写的是LRU的策略结果LRUKReplacerTest.Evict (0/6)

接着是task3的笔误,auto BufferPoolManager::DeletePage(page_id_t page_id) -> bool中的free_list_.emplace_back(fid);写成了free_list_.emplace_back(page_id);

通关记录

首先是任务1要实现一个LRU-K算法。在网上查阅一些资料说要弄两个队列去维护?但仔细想了一下只需要一个就好了,正如课程页面写的:

The LRU-K algorithm

The LRU-K algorithm evicts a frame whose backward k-distance is maximum of all frames in the replacer. Backward k-distance is computed as the difference in time between current timestamp and the timestamp of kth previous access. A frame with fewer than k historical accesses is given +inf as its backward k-distance. When multiple frames have +inf backward k-distance, the replacer evicts the frame with the earliest overall timestamp (i.e., the frame whose least-recent recorded access is the overall least recent access, overall, out of all frames).

因为当前时间戳在比较时都是一致的,所以不满足k条访问的设为极小值,然后按顺序插入即可实现一个队列维护操作:

void LRUKReplacer::RecordAccess(frame_id_t frame_id, [[maybe_unused]] AccessType access_type) {
  std::lock_guard<std::mutex> lock(latch_);
  if (static_cast<size_t>(frame_id) > replacer_size_) {
    throw Exception("The frame id is invalid!");
  }

  LRUKNode temp(k_, frame_id);
  if (frame_umap_.count(frame_id) != 0U) {
    auto it = frame_umap_.at(frame_id);
    // FIFO以通过测试
    if (it->Size() + 1 < k_) {
      it->AddRecord(current_timestamp_);
      current_timestamp_ += 1;
      return;
    }
    temp = *it;
    frame_.erase(it);
    frame_umap_.erase(frame_id);
  }
  temp.AddRecord(current_timestamp_);
  current_timestamp_ += 1;

  auto dis = temp.CalKDis();
  // 按顺序插入
  auto it = std::upper_bound(frame_.begin(), frame_.end(), dis,
                             [](size_t dis, const LRUKNode &node) { return dis < node.CalKDis(); });
  it = frame_.insert(it, temp);
  frame_umap_[frame_id] = it;
}

其他的内容按照注释实现即可。
任务2和任务3是实现一个缓存池页面的管理和置换,这里要学一下std::promise
接下来也是跟着注释写,但是在auto BufferPoolManager::FlushPage(page_id_t page_id) -> bool 还是没按照注释不设置is_dirty_ 标志符,感觉还是要设置的。

上一篇
下一篇