数据库课程 CMU15-445 2023 Fall Project-1 Buffer Pool Manager

0 实验结果

在这里插入图片描述

1 任务总结

本章按照任务书,需要完成

  1. LRU-K替换策略
  2. 磁盘调度器——后台线程接收请求,处理数据的读/写。
  3. 缓冲池管理——使用上面完成的功能,来对抽象的页操作。
1.1 LRU-K替换策略

每个函数的说明都很清楚,按照指示来写即可。
主要说明一些坑点

1.1.1 变量及其作用

时间戳这里要提一下,因为RecordAccess的访问很频繁,时间很短,获取真实的时间戳作用不大。
所以可以每RecordAccess一次,就递增当前的时间戳,计算 K距离时,通过当前时间戳和从当前开始向前数第K次的作差。

// 可以被淘汰置换出的帧数量
size_t curr_size_{0};
// 当前的时间戳
size_t current_timestamp_{0};
1.1.2 坑点

需要明确LRU-K算法,这里算法有点特殊
1.1.2.1 当一个帧访问次数不到K次时,K-距离都是INF,此时比较的是帧最早访问(即第一次)的时间,时间越早,越先被淘汰。
举个例子:当K=3时,此时因为帧1和帧2都没有访问到3次,而帧1最早访问,所以淘汰帧1。

frame_idtime_stamp
10
21
12
1.2 磁盘调度器

实现简单,没有坑点,过~

1.3 缓冲池管理

一开始对list,map,page分别上锁,测试无法通过,后改为使用大颗粒锁(即函数从头到尾锁定)。

1.3.1 NewPage

创建新的页面之后,先使用RecordAccess创建节点,再SetEvictable将其设置为Pin。
修改page的元数据,包括:
page_id_pin_count_is_dirty_ 等元数据

1.3.2 FetchPage

获取页面的时候,如果缓冲池中本来就存在,则pin_count_ 需要+1,如果是通过淘汰其他页面得到的,pin_count_ 需要重置为1。

1.3.3 UnpinPage

传入此函数的is_dirty使用注意:
只有当页面不脏时,需要设置此位为传入的参数。
并且多线程环境下 一定要 每次都执行判断is_dirty并赋值操作。

我在这里遇到的问题,就是它导致的。

[ 2.75] get 2: total_cnt=648 throughput=251.583 avg_throughput=235.808
page seed not consistent: seed_=0 seed=1

2 知识总结

2.1 std::list

一个双向链表容器
尾插入:push_back
头插入: push_front
删除元素:

pop_back
pop_front
erase

获取元素:

front()
back()

2.2 std::optional

表示一个可能存在也可能不存在的值,作用是:使用std::nullopt,避免使用 nullptr 或特殊值(如 -10)来表示“无值”的情况。
方法:

emplace

2.3 std::promise

并发编程中传递值或异常.
可以与 std::future 一起使用,以实现异步操作.
std::promise 可以存储任何类型的值.
std::future::get() 是一个阻塞调用,它会一直等待,直到 std::promise 设置了值或异常.

2.4 std::unordered_map

std::map 是一个有序的关联容器,基于红黑树(一种自平衡二叉搜索树)实现,
平均时间复杂度为 O(log n)。
由于红黑树的结构,内存占用相对较高。

std::unordered_map 是一个无序的关联容器,基于哈希表实现。
平均时间复杂度为 O(1),最坏情况下为 O(n),内存占用相对较低。

std::unordered_map的赋值

std::unordered_map<int,complex_type>data_src;

1. 赋值运算符拷贝
std::unordered_map<int,complex_type>data_src_copy = data_src;
2. 拷贝构造函数
std::unordered_map<int,complex_type>data_src_copy(data_src);

键和值 都会被拷贝到新的 std::unordered_map 容器中,如果是指针类型,仅复制指针地址。

	complex_type& operator=(const complex_type& that)
	{
		std::cout << "赋值重载" << std::endl;
		this->age = that.age;
		this->name = that.name;
		return *this;
	}
    // 结果
    ============
	有参构造函数
	拷贝构造函数
	============
	有参构造函数
	默认构造函数
	赋值重载
	============
	拷贝构造函数
	拷贝构造函数
	============
	赋值重载
	赋值重载
	============
	有参构造函数
	赋值重载
	============
	syh dd

	// 代码
    std::unordered_map<int,complex_type>data_src;
    std::cout << "============" << std::endl;
    data_src.emplace(1,complex_type(10, "syh"));
    std::cout << "============" << std::endl;
    data_src[2] = complex_type(20,"mike");
    std::cout << "============" << std::endl;
    std::unordered_map<int,complex_type>data_src_copy(data_src);// 因为有两个值,所以发生了两次拷贝
    std::cout << "============" << std::endl;
    data_src_copy = data_src;
    std::cout << "============" << std::endl;
    data_src_copy[1] = complex_type(57,"dd");
    std::cout << "============" << std::endl;
    std::cout << data_src[1].name<<" " << data_src_copy[1].name << std::endl;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值