leveldb源码分析9
leveldb源码分析9 本系列《leveldb源码分析》共有22篇文章,这是第九篇 6 SSTable之3 6.5 读取sstable文件 6.5.1 类层次 Sstable文件的读取逻辑在类Table中,其中涉及到的类还是比较多的,如图6.5-1所示。 Table类导出的函数只有3个,先从这三个导出函数开始分析。其中涉及到的类(包括上图中为画出的)都会一一遇到,然后再一一拆解。 本节分析sstable的打开逻辑,后面再分析key的查找与数据遍历。 6.5.2 Table::Open() 打开一个sstable文件,函数声明为: static Status Open(const Options& options, RandomAccessFile* file, uint64_tfile_size, Table** table); 这是Table类的一个静态函数,如果操作成功,指针*table指向新打开的表,否则返回错误。 要打开的文件和大小分别由参数file和file_size指定;option是一些选项; 下面就分析下函数逻辑: *1* S1 首先从文件的结尾读取Footer,并Decode到Footer对象中,如果文件长度小于Footer的长度,则报错。Footer的decode很简单,就是根据前面的Footer结构,解析并判断magic number是否正确,解析出meta index和index block的偏移和长度。 *table = NULL; if (size <Footer::kEncodedLength) { // 文件太短 returnStatus::InvalidArgument("file is too short to be an sstable"); } charfooter_space[Footer::kEncodedLength]; // Footer大小是固定的 Slice footer_input; Status s = file->Read(size -Footer::kEncodedLength, Footer::kEncodedLength, &footer_input, footer_space); if (!s.ok()) return s; Footer footer; s =footer.DecodeFrom(&footer_input); if (!s.ok()) return s; S2 解析出了Footer,我们就可以读取index block和meta index了,首先读取index block。 BlockContents contents; Block* index_block = NULL; if (s.ok()) { s = ReadBlock(file, ReadOptions(),footer.index_handle(), &contents); if (s.ok()) { index_block = newBlock(contents); } } 这是通过调用ReadBlock完成的,下面会分析这个函数。...