Seafile FUSE 虚拟文件系统开发---数据模型
本周对seafile项目源代码进行了初步的分析,主要是理清项目中的各个数据模型,理清他们之间的关系,理解数据储存的细节,我将整理部分我研究过的数据类型,并按照我的理解给出他们的关系,最后给出他们的储存细节。
注:一下的数据类型均省去了一些与实现FUSE文件系统实现无关的细节。
1 . 基本数据模型
1)数据模型: Repo
类型 | 名称 | 描述 |
gchar* | id | 该REPO的ID号,用于索引 |
gchar* | name | 该仓库名称 |
gboolean | encrypted | 该仓库是否加密 |
SeafBranch | head | 分支 |
gchar* | store_id | 源仓库的ID,实际的fs,block等储存在该仓库下。 |
2) 数据模型:Branch
类型 | 名称 | 描述 |
char* | id | 该Branch的ID号,用于索引 |
char* | name | 该分支名称 |
char* | commit_id | 分支最近一次commit的id |
3) 数据模型:Commit
类型 | 名称 | 描述 |
char* | commit_id | 该commit的ID号,用于索引 |
char* | repo_id | 该commit所属的repo的id |
char* | root_id | 该commit所属的文件系统的根的id |
char* | parent_id | 上一次commit的id |
guint64 | ctime | 该commit创建的时间 |
4) 数据模型:Dir
类型 | 名称 | 描述 |
char* | dir_id | 该目录在文件系统id,用于索引 |
List * | entries | 目录项列表 |
5) 数据模型:Dirent
类型 | 名称 | 描述 |
char* | id | 目录项在文件系统中的id号用于索引 |
char* | name | 该目录项名称 |
Int | mode | 模式,包含是目录项类型(目录,文件),权限等信息 |
guint64 | mtime | 修改时间 |
6) 数据模型:File
类型 | 名称 | 描述 |
char* | file_id | 该文件在文件系统中id号,用于索引 |
guint | n_blocks | 该文件的块数 |
char** | blk_chals | 该文件的块id表,用于所以该文件的所有块 |
2. 数据模型之间的联系
在熟悉了基本的数据类型之后,理清数据类型之间的联系不管对阅读代码,还是实现功能都是很用帮助的。但是我没有找到官方的这方面的文档,于是通过阅读代码,大致大致理清了其关系。以下是我的一些理解:
Repo 是仓库,仓库具有不同的分支。但现在本项目中仓库好像只有默认的“master”分支。与git相似,每个commit代表了一次仓库的更新,并且每个commit可以通过 parent_id找到上一个commit,这样就可以实现仓库版本的管理。commit 的 root_id 是其对应版本仓库的文件系统的根目录的索引,通过其可以获取根目录信息。dir 表示 文件系统中的目录,通过文件系统的id可以获取到。在每个目录中有该目录的目录项列表,该目录项为此有该项目的名字,修改信息,类型,等文件系统相关信息,并且通过 其对应的id号 ,可以进一步获取对应结构(file,dir)。flle代表一个文件,为此一个块索引列表,通过块索引可以获取对应的块。其关系如下图所示。
3. 储存细节
在熟悉这些数据结构之后,再利用现成的函数操作这些数据结构,就能够实现相应功能。但是是熟悉这些数据在底层的储存细节,能够更有效的理解系统,或者在调试的时候定位错位。以下是相关数据结构关系图:
SeafSession 管理了会话过程中的所有数据结构 ,SeafRepoManager 和 SeafBranchManager 分别管理了对 Repo 和 branch 的操作 ,并通过 SeafDB访问数据库。SeafCommitManager 和 SeafFsManager 分别用于管理 Commit 和 Fs 。SeafObjStore 封装了底层访问细节,ObjBackend 由一列函数向量和一个与实现类型相关的私有数据构成。 由此可以保持程序的灵活性,和高度的可修改性。SeafBlockManager 实现了对块的管理,BlockBend封装了存储的实现细节。经过进一步的分析发现 Commit ,Fs,Block等数据结构以Json储存在文件中,根据其 id 和 类型转化为文件系统的地址,然后获取这些数据结构。而Repo 和 branch 信息都被保存在数据库中。