我心目中的UBIFS之wandering tree

来源:互联网 发布:虚拟货币挖矿网站源码 编辑:程序博客网 时间:2024/06/05 07:28

虽然我很想将我之前的一个工业检测的小项目(图像算法)接着做完,但是还是决定将UBIFS系统的一些概念的地方完成!

那么废话少说,直奔主题!

Wandering tree,游离树,暂且这样翻译,毋庸置疑的它就是一棵B+树:

B+树一般作为文件系统的数据结构,与平衡二叉查找树-红黑树的主要区别在于子女的个数,具体由Flash的特性决定:

由上图得出B+树的定义:

一棵m阶的B+树:
1.有n棵子树的结点中含有n个关键字。
2.所有的叶子结点中包含了全部关键字的信息,及指向含这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接。
3.所有的非终端结点可以看成是索引部分,结点中仅含其子树(根结点)中的最大(或最小)关键字。
通常在B+树上有两个头指针,一个指向根结点,一个指向关键字最小的叶子结点。
 
定理:如果n>=1,则对任意一棵包含n个关键字,高度为h,最小度数t>=2的B树T,有h<=logt((n+1)/2)
说明:t是指每个结点能包含的关键字数的上界和下界
t>=2,最小包含2个关键字,上图的10与20在第2 level不再为关键字,图中标出了而已
每个非根节点至少t-1个关键字,至少有t个子女,至多2t-1个关键字,最多也就2t个子女,根结点至少包含一个关键字
 
Linux kernel构建B+ tree的算法如下:
/** * struct btree_head - btree head * * @node: the first node in the tree * @mempool: mempool used for node allocations * @height: current of the tree */struct btree_head {unsigned long *node;mempool_t *mempool;int height;};static int btree_insert_level(struct btree_head *head, struct btree_geo *geo,      unsigned long *key, void *val, int level,      gfp_t gfp){unsigned long *node;int i, pos, fill, err;BUG_ON(!val);if (head->height < level) {err = btree_grow(head, geo, gfp);if (err)return err;}retry:node = find_level(head, geo, key, level);pos = getpos(geo, node, key);fill = getfill(geo, node, pos);/* two identical keys are not allowed */BUG_ON(pos < fill && keycmp(geo, node, pos, key) == 0);if (fill == geo->no_pairs) {/* need to split node */unsigned long *new;new = btree_node_alloc(head, gfp);if (!new)return -ENOMEM;err = btree_insert_level(head, geo,bkey(geo, node, fill / 2 - 1),new, level + 1, gfp);if (err) {mempool_free(new, head->mempool);return err;}for (i = 0; i < fill / 2; i++) {setkey(geo, new, i, bkey(geo, node, i));setval(geo, new, i, bval(geo, node, i));setkey(geo, node, i, bkey(geo, node, i + fill / 2));setval(geo, node, i, bval(geo, node, i + fill / 2));clearpair(geo, node, i + fill / 2);}if (fill & 1) {setkey(geo, node, i, bkey(geo, node, fill - 1));setval(geo, node, i, bval(geo, node, fill - 1));clearpair(geo, node, fill - 1);}goto retry;}BUG_ON(fill >= geo->no_pairs);/* shift and insert */for (i = fill; i > pos; i--) {setkey(geo, node, i, bkey(geo, node, i - 1));setval(geo, node, i, bval(geo, node, i - 1));}setkey(geo, node, pos, key);setval(geo, node, pos, val);return 0;}
未完待续,实现将在后面附上:

 

 

原创粉丝点击