comparator.c/log_read.h/block.h/table.h/table_cache.h分析
一、comparator.c分析
抽象类,有两个类继承他BytewiseComparatorImpl、InternalKeyComparator
函数功能:
- FindShortestSeparator(std::string* start,const Slice& limit):如果*start<*limit,就在[start,limit)中找到一个短字符串并赋给*start;
-
FindShortSuccessor(std::string* key):找到一个>=*key的短字符串
排序的依据:
- user key:升序
- sequence number:降序
- value type:降序
二、log_reader.h分析
接口:reporter(汇报错误的)、sequentialfile(log文件读取类)
-
ReadRecord:
- 调整到指定位置-->SkipToInitialBlock(计算出在block的偏移量,确保是完整的block)
- 从文件读取record:得到正在读取的record的偏移值(record_type),record_type=kffType:是一条完整的record,成功饭hiuser record数据,核心函数是ReadPhysicalRecord(将读取到的内容放在buffer_中)
-
buffer_.size()<kHeaderSize
- eof=false:清空buffer,读取数
- eof=true&&buffer_为空:正常结束
- eof=true&&buffer_不为空:报错
- 表明已是一个完整的log record
- 校验crc32
-
三、block.h分析
功能:读取block内容
构造函数:用指定对象初始化,解析重启点数组
inter类:
- next
- 跳到下一个键值对,其位置在当前value之后
- 解析出entry,更新解析的状态,成功取出key value,更新重启点
- prev
- 向前回跳到current_前面那个重启点,并定位到重启点的k/v开始位置,从重启点位置向后遍历,直到遇到original前面的那个k/v对
四、table.h分析
功能:读取sstable文件
-
Open():
- 从结尾读取Footer(有一个魔数,用来decord),解析出meta index和index block的偏移量和长度
- 通过ReadBlock读取index block
- 此时table可以响应请求了,构建table对象,通过ReadMeta读取meta index数据构建filter policy,如果option打开了cache,还要为table创建cache
- ReadBlock()
- 根据handle指定的偏移和大小,读取block内容,type(1) crc32(4)
- 校验crc32
- type
- 非压缩:直接读取数据赋给result
- 压缩:解压,仔赋值
- ReadMeta()
- 先调用ReadBlock()读取Meta内容
- 根据读取的content构建Block,找到指定的filter,用ReadFilter构建filter对象
- ReadFilter()
- 解析出filter的偏移和大小
- 根据位置读filter内容,加入block的heap_allocted为true,表明需要自行释放堆内存,因此要把指针保留在filter data中,创建filterblockReader对象
TwoLevelIterator中的
- BlockFunction():block存储格式是相同的,但各自Block data存储的kv不同,能够在使用同意方式遍历不同的block时,又能解析出这些kv
-
InitDataBlock():根据index_iter来初始化data_iter,定位到新的block时需要
五、table_cache.h
Table_cache相当于所有打开的sst文件在内存中的管理结构,内部采用Lrucache,每个打开的sst文件在lrucache中都有一项map<file_number>{file,table}