自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(23)
  • 收藏
  • 关注

转载 hashtable学习

unordered_xxx的一些问题,学习于C++那些事

2023-10-15 21:42:29 90

原创 C++模板类的声明和定义都要放在.h文件中

因为 C++ 标准明确表示,

2023-07-20 22:42:04 653 1

原创 6.s081 lab3 xv6页表

动机:xv6中的每个进程都有一个用户页表,所有进程共享一个内核页表,为了实现更高的隔离性,我们要为每个进程分配一个自己的内核页表,避免所有进程因为共享内核代码和数据引发的系统错误。现在已经为每个进程完成了自己的内核页表的分配和回收了,现在将进一步优化:为了方便让进入内核的进程获取用户态的地址空间时,不需要再切换到用户态读取,直接在内核中实现查询和地址翻译。所以我们的工作总结就是给每个进程加一个新的内核页,在进入内核后将用户态页表拷贝到内核页表的低地址部分,实现内核中直接查询和地址翻译的工作。

2023-07-17 22:49:55 127

原创 Mit 6.S081 mmap

虚拟内存的初衷是为了增加隔离性,如进程A在物理内存addr64处存放一个变量i,进程B在物理内存addr128存放一个变量j。这会一切正常,但如果进程A在后续中在addr128又存放一个变量k,这时就乱了。进程A操纵了进程B的地址,把进程B的变量覆盖了。这就是因为没有隔离性造成的。所以虚拟内存的就是。

2023-07-13 22:07:30 94 1

原创 MIT 6.s081 XV6线程调度

我们可以看到在加载了cpu的context之后,第一步执行的时c->proc=0,接着执行release(&p->lock),此时的p还是t1,接下来再进行轮询线程,调用t2。注意此时的cpu的context中的ra,是保存的scheduler上一次调用swtch时保存下来的ra,即。还少一个在最后的yield中释放t2的锁。总结下来,对线程调度就清晰很多了!图来自知乎老哥,画的太清楚了!

2023-06-29 23:45:13 91

原创 MIT 6.s081 XV6源码阅读:traps

陷入机制是什么:每个RISC-V CPU都有一组控制寄存器,内核通过向这些寄存器中写入内容来告诉CPU如何处理陷阱,内核可以读取这些寄存器来明确已发生的陷阱。重要寄存器的概述:(具体参见6.s081 xv6 book):内核在这里写入其陷阱处理程序的地址;RISC-V跳转到这里处理陷阱。:当发生陷阱时,RISC-V会在这里保存程序计数器pc(因为pc会被stvec覆盖):(从陷阱返回)指令会将sepc复制到pc。内核可以写入sepc来控制sret的去向。

2023-06-23 12:21:26 135 1

原创 MIT 6.S081 栈的理解

这是xv6 栈的布局,fp为栈帧指针,sp为栈底指针。栈是从高地址向低地址扩张,整个调用过程的第一个函数在高地址,最近的函数在低地址。如A()->B()->C(),则A在高地址,C在低地址。但是每一个栈帧中往下0x8是返回地址,往下0x10是上一个函数对应的栈帧指针,这是固定的。可以看到是符合我们预期的,栈底是sys_sleep,往上依次是syscall、usertrap。在lab4中,我们要做一个backtrace的函数,来打印出函数调用的过程。注意:分清楚栈和栈帧的概念,(借用一下知乎大佬的图)

2023-06-21 12:28:52 63

原创 git实现6.s081版本控制

我们在在MIT 6.s081时会发现每做一个lab都需要从MIT的github上拉下来一个新的分支,但是怎么把我们做的lab上传到自己的github呢?就可以发现github仓库中多了一个分支!接下来继续做下一个实验吧!1、编辑.git文件的config,加入自己的github地址。例如我的是 git push github util:util。我用的github,现在config变成。2、写完lab进行上传。

2023-06-20 15:09:19 122 2

原创 CMU15445 projetc4 并发控制 task1

而在事务A第一次读取数据,比如此时读取了小明的年龄为20岁,事务B执行更改操作,将小明的年龄更改为30岁,此时事务A第二次读取到小明的年龄时,发现其年龄是30岁,和之前的数据不一样了。3、若是旧事物则进行锁升级,若不需要升级直接返回,若有其他事务在升级则回滚(注意,升级的锁该事务应该插在待获取锁的最前面,优先级较高),若排在该事务前面的事务加的锁跟升级的锁有冲突,则也需要回滚。4、RU 读未提交,事务仅需要获取IX、X锁,在growing状态下允许X、IX锁,永远不允许S、IS、SIX锁。

2023-06-12 17:21:04 138

原创 CMU15445/645 SQL实现(火山模型)

execution函数入口。参数为:1、执行计划的指针(来自Plan和Optimizer)2、vector存放提取的数据3、事务4、执行器上下文execution调用入口:while函数不断调用Next,将数据存储在vector中。这里的executor是一个基类指针,会自动根据executor类型调用不同算子的Next的函数。

2023-06-06 19:43:07 286

原创 CMU15-445/645 SQL层

sql层整体介绍

2023-06-06 16:43:14 48

转载 CMU15445 B+树 并发

具体在实现的第一个坑点就是对根节点的处理,根节点是没有父节点保护的。线程在遍历时,只有当子节点被认为是“安全”的,才释放父节点的锁。发生borrow/merge 时,要先对兄弟节点加写锁,可能疑惑,父节点不是锁住了,会有线程拿到兄弟节点的锁吗?在删除过程中,会碰到要把节点删除的情况,这个节点很可能同时也在pageset中,所以要加入DeletedPageSet,等到最后删除完成时,统一的。以上的操作是悲观锁,插入删除都需要对根节点加写锁,根节点是锁的瓶颈,高并发场景下导致效率不高。的访问都是需要锁保护的。

2023-05-30 19:27:16 243

原创 CMU15445 B+树 删除

注意node已经删除掉了目标key,若触发合并或分配现在的size必为minsize-1,兄弟节点给它一个kv就行,就能保证node的size为minsize。(3)删除掉key后,该叶子节点的size小于min_size,兄弟节点没有空位,需要和兄弟节点合并之后进行再分配。(2)删除掉key后,该叶子节点的size小于min_size,兄弟节点有空位,需要和兄弟节点合并。注意:我的实现中删除掉了10,根节点并没有变化,依然有10,这在书中也有提到,是允许的。(1)直接删除掉key,不需要其他操作,结束。

2023-05-30 17:11:08 144

原创 CMU15445 B+树 插入

我的实现在父节点分裂后,兄弟节点的头key并不会在兄弟节点中删除,而B+树的实现示意图中是会把头key从兄弟节点移除,直接加入父节点。4、插入叶子节点的size等于max_size,此时需要分裂为两个节点,前半部分(n/2)的元素在原节点,后半部分元素在新节点。(1)插入到了根节点了,创建新的根节点,并将新的根节点的子节点为old_node和new_node,返回即可。中间节点的size是可以等于max_size的,且注意,中间节点头部还有一个隐藏的无效节点,占用了一个size。

2023-05-29 21:20:49 165 1

原创 CMU15445 b+树 查询

拉取下一层的页面child_page,再转为BPlusTreePage*--child_node,并解除这一层page的锁和UnPin这一层的page,给下一层的page加锁。判断是否查询的最左边和最右边,若是可以直接返回0和size-1的value(下一层的page_id)判断i是否为size,或者i的value不等于想要的value,若是说明没有这个元素,返回false。1、先获取根节点的页面,转为BPlusTreePage*(方便后面转为中间页和叶子页)到下一个层节点的page_id。

2023-05-26 17:25:55 82 1

原创 CMU15445 project2(上)

注意有一个GetMinSize()函数,其中争对该页是否是叶子页,做了不同的处理。因为中间页在头部有一个无效的key,用来指向最左边。叶子节点内部存的是RID,什么是RID?page_id + slot number,唯一标识了一个元组。成员:一个存pair的array。成员:存pari的数组和next_page_id。注意该array中第一个元素是一个无效的key。非叶子节点的value是”指针“,实际上是一个。接口:主要是对成员变量的更改函数和获取函数。public继承父类。public继承父类。

2023-05-26 15:58:51 143 1

原创 CMU15445 project1总结

全局深度规定取索引最后几位,针对的是vector dir_,局部深度类似,桶大小是定死的不会变。需要一个历史队列(哈希表+链表)和一个缓存队列(哈希表+链表),一个访问次数记录表(哈希表),一个是否能驱逐记录表(哈希表)底层:空闲链表,page数组,page_table(可扩展哈希表,记录哪个page存放在哪个frame里)pin_count,为0表示该frame可以被驱逐或者是空闲的,>0则不能被驱逐,正在使用。2、到达k次后,从历史队列里弹出,加入到缓存队列里,更新所在队列位置(加入队列首部)

2023-05-07 22:50:21 238

原创 CMU15445-project1-可扩展哈希表

index是00,01,global是1,扩容后变成00,01,100,101,global为2,此时在IndexOf函数里得到的是后两位,所以00和100是指向一个桶,01和101是指向一个桶。我的思路是:利用mask=1<<local_depth和hask函数来进行分裂,&结果不为0的在一个桶buck1,为0的在另一个桶buck0。放回时利用dir下标i进行匹配,i&mask不为0则说明该处放入buck1,为0则放入buck0。2、桶如何分裂,分裂后的桶该放在目录的哪里?

2023-05-04 23:15:22 337 1

原创 一些网络问题

一些网络编程问题

2022-11-22 17:16:08 590

原创 Effective 第四章 C++ 设计与声明

effective c++ 第四章 这张例子很多 要自己多去看书理解

2022-09-22 17:24:21 333

原创 Effective 第三章 C++ 资源管理

effective c++阅读笔记

2022-09-21 15:47:05 221

原创 Effective C++ 构造/析构/赋值运算

effective c++第二部分

2022-09-15 15:14:58 294

原创 Effective C++ 第一部分 让自己习惯C++

effective c++第三版第一部分阅读笔记

2022-09-14 20:54:58 192 2

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除