AFS文件目录数据库系统初步方案规划

文章目录

  • AFS文件目录数据库系统初步方案规划
  • 前言
  • 一、AFS是什么?
  • 二、游戏关卡
  • 三、文件名字与标识
  • 四、与linux文件系统对比
  • 五、linux文件系统简介(网上择抄)
  • 总结

前言

linux的“文件系统+网络”代码量约有100万行。如要实现等同功效、甚至更高标准,但目标代码量要求小于1000行时;如何简化和实现,将是一个“好玩的挑战”。Linux内核源码行数总量共有27852148行分布在66492个文件中,我不可能去看linux源代码,没那个时间和精力;一年后,我要逐步回归“学习唱歌事业”。这一年的时间,3个产品(“飞鸡1-3”)的软硬件都要同步的边学边干进行。AOS简易微内核操作系统将包括:AFS文件目录数据库系统,ANET网络系统,内核(进程(线程)调度、内存管理、通信管理等等),基本的设备驱动。AOS的目标代码量为小于3千行,预计半年后进入调试阶段;更多的设备驱动、其它文件系统支持、用户应用层软件等等的代码编写,将是源于网络或其它公司或个人的支持,我只是给出框架支撑、C标准io库实现。通常是半个月我才能攻破一个算法流程等等的“游戏难关”,我会尽可能地从原理层上想法实现和简化代码量。如果超越3千行代码,我会感到有心无力、会累惨,预计开发时间会超过一年。如果24小时“在战斗”,预计3K代码量、半年可以完成(单纯编写是不会花多少时间,而时间主要花在实现方法的思考上)。AOS主要目标是简化代码量、高可靠、高速、微内核。


一、AFS是什么?

AOS实现VFS(Virtual Filesystem)的方式是不同于linux。如果某个ext3文件系统挂靠再AFS的某个目录AAA下,那么目录AAA就是该ext3文件系统的根目录文件,包含了其设备驱动相关和ext3文件系统所有操作方法以及所谓超级块等等,AFS会对ext3文件系统做元数据(Metadata)的相关外包装。是故,AFS的卷根目录文件自然是/(0号i节点,隐藏、包含AOS等);AFS是如何在/卷根目录文件实现的(预计不到500行代码),其它文件系统也可以参考实现之,不外是2组共32个方法(函数)的编写。所以,AOS内核没有大量Linux超级块对象(super_block)和VFS的复杂实现。打开一个文件,必定是其对应文件系统根目录文件也被打开,因为哪里才会有对其统属文件操控的方法。还有一种实现VFS的方式是用户进程或内核线程模式,AFS与之通信来实现。AFS最多支持到32种不同文件系统(外挂、安装模块来实现,不包含在AOS内),每个根目录最多有1K个目录项,但普通目录文件可以不限目录项(取决于i节点资源)。一个进程的打开文件号默认是32个,用户也可预定义到64K个;但socket连接号是另一种实现,最大可支持到16M个连接号(ANET实现代码小于500行,用户进程的网络操作更为简单,各种连接、自动读写文件等等实现ANET全包含了,用户发消息就OK、不用再去学网络编程之类的东东,呵呵、累成狗喘气的是我)。简洁和速度及高性能将贯穿整个AOS。一个设备驱动也是挂靠在AFS的目录下,并成为一个设备根目录文件。希望将来的电脑硬件:内存大于256Gb,固态盘大于256Tb,一块磁盘有16Zb。电脑达到人脑水平,需经历地变36层;即使现今世界上所有电脑加起来、都到不了半数的18层,离我想象还差好远。网络视为一个个孤岛矿山(网站)组成的海洋,各种网站还都是“粗矿石头”;需要电脑自动“采矿”精炼、建立“字典、联想数据库”,之后学习、推理、思考、预测等等,争取5年内、电脑可以达到幼儿园水平。

二、游戏关卡

考虑到以后智能电脑的需要,AFS文件目录系统管理的磁盘空间:一个全局磁盘阵列数据区(16块全局磁盘)1 GDRPT = 64Krl,一个卷rl (roll)= 64K bdb,一个大数据块bdb(big data block)= 64Kdb,一个数据块db( data block ) = 64 Kp,1p(页page) = 16 s(扇区sector) = 256 r(行row)= 2K w(字word)= 4Kz(半字z)= 8K b(字节byte)= 64K bit(位bit)。是故,1db = 512Mb,1bdb = 32Tb,1rl = 2Eb,1 GDRPT = 128 Zb。支持的最大文件2Eb,每卷最大文件数为4G个,支持最大分区2Eb(一个分区一个卷,一个全局磁盘数据区 GDPT可有4K个分区,分为32段、每段128个分区)。面临的游戏关卡主要有3个:
1)、inode号映射与分配、SQL数据库查询搜索等等。
2)、文件权限管理。
3)、空间分配算法。
耗费半个月,我总算想出了“独狼空间连续粒度分配算法”,取代 linux采用的“Buddy(伙伴)算法”;适用于磁盘空间的以卷、或以大数据块、或以数据块、或以页为单位粒度的连续空间分配,也适用于连续内存空间或FLASH连续空间分配(也可以是行为单位粒度(32字节一行)等等);极为有效减少碎片化,算法代码简洁、易于实现。而总体的空间分配算法为“四方兽空间分配算法,青龙粒、白虎骨,朱雀来、玄武出。”,包含单粒位图分配算法和“独狼”分配算法等等。
支持数据库表模式(或以数据库显示层、或以浏览器,作为用户互操作数据库表。)预配置内存空间、磁盘空间,参数初始化(如设备驱动树初始化配 置等等,未来代码也放入数据表、呵呵)。
根用户的权限也不能是无限大、必须考虑到保护用户的隐私!文件的权限设置、必须是文件的拥有者才行!只能是文件拥有者可以查看、修改文件,除非文件拥有者在i_mode中、允许root用户对文件拥有读、写权限!但根用户可以删除一切非根用户的文件。

1 Kb ( Kilobyte 千字节 ) =1024b,1024 = 2^10 ( 2的10次方);
1 Mb ( Megabyte 兆字节、简称“兆”) = 1024 Kb,
1Gb ( Gigabyte 吉字节、又称“千兆”) = 1024 Mb,
1 Tb ( Trillionbyte 万亿字节、太字节 ) = 1024 Gb,
1 Pb(Petabyte 千万亿字节、拍字节)= 1024 Tb,
1Eb(Exabyte 百亿亿字节、艾字节)= 1024 Pb;
1 Zb ( Zettabyte 十万亿亿字节、 泽字节 ) = 1024 Eb,
1 Yb (Yottabyte 一亿亿亿字节、 尧字节 ) = 1024 Zb,
1 Bb ( Brontobyte 一千亿亿亿字节 ) = 1024 Yb。

各种文件目录系统看得我心好累,太烦人了、只好一点点去沟通简化。

三、文件名字与标识

程序(在磁盘中为程序、在内存中打开为进程)、目录也是文件。文件是复杂数据容器集合的一种组织形式,通常由描述文件属性集的文件头结构和文件体元素数组组成,文件也可以只有文件头。文件头 是由一些属性字段元素组成的结构,通常有:文件名字,标识符,类型,文件权限,标志,大小,位置,方向(节点),时间戳等等。字段的元素可以是 C基本类型或者结构体、数组等等,由1个或多个字段所组成的集合称为记录,故文件头也可看作文件的属性记录。如果文件体元素数组的元素只是简单 的C基本类型变量,则被看成是一个字符流文件、或者一个二进制文件,又称为流式文件。反之,如果是记录类型数组,则称为记录式文件或者称为表文件。记录式文件或说表文件的文件体可称为“表”,表中每行为一个记录,记录也可以拆分为字段、视为列;这样,每个表由行和列组成。其实,流式文件也可以看作为只有一个简单字段列的“孤立字段表文件”。而记录表文件可以视为多个“关联字段表文件”的合成体。 是故,文件体可以视为表,而文件与表文件等价、看使用者的视角而已。数据库DB(data base)是存储数据表(data list/sheet)的集成仓库,可简单看作一个数据库目录,包含一堆数据表文件和相关文件。这样,文件目录系统可以看作数据库、反之也成立;设备驱动库、甚至系统内核(内存管理,进程和线程管理等等)也可以看作数据库;如此一来,总的编程代码量将大幅度减少。

1)、文件名字编码
AFS中文件名字的字符串编码采用的是2字节Unicode编码的变形,称为UTFA16。如果用UTF-8编码(Unicode Transformation Format ):
7位ASCII–>0bbbbbbb,8-11位–>110bbbbb 10bbbbbb,
12-16位–>1110bbbb 10bbbbbb 10bbbbbb,中文需要3字节。
UTFA16:
如果2个字节的最高位都是0、则分解为2个ASCII码,如果2个字节的最高位有一个为1可以有15.5位(xy:01、10、11):-xbbbbbbb ybbbbbbb,可表示48k个中文等符号,将其映像到48k个Unicode字符编码:xy=01时,14位b + 0X0080,映射到0X0080—0X407F;x=1时,15位b + 0X4080,映射到0X4080—0XABFF,还余0X1400个,分别映射到D800–DFFF(0X0800个),F400–FFFF(0X0C00个)。
这种算法很简单和高速,好处是英文等ASCII码符号只占一个字节。

2)、文件属性记录FAR(File Attribute record。文件头,包含文件的部分元数据(不含文件名属性记录),128b)
文件系统inode译成中文就是文件索引节点(information node 或index node)、也称i节点,在内存中打开的inode称为v_inode(v节点),其它文件系统的如ext2_inode等等。索引节点对象inode包含文件的相关信息(诸如文件的大小、磁盘位置、文件权限、时间戳、文件类型和标志、相关标识符、等等),其实质就是文件属性记录FAR(也就是对文件属性的描述,也称为文件索引节点对象inode object)。

AFS:文件 = 元数据(文件属性数据) + 数据(文件具体内容),
元数据 = 文件属性记录FAR(索引节点对象inode)+ 文件名字属性记录NAR(Name Attribute record),
NAR = GUID(16b文件标识) + __u8 afs_name_len(1b文件名字长度) + __u8 afs_file_type(1b文件类型) + pinode(1w所属目录的i节点)。

将磁盘中的inode调进填充入内存中的v_inode,这样才是算打开了磁盘文件的inode。linux的内存中的inode(VFS)和具体文件系统的inode(如ext2_inode)有着很大的区别,而AFS的差别不大。每个inode节点的大小,AFS是128字节,inode节点的总数是4G个,一般AFS是每2Mb就设置一个inode。AFS有2个线性表和一个哈希表:文件属性记录FAR表(i节点对象表)、文件小数据区表(每项4Kb、半页),文件名字属性记录NAR哈希表。相关线性表是根据inode排序,或说是以inode为下标的记录数组。

四、与linux文件系统对比

通常最大打开文件数会是系统内存的10%,如果系统同时打开16M个文件,那需要16M个v节点、2Gb内存;linux的目录项对象(dentry)也是要占内存约2Gb(dentry包含有文件名字、就算平均占128b吧),是故、单是元数据就要占内存约4Gb;如果同时打开的是512M个文件时,岂非元数据就要占内存约128Gb?其实,内存占多大并非重点,对我而言、重点是代码清晰和简洁!内核操纵的是v节点,不应将包含文件名字的dentry(注意:文件名字长度是不等长的,最大可到256个符号)弄进内存中。如果说引入存放在内存中linux的目录项对象(dentry)概念主要是出于方便查找文件的目的,那么、耗费我不少想象力后,我看到的只是:复杂无比,代码量巨增,不够清晰;除了增加复杂度和增加内存使用量,我没发现有特别之处。查找方便?如果一个目录下面的文件很多时,还不是要用哈希查找?还不是要磁盘I/O?如果就为在如open一个文件时增加那么一点点速度,而增加复杂度、增加dentry cache保存最近访问过的目录项(如果要找的目录项在cache中没有,就要从磁盘读到内存中),增加目录文件数据块的目录项哈希索引排放、等等;那么,还不如放弃目录项对象dentry概念。

所以,AFS取消了内存中的Linux目录项对象(dentry)概念,且AFS的目录文件之目录项dir_entry只是1个字的文件索引节点描述符inode;也不需要生成额外的两个目录项:".“和”…",因为inode节点对象已经包含相关描述,也不需要增加代码量去做目录文件数据块的目录项dir_entry的索引排布。如果为了相对数量极少的一些硬件符号链接文件、节省下一些inode号,而使得inode号没能与路径文件名、一一对应;我认为,终是得不偿失。linux硬链接只能对文件、不能对目录,而又不得不划分为软硬链接、增加了实现复杂和代码量。是故,AFS没有软、硬链接之分,只有简单的可以跨文件系统的目录或文件链接,链接文件inode对象含有到源inode号的指针(指向自己、则为源文件或目录)和链接计数项。链接文件不能再对其链接,这没必要。文件inode号一一对应于路径+文件名,任一条路径是唯一的、任一条路径 + 文件名也是唯一的。同一个路径下不能有相同名字的文件,这是规则。AFS最大4G个inode号,非根目录下文件数不限制,只受限于inode号资源;允许同名目录,不同路径下也允许同名文件以及文件和目录同名,例如:路径1/abc.txt、路径2/abc.txt、路径i/abc.txt,
/…abc/abc/abc/abc/abc。类似按通配符与部分文件名查询、或部分元数据属性查询时等等情形,使用B+树索引表和哈希表;但这是属于shell命令程序,不包含在AOS中。AOS支持数据库基本操作(数据库方法集)功能,AFS文件目录系统是数据库例子,支持SQL查询操作。AOS支持用户C标准库。

内存中打开的表有:PCB(process control block)进程表(进程描述符PID,Linux操作系统下的PCB是:task_struct,会被大改动),fd文件描述符表(file descriptor table),打开文件表(open file table),v_inode节点表(d_inode(目录i节点)、rd_inode(根目录i节点)、socket_inode(网络i节点)、f_inode(普通文件i节点)、p_inode(程序文件i节点)、等等在内存中打开之inode节点称为v节点)。内核中,对应于每个进程都有一个文件描述符表fdt,表示这个进程打开的所有文件。文件描述表fdt中每一项都是一个指针,指向一个用于描述打开的文件的数据块–file对象(打开文件表oft中的项),file对象中描述了文件的打开模式,读写位置等重要信息,当进程打开一个文件时,内核就会创建一个新的 file对象。file对象有引用计数,记录了引用这个对象的文件描述符个数,只有当引用计数为0时,内核才销毁file对象,因此某个进程关闭文件,不影响与之共享同 一个file对象的进程。file对象中包含一个指针,指向相应v_inode节点对象。v_inode节点对象包含了如文件系统类型、文件的权限、访问日期等文件属性,还包含到其父节点(所属路径)的指针(包括i节点和v节点指针)、从而回溯出整个路径,找出根目录v节点、自然就会得到最终对文件进行操作所需的所有信息、文件的操作方法、等等。打开文件后,进程得到的文件描述符实质上就是文件描述符表的下标,内核根据这个下标值去访问相应的文件对象,从而实现对文件的操作。注意,同一个进程多次打开同一个文件时,内核会创建多个file对象。PIDT–>fdt–>oft–>vnt。内核各种表的相互关系如何去表述?我就简单地放1个或2个指针。当我学习到“链表”知识时,对C语言表述的“双向链表”感冒;你可以用“圆环形带一圈夹子的衣架”来解释如何便于插入和删除等使用、或说linux系统大量使用简单的双向链表结构类(统一的、简洁的一堆C操作方法)来表示、等等,我就是“莫名的不喜欢”、那就是“感觉”,我感觉反而它是linux系统代码量庞大的原因之一(呵呵,与大众认知的双向链表结构类简化代码量相反)。也或许是我这小白错了,反正2张表关联就会有相互之指针,实现动态增长数据单元、就要一个数据单元有一个指针指向下一个数据单元,管它单向或双向的数据链表是否规范、只要清晰和代码量简单就ok。

五、linux文件系统简介(网上择抄)

1)、linux文件系统inode号、目录和链接

在Linux内部,访问文件都是通过inode号来进行的,所谓文件名仅仅是给用户容易使用的别称或者绰号。当我们打开一个文件的时候,首先,系统找到这个文件名对应的inode号;然后,通过inode号,得到inode信息,最后由inode找到文件数据所在的block,再进行文件数据块的相应处理。Linux系统允许,多个文件名指向同一个inode号码;这意味着,可以用不同的文件名访问相同inode号对应的实际文件内容。inode对象中有一项叫做"硬链接计数",记录指向该inode的文件名总数;删除一个文件名,就会使得inode节点中的"硬链接数"减1。当这个值减到0,表明没有文件名指向这个inode,系统就会回收这个inode号码,以及其所对应block区域。创建目录时,默认会生成两个目录项:".“和”…"。前者的inode号码就是当前目录的inode号码,等同于当前目录的"硬链接(hard link)";后者的inode号码就是当前目录的父目录的inode号码,等同于父目录的"硬链接"。除了硬链接以外,还有一种特殊情况。文件A和文件B的inode号码虽然不一样,但是文件A的内容是文件B的路径。读取文件A时,系统会自动将访问者导向文件B。因此,无论打开哪一个文件,最终读取的都是文件B。这时,文件A就称为文件B的"软链接"(soft link)或者"符号链接(symbolic link)”。这意味着,文件A依赖于文件B而存在,如果删除了文件B,打开文件A就会报错:“No such file or directory”。这是软链接与硬链接最大的不同:文件A指向文件B的文件名(含路径名),而不是文件B的inode号码,文件B的inode"链接数"不会因此发生变化。Linux系统中,目录(directory)也是一种文件。打开目录,实际上就是打开目录文件。目录文件的结构很简单,就是一系列目录项(Directory entry、简为dir_entry)的列表。每个目录项dir_entry(与内存中目录项对象dentry不一样),由两部分组成:所包含文件的文件名,以及该文件名对应的inode号码。硬链接:其实就是同一个文件具有多个别名,具有相同inode从而有相同的data block,但目录项dir_entry不同;只能对已存在的文件进行创建硬链接,不能对目录进行创建;可以不同交叉文件系统进行硬链接的创建,删除一个硬链接并不影响其他具有相同inode号的文件。软链接:软链接文件具有自己的inode(文件属性及权限等)和文件内容数据块(文件存放的内容是另一个文件的路径名),软链接可以对不存在的文件或目录创建;软链接可以交叉文件系统,可以对文件或目录创建;创建软链接时,硬链接计数i_nlink不会增加;删除软链接不会影响被指向的文件,但若指向的原文件被删除,则成死链接,但重新创建指向的路径即可恢复为正常的软链接,只是源文件的内容可能变了。
例子:普通文件的数据块里面保存的是文件数据,而目录文件的数据块里面保存的是目录里面一项一项的文件信息,这些信息称为ext4_dir_entry。

struct ext4_dir_entry {
__le32 inode; /* Inode number /
__le16 rec_len; /
Directory entry length /
__le16 name_len; /
Name length /
char name[EXT4_NAME_LEN]; /
File name /
};
struct ext4_dir_entry_2 { // 后来的改版
__le32 inode; /
Inode number /
__le16 rec_len; /
Directory entry length /
__u8 name_len; /
Name length /
__u8 file_type;
char name[EXT4_NAME_LEN]; /
File name */
};

简单的目录文件表述格式可以是:以ext4_dir_entry_2为项的线性表,第一项是“.”表示当前目录,第二项是“…”表示上一级目录,接下来就是一项一项的文件名和inode。通过查询比对相应的inode就能找到真正的文件。如果一个目录下面的文件太多时(比如10亿个),想在这个目录下找一个文件,按照列表一个个去找太慢了,于是就添加了索引的模式。如果在inode中设置EXT4_INDEX_FL标志,则目录文件的块的组织形式将发生变化,变成了下面定义的这个样子:

struct dx_root
{
struct fake_dirent dot;
char dot_name[4];
struct fake_dirent dotdot;
char dotdot_name[4];
struct dx_root_info
{
__le32 reserved_zero;
u8 hash_version;
u8 info_length; /* 8 */
u8 indirect_levels;
u8 unused_flags;
}
info;
struct dx_entry entries[0];
};

当然,首先出现的还是差不多的,第一项是“.”表示当前目录;第二项是“…”表示上一级目录,接下来就开始发生改变了,是一个dx_root_info的结构,其中最重要的成员变量是indirect_levels,表示间接索引的层数。接下来看索引项dx_entry,这个其实就是文件名的哈希值和数据块的一个映射关系,如下所示:

struct dx_entry
{
__le32 hash;
__le32 block;
};

如果要查找一个目录下面的文件名,可以通过名称取哈希。如果哈希能够匹配上,就说明这个文件的信息在相应的块里面。然后打开这个块,如果里面不再是索引,而是索引树的叶子节点的话,那里面还是ext4_dir_entry_2的列表,只是少量的一项一项找文件名就行。通过索引树可以将一个目录下面的N多文件分散到很多的块里面,可以很快地进行查找。

2)、Linux目录项对象(dentry)

它代表一个目录项(包括该目录对象对应的索引节点,子目录链表,父目录目录项对象,与它同级的目录的目录项对象链表,使用计数,缓存标志),是路径的一个组成部分(注:路径中的每个组成部分都由一个索引节点对象表示)。该对象只存放在内存中。引入目录项的概念主要是出于方便查找文件的目的。一个路径的各个组成部分,不管是目录还是普通的文件,都是一个目录项对象。如,在路径/home/source/test.c中,目录 /, home, source和文件 test.c都对应一个目录项对象。不同于前面的三个对象,目录项对象没有对应的磁盘数据结构,VFS在遍历路径名的过程中现场将它们逐个地解析成目录项对象,并使用缓存机制,以提高查找的速度(目录项对象与索引节点对象一一对应,即它也代表着一个文件,这里的文件可以是普通文件也可以是目录文件等)。目录项对象有三种状态:被使用、未被使用和负状态。
被使用:一个被使用的目录项对应一个有效的索引节点(d_inode指向相应的索引节点)并且表明该对象存在一个或多个使用者(d_count为正)。一个目录项处于被使用状态,意味着它正被VFS使用并且指向有效的索引节点,因此不能被释放。
未被使用:一个未被使用的目录项对应于一个有效的索引节点(d_inode指向相应的索引节点),但是应指明VFS当前并未使用它(d_count为0)。该目录项对象仍指向一个有效对象,而且被保留在缓存中以便需要时再使用它。由于该目录项不会过早地被销毁,所以在以后再需要用到它时,不必重新创建,从而使得路径查找更迅速。但如果要回收内存的话,可以销毁未使用的目录项。
负状态:没有对应的有效索引节点。因为索引节点已被删除了或路径不正确,但是目录项仍然保留,以便快速解析以后的路径查询。

以上三种类型的目录项都会被缓存到目录项缓存中,并且散列表也会被缓存。另外如果目录项被缓存了,并且是被使用状态,那么相应的索引节点也会被缓存。目录项是描述文件的逻辑属性,只存在于内存中,并没有实际对应的磁盘上的描述,更确切的说是存在于内存的目录项缓存,为了提高查找性能而设计。不管是文件夹还是最终的文件,都是属于目录项,所有的目录项在一起构成一颗庞大的目录树。例如:open一个文件/home/xxx/yyy.txt,那么/、 home、xxx、yyy.txt都是一个目录项,VFS在查找的时候,根据一层一层的目录项找到对应的每个目录项的inode,那么沿着目录项进行操作就可以找到最终的文件。注意:目录也是一种文件(所以也存在对应的inode)。打开目录,实际上就是打开目录文件。

struct dentry {
atomic_t d_count; // 目录项对象使用计数器
unsigned int d_flags; // 目录项标志
struct inode * d_inode; // 与文件名关联的索引节点
struct dentry * d_parent; // 父目录的目录项对象
struct list_head d_hash; // 散列表(哈希表)表项的指针
struct list_head d_lru; // 最近未使用的目录项的链表
struct list_head d_child; // 目录项通过这个加入到父目录的d_subdirs中
struct list_head d_subdirs;// 对目录而言,表示子目录目录项对象的链表
struct list_head d_alias; // 相关索引节点(别名)的链表
int d_mounted; // 表示被安装文件系统根项。一个目录下可有不同的文件系统!
struct qstr d_name; // 目录项名称
unsigned long d_time; /* used by d_revalidate 重新变为有效的时间!注意只要操作成功这个dentry就是有效的,否则无效。*/
struct dentry_operations *d_op; // 目录项方法
struct super_block * d_sb; // 文件超级块对象,这目录项所属的文件系统的超级块
vunsigned long d_vfs_flags;// 一些标志
void * d_fsdata;// 与文件系统相关的私有数据
unsigned char d_iname [DNAME_INLINE_LEN]; // 存放短文件名
};

一个有效的dentry结构必定有一个inode结构,这是因为一个目录项要么代表着一个文件,要么代表着一个目录,而目录实际上也是文件。所以,只要dentry结构是有效的,则其指针d_inode必定指向一个inode结构。inode却可以对应多个dentry,整个结构其实就是一棵树。


总结

linux的知识网上一大堆,呵呵、我也不太熟悉。我只能按自己所想当然去用汇编做AOS,感觉也不是一件非常复杂的事情,难度系数也就3.5星。

数组的特点是:寻址容易,插入和删除困难;而链表的特点是:寻址困难,插入和删除容易。哈希则是一种寻址容易,插入删除也容易的数据结构。从速度性能看,数组和哈希是最好的,加入位图将解决数组“插入和删除困难”的缺点、性能会比链表更好;是故,AOS以位图+数组、哈希为主,当然、单向链表和表的指针互指情形也是有的。操作对象的最基本方法之中的2种是:增加或删除一个对象。从另一个角度看,增加、删除可以看作是对资源对象的分配、释放。我们可以用一个位图变量中的一个二进制位来表示一个资源对象,增加或删除一个对象不外就是位图相应位置1或清0。资源对象可能是一个内存行、或一个内存数据块、或数据表中一条记录、或一个文件、或一个进程、或一个进程中的一个线程、或一页、或一个大数据块、或一个i节点、或进程中的一个打开的文件号、或线性表中的一个字段、或进程中的一个对象号、或一个消息号、或一个过程号、或一个方法集合等等。AOS中的一页 = 8Kb(字节) = 16s(扇区)= 64Kbit(位),AOS使用一页的位图(64Kbit、位序号用16位变量表示)来表示有64K个方法组;位图的一位对应一组方法跳转字(有16个方法跳转字w,方法组字段),总的方法组跳转表需要64K*16w = 1Mw = 4Mb的空间,方法组跳转表的字初始化为跳转到方法(函数)printf“没有安装”。位图最初的256位是AOS使用,其实、AOS也就用20多组方法,最多300多种方法代码吧(256个中断入口表不外是16个连续方法组,平均一个方法也就约10条指令)。64K - 256个方法组(可视为数据库表或说动态方法库),可以满足千奇百怪的各种设备驱动所需了(一个设备用1组方法),还有各种文件系统(连续2组方法)、应用软件的动态方法库以及玩家的各种独特设备驱动。我想象:所谓“模块”的注册、安装、卸除等等,不外是方法组位图相应位的置1或清0、以及相应方法组字段安装或初始化,另有一些、比如模块说明书、导出符号表之类的少量工作。每个方法的代码段是一个字数组、长度不一,需要使用到的方法组才会安装到AOS中、相应具体方法代码段的内存首地址也才会安装到方法组跳转表相应位置。用汇编写也就位图搜索第一位为1的指令或根据位图序号操作相应位、以及表跳转指令,C语言就那个case语句吧。想象力表明,操作系统只能是用汇编、C语言来编写;不可能蠢得用C++来写,难道每个不同对象类都来一组增加或删除方法?呵呵、那样代码量会无比臃肿。

AFS的文件名字哈希表hash table:文件名字–>硬件哈希4字MD5–>二次哈希到24位线性表相对指针(二维单向链表首指针)–>二维单向链表(横向为不同文件名字哈希冲突单向链表相对指针(首字相对指针next、为0结束),纵向为相同文件名字不同路径单向链表相对指针(尾字相对指针next、为0结束))。对路径文件、/home/source/test.c,先哈希test.c和路径/home/source,就可以得知/home/source/test.c的inode号;之后,再判断其是否在内存打开、等等。

AFS文件目录数据库系统初步方案规划相关推荐

  1. 空间管理员(一)AFS文件目录系统索引节点vfs_inode结构

    空间管理员(一)AFS文件目录系统索引节点vfs_inode结构 文章目录 空间管理员(一)AFS文件目录系统索引节点vfs_inode结构 前言 一.VFS(Virtual File System) ...

  2. 基于Vue+Vue-cli+webpack搭建渐进式高可维护性前端实战项目

    本文是专栏<Vue + SpringBoot前后端分离项目实战>的实战第一篇,将从Vue脚手架安装开始,逐步带你搭建起一套管理系统所需的架构.当然,在默认安装完成之后,会对文件目录进行初步 ...

  3. 初步认识数据库:数据、数据库、数据库管理系统、数据库系统分别是什么?

    一.数据 定义:描述事物的符号.数据是数据库中存储的基本对象 往往提到数据大多数人头脑中的第一反应就是数字,其实数字只是最简单的一种数据,是数据的一种传统狭义的理解.广义的理解认为数据的种类很多,例如 ...

  4. 1.Hadoop初步环境搭建(ssh无密码通信)

    一.初步环境搭建 1在Windows 7上安装VMware虚拟机(VMware-workstation-full-9.0.2),VMware Workstation下载地址: https://my.v ...

  5. ASP.NET MVC学前篇之Ninject的初步了解

    ASP.NET MVC学前篇之Ninject的初步了解 1.介绍 废话几句,Ninject是一种轻量级的.基础.NET的一个开源IoC框架,在对于MVC框架的学习中会用到IoC框架的,因为这种IoC开 ...

  6. 计算机视觉库OpenCV初步了解

    OpenCV全称是OpenSource Computer Vision Library,是一个开放源代码的计算机视觉库.OpenCV最初由英特尔公司发起并开发,以BSD许可证授权发行,可以在商业和研究 ...

  7. 哈尔滨工业大学-数据库系统(基本知识与关系模型1)

    第1讲-初步认识数据库系统 什么是数据库 关系中的概念 : 表 / 关系 表名 / 表标题(格式) / 表内容(值) 列 / 字段 / 属性 / 数据项 行 / 元组 / 记录 而 数据库(Datab ...

  8. java byte数组转string_Java调用C++接口(初步了解)

    (最近听到同事说了一下java调c++接口的事,于是就有点想了解下,然后就各种查资料记录下自己的简单实现过程,环境windows) 1.有java基础的都可以啦,新建一个类,如下(很简单~) pack ...

  9. 大数据入门基础系列之初步认识大数据生态系统圈(博主推荐)

    不多说,直接上干货! 之前在微信公众平台里写过 大数据入门基础系列之初步认识hadoop生态系统圈 http://mp.weixin.qq.com/s/KE09U5AbFnEdwht44FGrOA 大 ...

最新文章

  1. 【行走的Offer收割机】记一位朋友斩获BAT技术专家Offer的面试经历
  2. vue学习笔记(二)- 数据绑定、列表渲染、条件判断
  3. JavaScript实现strongly Connected Components 强连通分量算法(附完整源码)
  4. dexpler的使用方法
  5. Kubernetes 架构(上)- 每天5分钟玩转 Docker 容器技术(120)
  6. MySQL查询数据表中数据记录(包括多表查询)
  7. html画布的作用,HTML的canvas标签作用
  8. 表妹即将去读研,我送了她11个建议
  9. C# WinForm 使用FlowLayoutPanel控件做为导航菜单按钮的容器
  10. MTK Modem编译
  11. 408计算机及格要什么水平,2019考研计算机408难度水平?
  12. 小米6通话音量补丁_手机通话声音小?只需打开这个开关,音量既大又清晰
  13. 计算机开机显示器无显示器,电脑开机显示器显示无信号怎么办
  14. 【Linux 内核】实时调度类 ④ ( 实时运行队列 rt_rq 源码分析 | 实时运行队列 rt_rq 结构体字段分析 | active、rt_nr_running、curr、next 字段 )
  15. CF235C-Cyclical Quest
  16. 我的csdn博客所有的留言和评论我都不太想回复了
  17. 《斯坦福高效睡眠法》读书笔记思维导图版,成年人的睡眠解决法
  18. ubuntu chm文档阅读
  19. 【嵌入式工程师的30岁总结】 真实
  20. 老spring3.2版本 redistemplate 报错_卡普空“令人惊讶”的老系列新作,会是《恐龙危机》吗?...

热门文章

  1. 工业用微型计算机2014年10答案,201010月工业用微型计算机真题.doc
  2. 华为p8是android,有效利用华为P8的这些设置
  3. JS 获取元素到浏览器页面最左侧和顶部的距离
  4. 计算机的cpu可以通过什么控制硬盘软盘,计算机的CPU可以通过――来控制硬盘,软盘,键盘,鼠标,内存等各种设备。...
  5. dnf一换线就服务器不稳定,DNF:史派克做事了!换线黑屏已解决,玩家点取消可返回其它频道...
  6. 进程控制--->进程终止
  7. 易语言CEF3获取请求返回的源码
  8. PaaS+低代码,更猛烈的云计算第三次浪潮
  9. 通过硬件ID精确找到你要的驱动或寻求帮助
  10. js数组排序的六种方法