P1 缓冲池管理

news2024/10/6 10:32:03

文章目录

    • Task1 LRU-K 替换策略
    • Task2 缓冲池管理
    • Task3 读/写页面保护

Task1 LRU-K 替换策略

LRU-K算法:当访问次数达到K次后,将数据索引从历史队列移到缓存队列中(缓存队列时间降序);缓存数据队列中被访问后重新排序;需要淘汰数据时,淘汰缓存队列中排在末尾的数据。

相比于LRU-1,缓存数据更不容易被替换,而且偶发性的数据不易被缓存。在保证了缓存数据纯净的同时还提高了热点数据命中率。

一般来说通过以下数据结构实现:

左边队列是优先淘汰的访问历史队列,一有数据被访问就加入该队列,若此后没被访问到K次,且需要淘汰访问,就先入先出地淘汰掉。若访问到了K次,就进入右侧缓存数据队列,若再被访问就移到队尾,这样若此后没在被访问就会被先进先出地淘汰掉。淘汰历史是访问历史队列优先检查是否有可淘汰的历史,若没有则再看缓存数据队列是否有。

该代码实现的LRU-K替换算法是通过将一条双向链表分割成两部分来完成功能的

LRUKNode *head_;
LRUKNode *medium_;
LRUKNode *tail_;

medium–tail是访问历史队列,head–medium是缓存数据队列,链表上每个结点有一个标志位LRUKNode::is_evictable_来标志是否是可以被淘汰的

帧与队列节点的映射是通过无序map实现的

std::unordered_map<frame_id_t, LRUKNode *> node_store_;
std::lock_guard<std::mutex> lock(latch_);//std::mutex latch_;

通过"资源分配时初始化"(RAII)方法来加锁、解锁,避免了在临界区中因为抛出异常或return等操作导致没有解锁就退出的问题,lock_guard的作用域与普通对象相同,可以在一个方法中使用多次

Task2 缓冲池管理

页和帧是对同一数据在不同位置的不同称呼。页是在磁盘上存储的数据块,而帧是在内存中存储的数据块。当需要访问一个页时,DBMS会将该页加载到一个帧中(帧保存在缓冲池里),以便在内存中进行快速访问和修改。因此,页和帧实际上是同一数据在不同位置的两种表示方式。

Page *pages_;//缓冲池页面数组,虽然叫pages_但是保存的是帧,下标是frame_id
std::unordered_map<page_id_t, frame_id_t> page_table_;//页和帧的映射关系,通过page_id找frame_id,从而在pages_中找到内存缓冲池中的页数据
std::list<frame_id_t> free_list_;//记录哪些帧(pages_的下标)是空闲状态,BufferPoolManager初始化时全部帧都在这里
std::unique_ptr<LRUKReplacer> replacer_;//进行LRU-K策略的成员,传入frame_id表示对帧进行访问

BufferPoolManager::NewPage()先从free_list_中找空闲帧,有则弹出,没有就调用replacer_的LRU-K策略淘汰一个帧,在page_table_中取消映射,若淘汰的帧对应的页是脏页,就写入硬盘。然后分配page_id并将帧id交给page_table_来构建映射,从硬盘读数据到pages_并设置id,调用replacer_的LRU-K策略添加对帧id的访问历史并设为不可淘汰,以防止使用时淘汰。

BufferPoolManager::FetchPage()先从page_table_缓冲池中找页,找不到就找free_list中的空闲帧,没有就先replacer_淘汰一个(淘汰访问历史、若为脏页就将pages_中帧写入硬盘、删除page_table_中的页帧映射)后用淘汰的页。获取页帧后配置pages_中的页id并读取硬盘中页数据,构建页帧映射。将该页帧加入replacer_的LRU-K策略队列并设置不可淘汰。比BufferPoolManager::NewPage()多找了page_table_

BufferPoolManager::UnpinPage()用于设置page_table_中指定页映射的帧可淘汰

BufferPoolManager::FlushPage()pages_中指定页id的帧数据写入硬盘

Task3 读/写页面保护

在缓冲池管理器中,FetchPage 和 NewPage 函数返回指向已经固定的页面的指针。固定机制确保页面不会被驱逐,直到页面上没有更多的读写操作。为了表明内存中不再需要该页面,程序员必须手动调用 UnpinPage。

另一方面,如果程序员忘记调用 UnpinPage,页面将永远不会被驱逐出缓冲池。后果是由于缓冲池现在使用更少的帧进行操作,因此将会有更多的页面进出磁盘。不仅性能会受到影响,漏洞也很难被检测到。

你将实现 BasicPageGuard,它存储指向 BufferPoolManager 和 Page 对象的指针。页面保护确保一旦 page 对象超出作用域,就在相应的 page 对象上调用 UnpinPage。注意,它仍然应该为程序员提供一个方法来手动解除页面的固定。

在未来的项目中,多个线程将对同一个页面进行读写,因此需要使用读写锁来确保数据的正确性。请注意,在 Page 类中,有用于此目的的相关方法。类似于页面的解除锁定,程序员在使用页面后可能会忘记解除锁定。为了缓解这个问题,你将实现 ReadPageGuard 和 WritePageGuard,它们会在页面超出范围时自动解锁。

BasicPageGuard类成员属性有:

BufferPoolManager *bpm_{nullptr};
Page *page_{nullptr};
bool is_dirty_{false};

可见是对BufferPoolManangerPage的进一步封装管理,ReadPageGuardWritePageGuardBufferPoolMananger的好友类。

BasicPageGuard::Drop()保证在相应 page 对象上调用 UnpinPage。同时在Drop()operator=()中若封装的页非空就解读/写锁,而在有读写保护版的FetchPage(),即BufferPoolMananger::FetchPageRead()BufferPoolManager::FetchPageWrite()中进行加锁

return reinterpret_cast<T *>(GetDataMut());
//强制类型转换运算符 <要转换到的类型> (待转换的表达式)

static_cast用于进行比较"自然"和低风险的转换,如整型和浮点型、字符型之间的互相转换。另外,如果对象所属的类重载了强制类型转换运算符 T(如 T 是 int、int* 或其他类型名),则 static_cast 也能用来进行对象到 T 类型的转换。

reinterpret_cast用于进行各种不同类型的指针之间、不同类型的引用之间以及指针和能容纳指针的整数类型之间的转换。转换时,执行的是逐个比特复制的操作。

const_cast运算符仅用于进行去除 const 属性的转换,它也是四个强制类型转换运算符中唯一能够去除 const 属性的运算符。

dynamic_cast是通过"运行时类型检查"来保证安全性的。dynamic_cast 不能用于将非多态基类的指针或引用强制转换为派生类的指针或引用——这种转换没法保证安全性,只好用 reinterpret_cast 来完成。

C++强制类型转换运算符(static_cast、reinterpret_cast、const_cast和dynamic_cast) (biancheng.net)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1118497.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python--循环中的两大关键词 break 与 continue

在Python循环中&#xff0c;经常会遇到两个常见的关键词&#xff1a;break 与 continue break&#xff1a;代表终止整个循环结构 continue&#xff1a;代表中止当前本次循环&#xff0c;继续下一次循环 break&#xff1a; 英 /breɪk/ v. 打破&#xff0c;打碎&#xff0c…

c语言练习95:练习使用双向链表(实现增删改查)

练习使用双向链表&#xff08;实现增删改查&#xff09; 是指针指向了一块被释放的空间 解决方案&#xff1a; plistNULL List.h #pragma once #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<assert.h> #include<…

java实现多线程下载器

前言&#xff1a; &#x1f44f;作者简介&#xff1a;我是笑霸final&#xff0c;一名热爱技术的在校学生。 &#x1f4dd;个人主页&#xff1a;个人主页1 || 笑霸final的主页2 &#x1f4d5;系列专栏&#xff1a;项目专栏 &#x1f4e7;如果文章知识点有错误的地方&#xff0c;…

2316. 统计无向图中无法互相到达点对数(leetcode)并查集-------------------Java实现

2316. 统计无向图中无法互相到达点对数&#xff08;leetcode&#xff09;并查集-------------------Java实现 题目表述 给你一个整数 n &#xff0c;表示一张 无向图 中有 n 个节点&#xff0c;编号为 0 到 n - 1 。同时给你一个二维整数数组 edges &#xff0c;其中 edges[i…

使用IDEA时遇到java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver报错的解决方案

目录 一、项目环境二、可能原因解决方案1. 没有导入mysql的jar包2. mysql的jar包版本问题 一、项目环境 二、可能原因解决方案 1. 没有导入mysql的jar包 先检查项目lib文件夹下有没有mysql的jar包&#xff0c;没有就把jar包复制到该目录下 再检查项目结构中有没有导入mysql…

使用vscode搭建虚拟机

首先vscode插件安装 名称: Remote - SSH ID: ms-vscode-remote.remote-ssh 说明: Open any folder on a remote machine using SSH and take advantage of VS Codes full feature set. 版本: 0.51.0 VS Marketplace 链接: https://marketplace.visualstudio.com/items?it…

掌握 C++ 中 static 关键字的多种使用场景

static是什么 在最开始C中引入了static关键字可以用于修饰变量和函数&#xff0c;后来由于C引入了class的概念&#xff0c;现在static可以修饰的对象分为以下5种&#xff1a; 成员变量&#xff0c;成员函数&#xff0c;普通函数&#xff0c;局部变量&#xff0c; 全局变量 s…

vmware安装 Rocky9(自定义分区安装)

一、下载镜像 访问官网&#xff0c;下载dvd的镜像 Download Rocky | Rocky Linuxhttps://rockylinux.org/download 二、新建vmware虚拟机 1、vmware尽量选择vmware17 2、下一步 3、稍后安装 4、选择系统类型&#xff1a;red hat9 5、自定义安装位置 6、根据电脑配置&#…

动画系统的前世今生(一)

掐指一算&#xff0c;五年没更新过我的CSDN账号啦&#xff0c;方向也从人工智能变成了计算机图形学&#xff0c;当然也依旧会关注AI的发展&#xff0c;之前在知乎上写了一些文章[传送门]&#xff0c;后续也会逐渐同步到CSDN上&#xff5e; 这个系列将包含五篇文章&#xff0c;内…

allegro中shape的一些基本操作(二)——铜皮添加网络、合并shape

给铜皮&#xff08;shape&#xff09;添加网络 例如下图&#xff0c;想要给这个新添加的shape添加到GND的网络&#xff0c;可以先选中这个shape&#xff0c;让其进入shape编辑模式&#xff0c;然后再右键点击&#xff0c;最后再PCB上点击GND网络 选中铜皮后在铜皮上右键&…

字典树学习笔记

trie 树&#xff0c;即字典树&#xff0c;是一种可以实现 O ( S ) O(S) O(S) 的预处理&#xff08; S S S 为所有字符串的长度和&#xff09;&#xff0c; O ( N ) O(N) O(N)&#xff08; N N N 为查询的字符串的长度&#xff09;的查询的数据结构。 举个栗子&#xff0c;对于…

Rust-后端服务调试入坑记

这篇文章收录于Rust 实战专栏。这个专栏中的相关代码来自于我开发的笔记系统。它启动于是2023年的9月14日。相关技术栈目前包括&#xff1a;Rust&#xff0c;Javascript。关注我&#xff0c;我会通过这个项目的开发给大家带来相关实战技术的分享。 如果你关注过我的Rust 实战里…

Baize_h1mini六足机器人零件准备

导航在这里&#xff1a; Baize_H1mini六足机器人制作教程&#xff08;开源&#xff09;_ros 六足机器人教程-CSDN博客 你现在在地图的红色字体位置&#xff08;走到终点就制作完成了&#xff09;&#xff1a; 重要提示&#xff1a;自己使用打印机打印零件时&#xff0c;对于新…

Pandas数据处理分析系列5-数据如何提取

Pandas-数据提取 ①通过索引提取数据 # 提取前10行数据 df.head(10) # 提取末尾10行数据 df.tail(10) # 通过列名提取数据 df[列名’] # 通过布尔条件提取数据 df[df[列名] > 10] # 多条件过滤 df[(df[列名1] > 10) & (df[列名2] < 20)] df1=pd.read_excel(&quo…

14.Tensor Product:Covector-Covector Pairs

该文张量积仍使用一些非标准的符号。 左边的将是本文使用的 &#xff0c; 右边的是标准。 Covector-Covector Pairs 是Bilinear Forms 在上一节中&#xff0c; Linear Maps linear combinations of vector-covector pairs 这种将向量和协向量组合在一起的过程叫 张量积 这…

基于springboot实现java学习平台项目【项目源码+论文说明】计算机毕业设计

基于springboot实现java学习平台演示 摘要 在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括学习平台的网络应用&#xff0c;在外国学习平台已经是很普遍的方式&#xff0c;不过国内的管理平台可能还处于起步阶段。学习平台具…

Leetcode 第 360 场周赛题解

Leetcode 第 360 场周赛题解 Leetcode 第 360 场周赛题解题目1&#xff1a;2833. 距离原点最远的点思路代码复杂度分析 题目2&#xff1a;2834. 找出美丽数组的最小和思路代码复杂度分析 题目3&#xff1a;2835. 使子序列的和等于目标的最少操作次数思路代码复杂度分析 题目4&a…

使用GoogleNet网络实现花朵分类

一.数据集准备 新建一个项目文件夹GoogleNet&#xff0c;并在里面建立data_set文件夹用来保存数据集&#xff0c;在data_set文件夹下创建新文件夹"flower_data"&#xff0c;点击链接下载花分类数据集https://storage.googleapis.com/download.tensorflow.org/exampl…

基于TLS的抓包内容分析解决方法

https网络包传输过程中经SSL/TSL加密后&#xff0c;在协议分析工具中&#xff08;如wireshark&#xff09;对于应用层http内容数据无法分析。要解决这个问题&#xff0c;可以参考以下2种方法&#xff0c; &#xff08;1&#xff09;配置SSLKEYLOGFILE环境变量配置wireshark TLS…

由浅入深学习nginx

nginx&#xff08;高性能的http和反向代理服务器&#xff09;的优点&#xff1a; &#xff08;1&#xff09;占有内存少 &#xff08;2&#xff09;并发能力强&#xff08;支持5万个&#xff09; &#xff08;3&#xff09;专为性能优化而开发 nginx主要可以实现的功能有这么几…