leveldb流程分析--2
本章开始重点关注ssdb与leveldb的交互上,水平有限,一些关键地方没注意到的或者是说的不全或说错的欢迎批评指正。先上代码:
这就是我们能在ssdb中实际活动的范围,从入口看就这些,拿数据,进行指令分析proc:
再进一步缩小范围,就这儿了,好,我们用set a 1 先从写流程入手调试看下:
现在进入到proc了,
准备进入指令接口:proc_set:
这里重点关注图中红色方框中的这一步,其它的我用调试的方式打印下它的参数:
继续看下set:
都比较关键,分别看下:
encode_kv_key:
生成这样一个key:
Transaction::put:
uddates是:
是leveldb的一个写操作,看下结构和put定义,再继续从slice跟踪,这里都是leveldb相关的了:
看下Put定义:
之后执行wirte就会进行batch操作,其实,这里有一点作者在github上说过了,为啥尽量用batch:
https://github.com/google/leveldb/blob/master/doc/index.md#atomic-updates
大概能猜到直接ADD到了memtable了,好,回到调试流程继续 看:
就是leveldb人家定义的一个内存切片,这里先不继续深究这个了,有兴趣后边再回来补充。
继续就是刚才的Put了,回来之后:
我忍不住再打印下堆栈信息:省的看乱了:
这里的ldb就是在ssdb初始化的时候调用leveldb::DB::open()赋值的:
那看下DBIml::Write():
这里是用这个条件变量mu初始化writer所属线程的cv,就是该线程自己的条件变量,然后在对其上锁:
现在把当前写操作的writer放到一个队列里:
这波操作就是保证轮到自己写log的时候才继续往下走:看下MakeRoomForWrite:
这个函数的作用是为这个写操作做必要的判断和操作,具体的是检查当前所在的memtable是否已满,满了就要创建新的了,然后接下来就是添加日志记录->写入当前的memtable中,我们具体看下怎么写到
memtable中的,先贴一下关键步骤:
应该从代码上就很明了,准备一个memtable的插入操作实例,然后迭代插入
这里的Handler实例对象是memtableinserter,操作如下:
我们调试看下Iterator的一些细节:
其实这个rep_就是存储的这个k-v,
数据从这来的:
对应的操作位置:
进入while(!imput.empty())准备逐步处理这个k-v
现在已拿到内部形式的key值和value值了,要做的就是插入而已
然后逐步返回,并做一些verstion,lastsequence更新的事情,这个verstion和lastsequence的作用是在MakeRoomForWrite中体现的,用来决定内存的使用是否需要调整。
到此客户端拿到数据"ok",
到这,对leveldb的写操作流程简单分析工作已经做完,还有更多的事情需要后续循序渐进补充,例如memtable的一些细节,imemtable,sst,log,manifest的文件的一些细节,还有lebeldb的UML,不过下一章节还是先把读操作流程再调试跟踪一遍,仅此做记录