CMU15-445 lab1 BufferPool实现过程(100% pass)

首先为LRUReplacer添加成员变量,这里直接使用STL的unordered_map和list,为了保证线程完全,直接在函数外面加互斥锁。

 

 private:
  using ListIterator = typename std::list<frame_id_t>::const_iterator;
  using CacheMap = std::unordered_map<frame_id_t,ListIterator>;

  std::list<frame_id_t> m_lruList;
  CacheMap m_lruMap;
  std::mutex m_lock;

 

注意,这几个函数的描述不是特别清楚,去test中找测试例子搞清楚这几个方法的含义。

Victim(T*)  找到替换的最久使用的对象,返回T*。

Pin(T) 从LRUReplacer删除对象T。

Unpin(T) 插入T到LRUReplacer中。注意当没有位置时,要进行淘汰掉最久没有使用的。

Size()就没有什么好说的。

  • Victim(T*) : Remove the object that was accessed the least recently compared to all the elements being tracked by the Replacer, store its contents in the output parameter and return True. If the Replacer is empty return False.
  • Pin(T) : This method should be called after a page is pinned to a frame in the BufferPoolManager. It should remove the frame containing the pinned page from the LRUReplacer.
  • Unpin(T) : This method should be called when the pin_count of a page becomes 0. This method should add the frame containing the unpinned page to the LRUReplacer.
  • Size() : This method returns the number of frames that are currently in the LRUReplacer.

接下来实现这六个函数

FetchPageImpl(page_id)
NewPageImpl(page_id)
UnpinPageImpl(page_id, is_dirty)
FlushPageImpl(page_id)
DeletePageImpl(page_id)
FlushAllPagesImpl()

这几个函数在文档中描述不是特别清楚。要结合注释揣摩,其中UnpinPage的实现需要特别注意

bool BufferPoolManager::UnpinPageImpl(page_id_t page_id, bool is_dirty) {
  std::scoped_lock bpm_slk{latch_};
  if(page_table_.find(page_id) == page_table_.end()){
    return false;
  }
  auto frame_id = page_table_[page_id];
  if(pages_[frame_id].pin_count_ > 0){
    pages_[frame_id].pin_count_--;
  }
  if(pages_[frame_id].pin_count_ == 0){
    replacer_->Unpin(frame_id);
  }
  if(is_dirty){
    pages_[frame_id].is_dirty_ = true;
  }
  return true;
}

Fetch和New都涉及到页面置换算法,所以为了简单,封装一个统一的页面置换操作

frame_id_t BufferPoolManager::find_replace() {
  frame_id_t replace_id = -1;
  if (!free_list_.empty()) {
    replace_id = free_list_.front();
    free_list_.pop_front();
  } else if (replacer_->Size() > 0) {
    replacer_->Victim(&replace_id);
    page_table_.erase(pages_[replace_id].page_id_);
    if (pages_[replace_id].IsDirty()) {
      disk_manager_->WritePage(pages_[replace_id].page_id_, pages_[replace_id].GetData());
    }
  }
  return replace_id;
}

另外对Page结构也做一个初始化操作

void BufferPoolManager::init_new_page(frame_id_t frame_id, page_id_t page_id) {
  pages_[frame_id].page_id_ = page_id;
  pages_[frame_id].pin_count_ = 1;
  pages_[frame_id].is_dirty_ = false;
}

另外还需要注意C++ 互斥锁的操作。在所有方法最开始都加上。

std::scoped_lock bpm_slk{latch_};

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值