【CMU 15-445】Proj1 Buffer Pool Manager

2023-11-10 22:28
文章标签 15 manager buffer 445 pool cmu proj1

本文主要是介绍【CMU 15-445】Proj1 Buffer Pool Manager,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Buffer Pool Manager

  • 通关记录
  • Task1 LRU-K Replacement Policy
  • Task2 Disk Scheduler
  • Task3 Buffer Pool Manager
    • FlushPage
    • FlushAllPages
    • UnpinPage
    • NewPage
    • FetchPage
    • DeletePage
  • Optimizations

CMU-15445汇总
本文对应的project版本为CMU-Fall-2023的project1
由于Andy要求,本博客只提供思路,不会公开任何代码

通关记录

在这里插入图片描述

在这里插入图片描述
目前的rank还比较低,lru-k后续会优化下

Task1 LRU-K Replacement Policy

LRU-KLRU一样,都属于缓冲区的页面置换算法,不同的是,LRU-K考虑的是页面的之前第K次访问时间戳与当前时间戳的差(若不足K次则优先驱逐,若有多个访问不足K次的页面,则按LRU规则驱逐),而LRU考虑的是页面最近一次访问时间戳与当前时间戳的差。一个具体的例子如下图所示,假设K=3buffer大小为3,访问序列为1 2 3 2 3 2 3 1 1 4,当访问4时,会将1驱逐掉,图中当页面访问不足K次时,时间戳为最新访问时间戳,否则为前第K次的时间戳(蓝色数字为时间戳)。
在这里插入图片描述
Task1的要求是实现src/buffer/lru_k_replacer.cpp文件中的如下几个函数:

  • Evict(frame_id_t* frame_id):使用LRU-K算法驱逐一个frame,并使用参数返回frame_id;返回值类型为bool,若驱逐成功返回true,若当前可驱逐frame数量为0,则返回false
  • RecordAccess(frame_id_t frame_id):记录给定frame的访问历史
  • Remove(frame_id_t frame_id):将给定framebuffer中移除
  • SetEvictable(frame_id_t frame_id, bool set_evictable):设置frame可驱逐不可驱逐,若设置前后该属性不一致,则需要修改类内维护的可驱逐frame数量属性
  • Size():返回当前可驱逐frame数量

个人建议的实现顺序为Size->SetEvictable->RecordAccess->Evict->Remove
主要的难点在于RecordAccessEvict中各frameLRU-K信息维护与驱逐算法实现,目前我实现的版本为暴力版本,即在RecordAccess为每个frame维护一个大小为K的访问时间戳队列;在Evict中,遍历所有可驱逐的frame,找出LRU-K timestamp最小的那个,将其驱逐。(这个做法明显太慢了,后续优化一下)

Task2 Disk Scheduler

此部分需要实现一个简单的磁盘调度器,接收BufferPoolManager发来的读写磁盘请求放入一个请求队列中;然后启动一个新线程,不断从请求队列中获取请求,根据请求类型调用对应DiskManager的读写函数进行磁盘读写。主要实现文件src/storage/disk/disk_scheduler.cpp中的两个函数:

  • Schedule(DiskRequest r):接收请求并放入请求队列
  • StartWorkerThread():线程函数,从请求队列中获取新请求,并根据请求类型调用磁盘读写函数

个人建议的实现顺序为Schedule->StartWorkerThread
不需要考虑队列的线程安全性,已经有一个Channel类帮忙实现了生产者消费者模型;关于std::promise的用法,可参考disk_scheduler_test.cpp文件。

Task3 Buffer Pool Manager

这一部分需要实现一个BufferPoolManager,结合前两部分实现的LRU-K ReplacerDisk Scheduler进行缓冲区的管理物理页的开辟、获取与释放BufferPoolManager类维护的数据结构中包含一个Page类的数组(在BufferPoolManager的构造函数中会开辟空间),数组中的每个元素即为一个一个的framePage类主要包含以下几个成员:

  • page_id_t page_id_:表示该frame指向的物理页面id
  • char* data_:用于储存对应物理页面中的真实数据
  • int pin_count_:故名思意,该framepin count,表示被多少个进程pin住,当pin_count_不为0时,该frame不能被驱逐
  • bool is_dirty_:该frame是否被写过,如果被写过则需要将内容写回磁盘

在这个任务中,我们需要实现文件src/buffer/buffer_pool_manager.cpp中的以下方法:

  • FetchPage(page_id_t page_id)
  • UnpinPage(page_id_t page_id, bool is_dirty)
  • FlushPage(page_id_t page_id)
  • NewPage(page_id_t* page_id)
  • DeletePage(page_id_t page_id)
  • FlushAllPages()

个人建议的实现顺序为:FlushPage->FlushAllPages->UnpinPage->NewPage->FetchPage->DeletePage
接下来我介绍下我每个函数的实现思路

FlushPage

功能:将给定的缓存页写回磁盘,无视is_dirty_标志
参数:page_id表示给定的想要flush到磁盘的物理页id
返回值:bool,若page_id不存在,返回false;否则true
实现:BufferPoolManager类中需要维护一个page_table_,存放着每个已分配物理页对应的frame,通过page_table_查找到给定page_id对应的frame_id,然后调用Disk Scheduler提供的scheduler方法发出写请求即可,最后清空frameis_dirty_标志。

FlushAllPages

功能:将所有有效的缓存页写回磁盘,无视is_dirty_标志
参数:无
返回值:void
实现:遍历整个buffer的所有frame,若frame上的page_id不为空,则使用与FlushPage类似方法写回磁盘即可。

UnpinPage

功能:将指定的物理页对应的framepin_count减1
参数:page_id表示给定的物理页id,is_dirty表示在pin住frame时是否发生了写操作
返回值:bool,若指定的物理页id不存在,返回false;否则true
实现:首先根据page_id找到对应的frame,将framepin_count减1,此时若pin_count为0,还需调用LRU-K Replacer提供的SetEvictable函数设置frame的状态为可驱逐。然后,根据is_dirty参数设置frameis_dirty_成员即可。

NewPage

功能:找到一个空闲frame新分配一个物理页,并将该物理页的内容读取到刚找到的这个frame
参数:page_id_t *page_id分配的物理页id以参数形式返回
返回值:Page*表示新分配的物理页最终存放的frame地址
实现:找到空闲的frame首先从一个free list里面找,如果free list为空表明现在的buffer已满,需要使用LRU-K Replacer驱逐一个frame并将其作为新物理页的承载体(若该frameis_dirty_true,那么需要先将frame中的内容写回对应的物理页)。接着,调用AllocatePage函数分配新物理页,并设置frame中的相关成员即可。最后,需要调用LRU-K Replacer提供的RecordAccess函数记录下访问历史,并调用SetEvictable函数pin住frame

FetchPage

功能:给定物理页id,获取该物理页所对应的frame
参数:page_id表示给定的物理页id
返回值:Page*表示给定物理页所在的frame地址
实现:首先从page_table_中寻找给定物理页对应的frame,若未找到,则需要驱逐缓存页,这一块的处理与NewPage函数中驱逐的处理一致,代码可以复用;若找到则进行下一步。然后,将最终确定的frame记录访问历史pin住操作,也与NewPage中的操作一致。

DeletePage

功能:给定物理页id,将物理页对应的framebuffer中删除
参数:page_id表示给定的物理页id
返回值:bool,物理页不在buffer中或删除成功则返回true;物理页存在且对应的frame仍然被pin住(pin_count不为0)时,则返回false
实现:查找物理页对应的frame,将page_idpage_table_中移除,调用LRU-K ReplacerRemove函数将frame_idbuffer中移除,并将frame_id加入free_list_中,重置frame的成员,最后调用DeallocatePage将物理页回收

Optimizations

这篇关于【CMU 15-445】Proj1 Buffer Pool Manager的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/385674

相关文章

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

ORACLE 11g 创建数据库时 Enterprise Manager配置失败的解决办法 无法打开OEM的解决办法

在win7 64位系统下安装oracle11g,在使用Database configuration Assistant创建数据库时,在创建到85%的时候报错,错误如下: 解决办法: 在listener.ora中增加对BlueAeri-PC或ip地址的侦听,具体步骤如下: 1.启动Net Manager,在“监听程序”--Listener下添加一个地址,主机名写计

Adblock Plus官方规则Easylist China说明与反馈贴(2015.12.15)

-------------------------------特别说明--------------------------------------- 视频广告问题:因Adblock Plus的局限,存在以下现象,优酷、搜狐、17173黑屏并倒数;乐视、爱奇艺播放广告。因为这些视频网站的Flash播放器被植入了检测代码,而Adblock Plus无法修改播放器。 如需同时使用ads

15 组件的切换和对组件的data的使用

划重点 a 标签的使用事件修饰符组件的定义组件的切换:登录 / 注册 泡椒鱼头 :微辣 <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-

Java 文件读写最好是用buffer对于大文件可以加快速度

参考例子: FileReader fileReader = new FileReader(filename);BufferedReader bufferedReader = new BufferedReader(fileReader);List<String> lines = new ArrayList<String>();String line = null;while ((line =

【Node】Buffer 与 Stream

node 为什么会出现 Buffer 这个模块 在最初的时候,JavaScript 只运行在浏览器端, 对于处理 Unicode 编码的字符串很容易,但是对于处理二进制以及非 Unicode 编码的数据便无能为力。 不过对于 Server 端操作来说 网络I/O 以及 文件I/O 的处理是必须的,所以 Node 中便提供了 Buffer 类处理二进制的数据。 二进制缓冲区 Buffer

Oracle Enterprise Manager:Oracle数据库管理的高效工具

在数据库管理和维护中,Oracle Enterprise Manager(OEM)是一个强大的工具,它提供了一个集中的平台来监控、管理和优化Oracle数据库环境。通过使用Oracle Enterprise Manager,数据库管理员可以提高效率、减少手动干预并确保数据库系统的稳定性和性能。本文将详细介绍如何在Oracle中使用Oracle Enterprise Manager,包括其主要功能、

java基础总结15-面向对象11(抽象类)

下面通过一下的小程序深入理解抽象类 因此在类Animal里面只需要定义这个enjoy()方法就可以了,使用abstract关键字把enjoy()方法定义成一个抽象方法,定义如下:public abstract void enjoy();   从某种意义上来说,抽象方法就是被用来重写的,所以在父类声明的抽象方法一定要在子类里面重写。如果真的不想在子类里面重写这个方法,那么可以再在子类里

15年亚洲区长春站赛后总结

刷题打比赛的日子才叫青春   今年和ljy、lsj组队去长春站。这支队伍是我很放心的一支队伍,ljy可以做数学题和复杂思维题,lsj思维缜密可以和ljy对思路,我负责手速狗+模板暴力流。 有了去年两场亚洲区的经验,心态有了很大变化,也深知赛场上风云莫测,不至最后一分钟,仍未分胜负。开场的F题卡了很久,WA了很多发,这种复杂思维题丢给ljy和lsj搞了。我去开L题,给LJY说完题意后,他给