文件系统中,一个目录由一个inode节点(记录文件属性)及众多目录项(entry)组成,目录项用于对该目录下各个子文件进行索引,通常目录项中会记录如下信息。
子目录的文件名称;
文件名称的长度;
子目录inode节点所在位置。
当查找一个文件时,通常是先找到该文件的inode节点,inode节点是根据其父目录内对应的目录项所记录的inode节点位置进行查找的。因此目录项的索引效率的高低对文件查找有着很大的影响。
以前的TpsFs版本中,一个文件夹下目录项的存储通常是顺序存储,当我们去查找一个文件夹下面的子文件时,会将众多目录项从磁盘内逐一读出,并用目录项下的文件名称进行比较。查找目录项算法如图1.1所示。
图1.1 依次遍历目录项
这种算法的缺点是当一个文件夹内的目录项数目很多,并且待查找的目录项又在文件夹末尾时,则需要将这些目录项全部从磁盘内读出,磁盘访问次数急剧增加,从而影响了目录索引的效率。
2.高版本TpsFs的目录索引算法
在3.2.5 SylixOS内核版本以后,TpsFs为了提高目录索引效率,采用了B+树方式对目录内的目录项进行存储。当TpsFs新建一个目录时,不仅仅只是建立该目录的inode节点,同时还会建立B+树根节点并初始化。当需要向该目录内增加子文件时,该算法先通过murmurhash哈希算法算出该子文件对应的Hash值,并将该Hash值做为B+树的键值,该B+树的叶子结点的键值用于存储目录项的位置。
下面举例说明这种算法的存储过程,TpsFs在根目录下分别建立a.txt、b.txt、c.txt文件,其过程如下:
TpsFs通过Murmurhash算法算出a.txt的Hash值为10,该值做为B+树键值;为a.txt目录项分配空间,该空间的位置由B+树键值索引。
TpsFs通过Murmurhash算法算出b.txt的Hash值为20,该值作为B+树键值;为b.txt目录项分配空间,该空间的位置由B+树键值索引。
TpsFs通过Murmurhash算法算出c.txt的Hash值为30,该值作为B+树键值;为c.txt目录项分配空间,该空间的位置由该B+树键值索引。
创建成功后,各个子文件对应的目录项的位置如图1- 2所示。
图1- 2 各个子文件对应目录项位置
根据B+树的特点,当采用上述这种算法时,查找某目录下的一个子文件所需要访问的磁盘次数即为整个B+树的深度,TpsFs中的B+树一个节点可以存储几百个键值,也就是说当一个文件夹内存在几百个文件时,其B+树深度也还是1,这比低版本的依次遍历算法的效率明显高出很多。B+树的深度通常由B+树一个节点所能容纳的最大键值数和总的键值数决定,这里不多做讨论,可自行了解B+树的基本定义,TpsFs中最大节点数定义在libsylixos\SylixOS\fs\tpsFs\tpsfs_btree.h文件内。
2.1Murmurhash算法特点
Murmurhash算法是一种非加密型哈希函数,适用于一般的哈希检索操作,其特点为速度快、实现32位、238位Hash键值,具有较高的平衡性和低碰撞率,也就是说,不同文件名对应的Hash值相同的概率很低。
虽热不同文件名Hash值重复的概率较低,但也是有可能发生的,当出现不同文件名对应相同的Hash值时,TpsFs会将Hash值重复的子文件的目录项保存到低版本时所采用的数据区,即还是采用如图1- 2所示的算法对子文件的目录项进行查找。
3.总结
目录索引算法的好坏对文件系统查找效率有着很大的影响,TpsFs在多处索引算法上都采用B+树,其查找、修改、插入都有着较为稳定的时间复杂度。
原文地址:http://blog.51cto.com/11624185/2054552