参考网址:http://www.aikaiyuan.com/7925.html
include
└── leveldb
├── c.h => c binding
├── cache.h => cache接口
├── comparator.h => 比较器接口
├── db.h => DB接口
├── env.h => 为跨平台准备的env接口
├── filter_policy.h => fliter策略,用于缓存,请看到文档及相应实现
├── iterator.h => 迭代器,用于遍历数据库中存储的数据
├── options.h => 包含控制数据库的Options,控制读的WriteOptions,ReadOptions
├── slice.h => Slice的接口
├── status.h => leveldb中大多接口返回的Status接口
├── table.h => immutable接口
├── table_builder.h => 用于创建table的构建器接口
└── write_batch.h => 使多个写操作成为原子写的接口
leveldb为使用c代码提供了c bingding,为几乎所有的c++接口都有对应的c函数。
为了提高性能,使用LRU策略的Cache.如果使用自定义的cache方法,需要继承Catch类,并实现其纯虚函数。
Comparator提供了Comparator接口,用于比较key的大小,作为存放位置的参考.其接口定义也较为简单.
db.h是使用leveldb时最经常include的头文件.在这个头文件中提供了DB的接口的定义,也是我们需要的部分.在db.h中,定义了Snapshot,Range,DB三个接口.Range为一个Slice对,定义了[start,end).符合C++的习惯.Snapshot为DB的某个特定状态.由于其只读,因此多线程访问并不需要锁.DB则提供了经常使用的几个方法:
在env.h中,leveldb抽象了一层接口Env,将系统调用,文件操作,文件锁,线程库等系统调用进行了封装,成为了Env.另外将文件抽象成了RandomAccessFile,SequentialFile,WritableFile.这么抽象的好处显而易见: 跨平台更为简单.客户端调用接口抽象出来的一致方法.使得不同平台下的代码更为一致.而实现跨平台也很简单.无论是windows,还是*nix,甚至是android及ios,各个平台只需要实现相应的方法就能完成port的工作.这种方式在开发跨平台代码时很值得借鉴.
由于leveldb对于文件接口使用的较多,所以env中有很多文件操作的接口.除此之外还有线程,logger,时间等使用到的接口.查看代码可以看出,其是庞大的系统调用中的一个非常的微小集合.
filter_policy.h中包含了FilterPolicy接口.由于leveldb的数据存储在文件中,因此一次Get请求可能会引起多次的读操作.Filter的作用就在于通过空间换时间.当leveldb读取某个key时,首先访问filter,以判断数据是否在sstable中.filter的数据存储在内存中,访问速度很高,同时也减少文件IO,提高效率.leveldb提供了一个内置实现: BloomFilterPolicy.
在该头文件中,声明了Iterator接口.该接口主要用于遍历数据库中的数据.leveldb中有多个Iterator的实现,用于遍历Table及Db中的数据.Iterator中的const方法是线程安全的(因为访问该方法不改变数据),剩余的方法在并发条件下需要加锁.Iterator类似于c++中的iter,c++使用较多的朋友也肯定不会陌生.
options.h中给出了经常用到的三个Option: Options, ReadOptions, WriteOptions.
在leveldb中,为了减少数据复制的负担,对于需要传递字符串的部分,都采用了Slice类.string虽然性能也很好,但是其实现有多种,在传递数据时仍然会发生数据拷贝.查看下面的Slice声明,就能发现Slice到底为什么性能高,也为什么会有坑.
status.h中包含了Status的声明.Status是leveldb大多数函数调用的返回值.其作用类似于errno,只不过封装的更为完善,也更为c++.Status的数据存储在state_中.state_是一个长度至少为6的字符串.前四位为message的length,第5位为status的状态,再之后的为message.
talbe是一张按照key进行排序的map.其状态为只读.当用户的写超过一定数量时,leveldb将会生成一个table表.而后由后台线程进行处理,生成sstable.放入磁盘中.具体内容在之后分析leveldb表的格式及源码时再进行了解.
TableBuilder用于创建Table.
WriteBatch为leveldb提供了原子修改的功能.调用者可以在一个batch中多次调用Put和Delete.而后通过db->Write将修改一次性写入到数据库中,而不必担心写到一半出现异常,从而导致数据库数据不一致的状态.作为功能类,WriteBatch的接口十分简洁.仅仅提供了Put,Delete和Clear功能.同时提供了一个Handler,用于遍历Batch中的数据.WriteBatch只有一个成员变量: string rep_.该变量是实现原子修改的关键.实际上,对于WriteBatch的Put,Delete,实际上都是对rep_的操作.在调用DB::Write时,DB将rep_的数据一次性写入log中,而后将数据迭代存入到内存中.由于是一次性写入log,因此能保证写入一致性.