在leveldb中,Version就代表了一个版本,它包括当前磁盘及内存中的所有文件信息。当执行一次compaction后,Leveldb将在当前版本基础上创建一个新版本,在所有的version中,只有一个是CURRENT。
VersionSet是所有Version的集合,用于管理所有的version。
VersionEdit记录了Version之间的变化,其中记录了基于上一Version增加了多少文件,删除了文件。也就是说:Version0 + VersionEdit --> Version1。
每次文件有变动时,leveldb就把变动记录到一个VersionEdit变量中,然后通过VersionEdit把变动应用到current version上,并把current version的快照,也就是db元信息保存到MANIFEST文件中。
VersionSet是所有Version的集合,用于管理所有的version。
VersionEdit记录了Version之间的变化,其中记录了基于上一Version增加了多少文件,删除了文件。也就是说:Version0 + VersionEdit --> Version1。
每次文件有变动时,leveldb就把变动记录到一个VersionEdit变量中,然后通过VersionEdit把变动应用到current version上,并把current version的快照,也就是db元信息保存到MANIFEST文件中。
另外,MANIFEST文件组织是以VersionEdit的形式写入的,它本身是一个log文件格式,采用log::Writer/Reader的方式读写,一个VersionEdit就是一条log record。
由之前 对leveldb文件命名的分析 可知,通过文件编号和文件类型就可以知道leveldb中文件的完整名称,并获得相应文件了,因此在下面可以看到很多数据结构中都保存的文件编号这一变量。
1、FileMetaData
leveldb中有很多SSTable,其中保存着Key值有序的数据,不同的SSTable文件之间的Key值区间没有重叠(level 0除外)。FileMetaData用于描述每一个.sst文件的信息,它记录了一个SSTable中的最小和最大的Key值,即Key值的变化区间,极大的提高了查找操作的效率。其数据结构如下:
struct FileMetaData {
int refs;//引用次数
int allowed_seeks; //允许的最大查找次数
uint64_t number; //.sst文件编号
uint64_t file_size; // File size in bytes
InternalKey smallest; // Smallest internal key served by table
InternalKey largest; // Largest internal key served by table
};
allowed_seeks的值初始化一般如下:(文件大小除以16K,小于100时为100)
f->allowed_seeks = (f->file_size / 16384);
if (f->allowed_seeks < 100) f->allowed_seeks &