B+ 树及其在xfs inode中得使用

B+ 树

本文中B+树说明基本使用wiki的词条内容。

什么是B+树

B+ 树是B 树的一个扩展。一种树数据结构,通常用于数据库和操作系统的文件系统中。B+ 树的特点是能够保持数据稳定有序,其插入与修改拥有较稳定的对数时间复杂度。B+ 树元素自底向上插入,这与二叉树恰好相反。

B+ 树在节点访问时间远远超过节点内部访问时间的时候,比可作为替代的实现有着实在的优势。这通常在多数节点在次级存储比如硬盘中的时候出现。通过最大化在每个内部节点内的子节点的数目减少树的高度,平衡操作不经常发生,而且效率增加了。这种价值得以确立通常需要每个节点在次级存储中占据完整的磁盘块或近似的大小。

B+

B+ 背后的想法是内部节点可以有在预定范围内的可变数目的子节点。因此,B+ 树不需要象其他自平衡二叉查找树那样经常的重新平衡。对于特定的实现在子节点数目上的低和高边界是固定的。例如,在 2-3 B 树(常简称为2-3 树)中,每个内部节点只可能有 2 或 3 个子节点。如果节点有无效数目的子节点则被当作处于违规状态。

B+ 树节点结构

在 B+ 树中的节点通常被表示为一组有序的元素和子指针。如果此B+树的序数(order)是m ,则除了根之外的每个节点都包含最少 m/2(向下取整) 个元素最多 m-1 个元素,对于任意的节点有最多 m 个子指针。对于所有内部节点,子指针的数目总是比元素的数目多一个。因为所有叶子都在相同的高度上,节点通常不包含确定它们是叶子还是内部节点的方式。

每个内部节点的元素充当分开它的子树的分离值。例如,如果内部节点有三个子节点(或子树)则它必须有两个分离值或元素 a1 和 a2。在最左子树中所有的值都小于 a1,在中间子树中所有的值都在 a1 和 a2 之间,而在最右子树中所有的值都大于 a2。

算法

查找

查找类似二叉树查找,从root节点开始查找,自上往下遍历树,选择其分离值在要查找值任意一边的子指针。在节点内部使用二分查找确定这个位置。

插入

节点要处于违规状态,它必须包含在可接受范围之外数目的元素。

  1. 首先,查找要插入其中的节点的位置。接着把值插入这个节点中。

  2. 如果没有节点处于违规状态则处理结束。

  3. 如果某个节点有过多元素,则把它分裂为两个节点,每个都有最小数目的元素。在树上递归向上继续这个处理直到到达根节点,如果根节点被分裂,则创建一个新根节点。为了使它工作,元素的最小和最大数目典型的必须选择为使最小数不小于最大数的一半。

删除

  1. 首先,查找要删除的值。接着从包含它的节点中删除这个值。

  2. 如果没有节点处于违规状态则处理结束。

  3. 如果节点处于违规状态则有两种可能情况:

 1. 它的兄弟节点,就是同一个父节点的子节点,可以把一个或多个它的子节点转移到当前节点,而把它返回为合法状态。如果是这样,在更改父节点和两个兄弟节点的分离值之后处理结束。
 2. 它的兄弟节点由于处在低边界上而没有额外的子节点。在这种情况下把两个兄弟节点合并到一个单一的节点中,而且我们递归到父节点上,因为它被删除了一个子节点。持续这个处理直到当前节点是合法状态或者到达根节点,在其上根节点的子节点被合并而且合并后的节点成为新的根节点。

B+ 树在xfs中的应用

当前大部分Linux filesystem的inode都用B+ 树来组织他们的inode节点。使得查找更快更便捷。

xfs相关的是参照 麦子迈的博客。

Linux filesystem的结构特点

在Linux系统内部,一个文件系统是由逻辑块的序列组成的,每块为512个字节。具体组成下面表中所示。

引导块 超级块 索引节点(inode)区 数据区
用于读入启动操作系统 记录文件系统的当前状态,如硬盘空间的大小和文件系统的基本信息 存放文件系统的索引节点表,Linux系统中每个文件和目录都占据一个索引节点。文件系统一般从根节点开始 存放文件系统的索引节点表,Linux系统中每个文件和目录都占据一个索引节点。文件系统一般从根节点开始

当然,现在主流的filesystem超级块可能不止一个,索引节点区和数据区又会划分成多个block group。

xfs中Allocation Group

XFS 引入了 Allocation Group(AG) 来划分一系列相等的块,每个 AG 所含的信息非常接近于一个完整的 XFS。每个 AG 都有三个主要功能:

  1. 一个 Superblock 来描述整个文件系统信息

  2. 空闲空间管理

  3. Inode 分配和管理

多个 AG 的引入使得整个文件系统更加并行化,因为 AG 之间没有太多的共享资源和依赖。唯一的全局信息是第一个 AG 维护了一个全局的空闲空间情况和全局 inode 数(只在 umount 的时候会更新)。

B+树在AG中得使用

AG

XFS 通过两个B+树来管理空闲空间,如上图所示,分别是 Key 为 Block number 和 Block count 的两个。这使得 XFS 能通过 Block number 或者 Block size 来快速定位。如上图所示”AG free block info”主要是包括两个B+树的 root 节点的 block number(一个 block 存储一个 root 节点),level,第一个和最后一个空闲列表块,空闲列表块的数量等等。

从”AG free block info”得到两个B+树的 root 节点信息后,每个节点分为两部分,一部分是节点信息,另一部分是 Key(Block count 或者 Block size)。

而图中的”AG Free List”是每个 AG 保留下来供B+树增长使用的,通常来说会是4个 block。

AG inode管理

Inode 管理是每个 Linux 文件系统的重点,如何使用和分配 Inode 影响着文件系统的性能和利用率。”AG inode B+tree info”包含着 AG 的 inode 信息,如 inode 已分配数,root 节点,空闲 inode 数,最近分配的 inode 和一个已删除 inode (inode 被删除但是其管理的数据块仍在,需要推迟删除,这个表在 mount 和 umount 的时候通常会清空)的哈希表。

与空闲空间管理的B+树类似,inode B+树的每个节点都包含着节点信息和Key(块位置)。

Data fork

XFS 使用 extent 来管理空间,一个 extent 包含了文件的逻辑 offset 和 block 的开始位置与长度,状态。一个文件可能会有多个 extent 组成,当 extent 所代表的 block 连续时,多个 extent 会相互合并。

data fork 里的 extent 数据在绝大多数都可以放在 inode block 里,每个 extent 代表一个记录组成一个数组放在 data fork。但是当 data fork 无法容纳更多的 extent 时,extent 会被使用B+树管理。B+树的 root 节点会被放在 data fork 里。


你可能感兴趣的:(tree,B+,iNode,XFS)