| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> CMU15-445/645 Database System/Fall2021 #Project1_BufferPoolManager详细解析 -> 正文阅读 |
|
[数据结构与算法]CMU15-445/645 Database System/Fall2021 #Project1_BufferPoolManager详细解析 |
CMU 15-445/645 Database System/Fall2021 #Project1_BufferPoolManager CMU 15-445是一门数据库系统课程——官方主页CMU-15445。由于官方网站提示不能在公开网络张贴答案,所以本文不会有全面详细的代码,但是会有详细的解析。 一、LRU Replacement Policy 第一个任务是实现缓冲池的LRU算法,这里的LRU算法提供的接口和日常在LeetCode刷题中遇到的接口不一样:
我们需要实现的是LRUReplacer的构造函数,析构函数,Victim淘汰函数,Pin函数,Unpin函数。LRUReplacer中装的是,frame_id,也可以理解为页框号,这里Victim函数需要做的事情就是淘汰LRUReplacer(头进尾出)中末尾的frame_id。 Pin函数的逻辑需要注意一下,这里的Pin是指某一页被钉住了,不会从BufferPool中被换出,而所有被换出的页对应的页框号frame_id都需要Victim接口来提供。所以这里Pin的逻辑是将该页对应的页框号从LRUReplacer中踢出,这样Victim函数就用于无法得到该页的页框号,从而达到“钉住”的效果。 Unpin相反,需要我们将某页对应的页框号加入到LRUReplacer之中,这样Victim函数就能得到该页框号,从而进行页换出处理。 这里lru的实现就是采用经典的双向链表加哈希表的方式,不过多赘述,但是这里LRU算法有一个奇怪的地方,在第二次将同一个frame_id放入LRUReplacer时,不能将其移动到队头,这么做了反而测试会不通过。 二、Buffer Pool Manager Instance 这个任务算是Project1中的核心任务,需要实现以下6个函数:
在实现函数之前,需要对一些关键概念进行理解,如下图:
在进行页换出的时候,通过LRUReplacer的Victim函数可以找到应该被换出的页所对应的页框号,然后将页框中的内容也就是Page的元数据清空,再放入新换入的页并更新元数据即可。在这个任务中Pin和Unpin的逻辑与上个任务相反: 在这些函数中都需要对考虑线程安全,这里使用粗粒度的互斥锁实现,为了简洁方便,可以使用unique_lock。 FlushPgImp函数需要将参数指定的page_id对应的页刷盘,通过page_id在page_table_中查到对应的页框号,然后访问Page数组page_就可得到Page对象,FlushAllPgImp直接对page_table中的page_id挨个调用FlushPgImp即可,注意该函数不用加锁,否则重复对同一个互斥量加锁会造成死锁。 如上图所示,无论是pin还是unpin的页,都能在page_table_中找到所对应的页框号。free_list中的页框没有装数据页,获取新页框先从free_list中获取,取不到再去replacer中使用Victim函数获取淘汰页占用的页框的页框号,从而得到页框。 NewPgImp函数返回一个新的页框,实现的时候需要注意第三步,需要在更新P的元数据之前将其原来的page_id从page_table_中移除,然后插入新的{page_id,frame_id}到page_table_。另外新的Page的pin_count_应该为1。 FetchPgImp函数将指定page_id的页从Disk中读入到BufferPool,如果page_table_中已经存在该页,对应的pin_count++,并调用replacer的Pin函数,将该页对应的页框号从LRUReplacer中移除,然后是获取页框,和NewPgImp类似,具体实现按照注释步骤来即可。 DeletePgImp函数负责删除参数page_id指定的页占用的页框,清空其元数据后归还到free_list中,这里需要注意在清空元数据后需要调用replacer->Pin()函数,防止删除后页框号同时在replacer和free_list中,其他实现根据注释提示来即可。 UnpinPgImp函数还需要注意,只有当参数is_dirty为true的时候才能将Page的数据成员is_dirty_置为true,不能直接赋值,如果原来该page的is_dirty_是true,这里传入is_dirty_为false,就会导致错误。
在单个BufferPool Instance的情况下,多个线程会争抢一个互斥量,一个潜在的解决方法是一个系统中有多个BufferPool Instance,他们每一个都拥有一个自己的互斥量(mutex/latch)。 这里要求实现下列10个函数,大部分只需调用上个任务的方法即可,下面贴出部分函数实现。 部分自己添加的数据成员:
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 8:24:52- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |