CMU 15445 Project 2B 实现并发B+树的数据库索引(删除和验证)

删除这关也不是那么好过。花了一整天才把代码写完加上BUG调完。
值得幸运的是,内存泄漏的问题在实现中没有发生。
首先我们先来看下书上的伪代码

B+ 树删除伪代码

image.png

然后依据这个,再对照作业里的代码框架开始整理。
Remove 是暴露给CLIENT的调用,思想是找到LEAF PAGE删除掉对应的节点,随后按需看做不做合并或者借节点。


image.png

难点就在于 CoalesceOrRedistribute
里面主要有三件事,第一件如果来的是ROOT PAGE,要做ADJUST ROOT。
如果不是,首要要找到这个PAGE的兄弟PAGE。
然后按照兄弟PAGE和当前PAGE的位置关系,来做2个事情。第一个是当可以合并的时候,走Coalesce。 如果不能合并,就意味着可以借节点。走Redistribute

上述2个函数,都会要去传入一个INDEX的参数。
经过研究我理解了,对于Redistribute,是要求传当前节点在PARENT PAGE里的INDEX的位置。
如果是0的话,就要把后面的第一个节点借过来。如果不是的话,就要把前面的最后一个节点接过来。

那么我们在找兄弟节点的时候,就是先找前面的,如果自己是第一个的情况下,才找后面的兄弟节点。

对于Coalesce来说,需要合并,那么统一把后面PAGE的全部孩子移到前面的PAGE。随后把后面PAGE对应在父节点的节点给删了。那个INDEX就是对应后面的NODE在PARENT的INDEX。

下面代码的思想是按照伪代码来写的。


image.png

FIND SIBLING 就是找到前一个兄弟,只有当自己是头节点的时候,才找后一个同时返回TRUE。

image.png

合并的方法,就是把后面的移到前面的。随后把全部移走的那个节点从PAGE TABLE里删了。然后移除PARENT的节点。最后按PARENT是不是小于阈值,递归。

image.png

这里有个很重要的不同
parent->GetSize() <= parent->GetMinSize()
因为走到这个分支的都是INTERNAL PAGE。
LEAF PAGE 是不用小于等于的,而是直接小于。
原因就是INTERNAL PAGE,最小的SIZE就是2.我们设想MAX SIZE 是4的INTERNAL PAGE。 如果SIZE 是2,那么有效的节点其实只有1个(因为第一个是INVALID KEY),所以等于的情况也是需要做合并的。

如果MAX SIZE是5,SIZE 是3,有效节点是2 的情况可以允许。所以有了这里的小于等于

这里再更新下MINSIZE的计算方法。大家自己琢磨下为什么LEAF PAGE是<
INTERNAL PAGE 是<=

image.png

借孩子的方法也是简单粗暴,不多做解释了。


image.png

AdjustRoot 的分为2个情况,一个是ROOT本身是LEAF PAGE,那么因为只有<= min size 才会被调用。所以一定是空PAGE了,直接删成EMPTY TREE就好。
还有一个ROOT PAGE 不是LEAF PAGE,但是小于2了。就意味他的唯一的孩子 需要继承来做ROOT PAGE。
这里我写的时候忘记SET 他孩子的PARENT PAGE ID 为INVALID_PAGE_ID。后来DEBUG时发现。

image.png

综上B+树的删除写完了。我们还需要去PAGE里实现,PAGE的子方法。

叶子节点的比较简单粗暴,就是直接移动,然后更新NEXT PAGE ID即可。和MOVE HALF TO 差不多的套路,复制下来改改就好。

image.png

而INTERNAL的要麻烦一些。
在调用MOVE ALL TO的时候,因为第一个节点是INVALID的节点,我们需要先去把PARENT指向这个PAGE的KEY的值拿到赋予第一个INVALID KEY。然后再搬过去。
我用图来解释一下。下图来自作业


image.png

我们可以看到在标1的地方,就直接MOVE ALL头把32给移过去即可。
因为删31的时候,会响应删掉整个PAGE在PARENT中的INDEX,也就是30.

这是会触发30的那个INTERNAL PAGE <= minsize , 就会再触发合并,也要MOVE ALL TO

invalid key指的是第一个没有KEY,只有一根指针的节点,在INTERNAL PAGE里永远是0的位置。

其实我们需要把26给MOVE 过去,但是那个PAGE只有一个INVALID KEY了怎么办呢?
他要把他即将要删除的父节点(图中为根节点的26)先搞下来,放在他INVALID key的位置,随后把这个KEY MOVE 过去。就有了最终的形态。

同时根节点的SIZE为1(只有一个INVALID KEY)就会触发ADJUST ROOT的CASE 2


image.png

做INTERNAL PAGE的时候,再搬节点,都要记得更新孩子上维持的父亲节点。

下面就是移头或者移尾。可以看到INTERNAL PAGE主要多多出来的就是维护孩子的指针那一块。


image.png
image.png

最后实现好了之后就是写测试。

STEP1 继续先针对PAGE写测试。

image.png

STEP2 过送的2个DELETE测试

STEP 3 自己写一个测试DELETE SCALE的测试。

这里有个技巧,比较直观的去看和分析的是,大概MAX KEY是3的时候,我经过研究,把GENERIC KEY设置为16,PAGE SIZE设置为128,可以有这个效果。


image.png
image.png

INSERT 和 REMOVE前都打印下。


image.png

让分裂的时候,奇数的时候前半部分可以拿到更多KEY。只要用TOTAL+1即可。
我之前的实现是后半部分拿到多数的KEY。
其实都可以,但是前半部分多数KEY,在顺序插入的时候会好看一些。

image.png

image.png

不变量的验证

一般一种数据结构,都有特定的不变量,比如BST,比如红黑树。
B+树也不例外。
我们可以根据B+数的特性,得到每一次插入,删除操作后
B+树应该满足。
每个PAGE的SIZE 满>= MIN SIZE, <= MAX SIZE
每个PAGE里面的元素是有序的。
INTERNAL PAGE指向左边的PAGE的最大值小于INTERNAL PAGE的KEY,右边PAGE的最小值,大于等于KEY。

同时每个LEAF 节点到根节点的深度一致。

最后做完操作后,所有PAGE 应该都保持PIN COUNT 为0的情况。

具体的代码,小伙伴可以去我的GIT上,下下来使用。


image.png

使用方法,在INSERT 和 REMOVE的时候,返回前调用。


image.png

因为验证是O N的时间复杂度,所以在处理10000的规模的数据的时候,每一次操作都调用,就是N^2的复杂度,会非常慢。所以我额外加了一些截止,让他再处理大数据集的时候 去批量验证。以提高测试通过速度。当然最简单的方法是注释掉每次INSERT, REMOVE之后的不变量CHECK。

测试内存无泄漏

image.png

这次更新的代码提交到2B FINISH

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,254评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,875评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,682评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,896评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,015评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,152评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,208评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,962评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,388评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,700评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,867评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,551评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,186评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,901评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,689评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,757评论 2 351

推荐阅读更多精彩内容