1.设计思路
以block文件的形式存放数据文件(一般64M一个block),以下简称为“块”,每个块都有唯一的一个整数编号,块在使用之前所用到的存储空间都会预先分配和初始化。
每一个块由一个索引文件、一个主块文件和若干个扩展块组成,“小文件”主要存放在主块中,扩展块主要用来存放溢出的数据。
每个索引文件存放对应的块信息和“小文件”索引信息,索引文件会在服务启动是映射(mmap)到内存,以便极大的提高文件检索速度。“小文件”索引信息采用在索引文件中的数据结构哈希链表来实现。
每个文件有对应的文件编号,文件编号从1开始编号,依次递增,同时作为哈希查找算法的Key 来定位“小文件”在主块和扩展块中的偏移量。文件编号+块编号按某种算法可得到“小文件”对应的文件名。
2.什么是哈希链表
哈希表 - 散列表,它是基于快速存取的角度设计的,也是一种典型的“空间换时间”的做法
关键点: 键(key): 文件的编号 如, 1 、 5 、 19 。 。 。
值(value): 文件的索引信息(包含 文件大小、位置)
索引: 数组的下标(0,1,2,3,4) ,用以快速定位和检索数据
哈希桶: 保存索引的数组,数组成员为每一个索引值相同的多个 元素(以链表的形式链接)的首节点
哈希函数: 将文件编号映射到索引上,采用求余法 ,如: 文件编号 19
关键数据结构
struct BlockInfo
{
uint32_t block_id_; //块编号 1 ......2^32-1 TFS = NameServer + DataServer
int32_t version_; //块当前版本号
int32_t file_count_; //当前已保存文件总数
int32_t size_; //当前已保存文件数据总大小
int32_t del_file_count_; //已删除的文件数量
int32_t del_size_; //已删除的文件数据总大小
uint32_t seq_no_; //下一个可分配的文件编号 1 ...2^64-1
}
struct RawMeta {
uint64_t fileid_; //文件编号
struct
{
int32_t inner_offset_; //文件在块内部的偏移量
int32_t size_; //文件大小
} location_;
struct MetaInfo{
RawMeta raw_meta_; //文件元数据
int32_t next_meta_offset_; //当前哈希链下一个节点在索引文件中的偏移量
}