最先是解释了一个古老的,现在没什么人用数据结构----T-tree,因为现代的cpu到cache和到memory差异巨大,同时memory的容量也变大了。
T-tree
两个key标志着范围,决定到哪里找key,然后存的都是指针,指向parent,和两个children的。
然后有个Data table,为了节省内存,我想这个地方可能存的是整个attributte。
好处:1.节约内存
2.预先判断范围
缺点:1.很难平衡和并发操作,要上latch,很难latch-free
2.cache miss很多
BW-tree
主要思想:1.不就地更改,降低cache失效
2,都是物理地址用一个间接层--------mapping table(page_id和physics)这样就可以无锁用CAS来改变了(不然很多指向同一个page的话,就很难,也可能通过无锁来实现)
结构
看起来挺像B+ tree的,就是多个间接层。
。
接下来看看如何delete/insert
addreess最先是page102的,所以这个delta(insert k0)对于别的线程是不可见的,然后用CAS把102的物理地址指向delta,这样我们遍历时第一个到delta,就会发现已经insertk0,那么我们就可以返回了。
这张图很好的说明了并发安全的保证
如果两个同时到的话,CAS(对mapping table)返回false的,那个就可以abort或者retry了。
为了避免delta太长,对性能损害变大,我们在delta到达一个阈值(paper里面是8)把这个apply到page 102,也开一个新的page来做,因为不是就地跟新的。 同时delta是从下往上apply,可以往下遍历时,保存一下副本
然后就发现之前的那一堆东西想mvcc一样对别的不可见可以gc了
gc安全性保证
一个是thread引用计数,但是对多核来说cache一致性的交流开销就大了。
epoch周期确定
插入太多的话,节点要分裂
分裂策略
一种是在分裂节点头上分裂出指向分裂出来的节点,一种是在分裂节点的父亲节点上做动作来指向分裂出来的node。
优化
1.预先分配delta,,同时减少了碎片和提高了局部性,减少了cache miss的次数
2.通过虚拟内存预先分配mapping table
但好像Bw-tree也没多吊。。。