mindpin / problems

问题驱动研发!!
5 stars 1 forks source link

一种虚拟文件系统的设计思路 #86

Open ben7th opened 9 years ago

ben7th commented 9 years ago

不成形思路,先写在这里,暂勿回复

在 2012 年左右,我们开发 esahre 的过程中,曾经设计过虚拟文件系统。 受当时的文件存储方式,设计思路的局限,系统较为繁琐,工作性能也不佳。

而现在,两个条件发生了变化:

  1. 我们已经几乎不再使用关系数据库,而是频繁使用 mongdb 这样的非关系数据库
  2. 文件存储已经主要依赖云服务。

在这种情况下,提出一种新的虚拟文件系统的设计思路。


文件记录对象 FileEntity

文件记录对象不负责文件的存储(存储交给云服务),而是在虚拟文件系统中代表一个文件。 每个文件记录对象具有如下的属性:

class FileEntity
  field :scope # 作用范围
  field :virtual_path # 虚拟文件路径,在作用范围内唯一
end

virtual_path 是一个字符串,该字符串总是以 / 开头,并以类似如下的形式表达: /foo.html /foo/bar.html /foo/bar/ha 它代表该文件在虚拟文件系统内的路径,注意,文件有可能是没有扩展名的。

我们来讨论这样的一个文件结构该怎样表示:

/
├── aaa.html
├── foo
│   └── bbb.html       
└── bar
    └── ha
        ├── ccc.html
        └── ddd

一共有四个文件,可以把它们表示为:

#<FileEntity virtual_path: '/aaa.html'>
#<FileEntity virtual_path: '/foo/bbb.html'>
#<FileEntity virtual_path: '/bar/ha/ccc.html'>
#<FileEntity virtual_path: '/bar/ha/ddd'>

可以看到 virtual_path 非常类似云存储中的 key.


虚拟文件夹对象 DirEntity

原则上来说,只有 FileEntity 对象也足够了。但是有时候我们需要进行“列出某个文件夹下的文件”这样的操作时,需要有比较高效的算法。

而虚拟文件夹对象就是用于进行快速查找的。

逐个来看上面的四个文件,看他们属于哪些文件夹(包括所有祖先文件夹)

#<FileEntity virtual_path: '/aaa.html'>
这个文件在根目录下,所以它并不属于任何文件夹

#<FileEntity virtual_path: '/foo/bbb.html'>
这个文件属于 [ '/foo' ] 这一个文件夹

#<FileEntity virtual_path: '/bar/ha/ccc.html'>
这个文件属于 [ '/bar', '/bar/ha' ] 这两个文件夹

#<FileEntity virtual_path: '/bar/ha/ddd'>
这个文件属于 [ '/bar', '/bar/ha' ] 这两个文件夹

因此,尝试用这样的方法来表示一个虚拟文件夹

class DirEntity
  field :scope # 作用范围
  field :virtual_path # 虚拟文件夹路径,在作用范围内唯一
end

针对上面的文件,会有三个虚拟文件夹

#<DirEntity virtual_path: '/foo'>
#<DirEntity virtual_path: '/bar'>
#<DirEntity virtual_path: '/bar/ha'>

关联关系 FileEntityDirEntity 应该是多对多的关联关系。

当一个虚拟文件属于一个虚拟文件夹(或者属于该虚拟文件夹的子文件夹) 则在他们之间建立关联关系。

ben7th commented 9 years ago

操作过程

创建 /aaa.html,生成

#<FileEntity virtual_path: '/aaa.html'>

创建 /foo/bbb.html,生成

#<FileEntity virtual_path: '/foo/bbb.html'>
#<DirEntity virtual_path: '/foo'>

创建 /bar/ha/ccc.html,生成

#<FileEntity virtual_path: '/bar/ha/ccc.html'>
#<DirEntity virtual_path: '/bar'>
#<DirEntity virtual_path: '/bar/ha'>

创建 /bar/ha/ddd,生成

#<FileEntity virtual_path: '/bar/ha/ddd'>
#<DirEntity virtual_path: '/bar'> 已存在,只是改变关联关系
#<DirEntity virtual_path: '/bar/ha'> 已存在,只是改变关联关系