再来分析DoCompactionWork前,我们先来熟悉几个与DoCompactionWork相关的数据结构
Compaction
class Compaction {
public:
~Compaction();
// 返回将要合并的层数,我们将level_与level_+1中冲突的文件合并到level_+1层
int level() const { return level_; }
// 返回VersionEdit用于记录这次合并产生的文件变化
VersionEdit* edit() { return &edit_; }
//返回第level + which层中产生冲突文件的个数,which只能为0或1
int num_input_files(int which) const { return inputs_[which].size(); }
// 返回第level + which层中第i个冲突文件的元数据信息
FileMetaData* input(int which, int i) const { return inputs_[which][i]; }
// 合并产生的新文件的最大文件大小,超过该值就得另生成新文件用于合并
uint64_t MaxOutputFileSize() const { return max_output_file_size_; }
// 能否直接将第level层的冲突文件直接放入level + 1层
bool IsTrivialMove() const;
// 冲突的文件合并完后就可以删除了,将要删除的文件记录进edit中
void AddInputDeletions(VersionEdit* edit);
// level+1层以上层中的文件都不包含该user_key,说明该user_key是最老的了
bool IsBaseLevelForKey(const Slice& user_key);
// 是否该停止对internal_key的合并,停止的原因是因为将
bool ShouldStopBefore(const Slice& internal_key);
// 减少input_version_的引用计数
void ReleaseInputs();
private:
friend class Version;
friend class VersionSet;
Compaction(const Options* options, int level);
int level_;//合并哪一层
uint64_t max_output_file_size_;//合并产生的文件大小的最大值
Version* input_version_; //合并的版本
VersionEdit edit_; //用来记录合并过程中sst文件的变化情况
// "level_" and "level_+1"层中需要进行合并的冲突文件的元数据集合
std::vector<FileMetaData*> inputs_[2];
// grandparent == level_ + 2,第level_ + 2层文件的元数据信息集合
std::vector<FileMetaData*> grandparents_;
size_t grandparent_index_; // Index in grandparent_starts_
bool seen_key_; //用于判断现在要合并的key是否以及和level+2层文件产生冲突了
int64_t overlapped_bytes_; //用于记录当前合并产生的level+1层的文件与level+2层产生冲突的文件大小总和
// State for implementing IsBaseLevelForKey
//用于优化IsBaseLevelForKey性能的,因为调用IsBaseLevelForKey的key都是递增的
//所以没有必要每次都从各层的第一个文件检查
size_t level_ptrs_[config::kNumLevels];
};
bool Compaction::IsTrivialMove()