您的位置:首页 > 理论基础 > 数据结构算法

B树的一种具体实现

2014-05-08 11:35 246 查看
B树是为了磁盘访问时候,经过最少次的读取磁盘读取相关数据的一个数据结构,B树深度小,比较平衡(2叉树分叉少,深度深,需要多次加载,一般用于内存查找)
访问节点大小如果是4k和8k能和内存页大小和磁盘访问大小契合

此文章写的比较粗,主要讲的是B树磁盘布局和对应的操作,插入删除部分请看算法导论。
需要本身对B树有一定了解才能理解B树对应磁盘的操作

•1.数据结构
•2.加载
•3.插入
•4.删除
•5.写磁盘

•1.数据结构



head固定大小,数据区域由Btree节点组成,B树节点组成如下:



addr是自己在整个文件中偏移
less 是比element1小的node的地址 elemnt中ptr是大于此element小于下个element的node的地址
所以一个node有n个element就会有n+1个孩子

•2.加载

1.加载free root,把freeaddr加入空闲表

把freelist从文件截断

2.加载root,获取root地址

查找算法

1. 存在:

返回节点和元素在节点位置

2. 不存在:

  a.找下一级节点

  比如key<e1查找node->less

  elenmt n<key<elenmt  n+1 查找element
n->ptr

  b.下一级节点为0,查找失败 返回此节点

•3.插入

1.find node:

从磁盘加根节点然后查找,依次加载直到找到需要插入节点

2.a 节点没有满直接插入

2.b如果节点满,把此节点分裂,中间element插入parent

如果parent满,接着分裂,直到根节点

New node优先选择freelist中地址,freelist为空,选择文件尾

修改过的节点flag改为changed,changed节点加入缓存

3.刷磁盘:

文件流移动到node->addr,直接把node所有内容flush

插入节点不满,直接插入,否则分裂,如果父节点满,父节点继续分裂



newnode 分配优先从freelist中获取,如果freelist为空,从文件尾获取

4.删除

1.find node



2.删除元素后不符合btree特点,merge节点

置相应节点flag为changed,删除节点加入空闲表

3.刷磁盘:

文件流移动到node->addr,直接把node所有内容flush

关闭系统时把freelist刷入磁盘(中途关机,再启动时没有freelist,造成空闲空间浪费)

删除算法:

删除非根节点

1.加载leftchildrightchild

2. 选择leftchildrightchild中element多的node
2.1.node是叶子

2.1.1.把删除的element位置填入node中最近元素

2.1.2.删除此叶子node中最后一个元素

2.2.node不是叶子

2.2.1.找到node子孙中最接近key的元素,插入
2.2.2.删除此叶子节点元素

删除叶子节点
1.直接删除
2.向兄弟节点借元素(通过根节点转移)
3.合并

•5.写磁盘

有change的节点包括New的节点,放入缓存,节点个数到一定数值把所有节点刷入磁盘即可 最后清除缓存

系统关闭时候在文件尾刷入freelist(每个free节点地址即可),更新free root值

参考资料:
https://code.google.com/p/btrfs-learning/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息