一个简单的leveldb使用示例如下:
<code class="hljs cpp has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <assert.h></span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <iostream></span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include "leveldb/db.h"</span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include "leveldb/env.h"</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">namespace</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">std</span>; <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <assert.h></span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <iostream></span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include "leveldb/db.h"</span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include "leveldb/env.h"</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">namespace</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">std</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> main() { leveldb::DB *db; leveldb::Options ops; ops.create_if_missing=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>; <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">std</span>::<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">string</span> dbpath=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"testdb"</span>; leveldb::Status status=leveldb::DB::Open(ops,dbpath,&db); assert(status.ok()); <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">string</span> key=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"lili"</span>; <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">string</span> value=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"hihi"</span>; <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">string</span> res; status=db->Put(leveldb::WriteOptions(),key,value);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//将Key-Value插入到leveldb中</span> status=db->Get(leveldb::ReadOptions(),key,&res);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//根据Key值在leveldb中查找其对应的Value,返回值存放在res中</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span><<res<<endl; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">delete</span> db; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li></ul>
Put操作
1、根据leveldb的源码可知,leveldb::DB是一个抽象基类,其中定义了一些纯虚函数,包括Put和Get等,使其只能作为父类被继承,而不能被实例化。leveldb::DBImpl继承自该基类,因此在调用db->Put()时,首先调用的是leveldb::DBImpl->Put()方法:
<code class="hljs cs has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;">Status DBImpl::Put(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> WriteOptions& o, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> Slice& key, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> Slice& val) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> DB::Put(o, key, val); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>
在该方法中,只是简单的调用父类leveldb::DB实现的Put()方法,leveldb::DBImpl只是提供一个接口。
2、以前以为纯虚函数是只能定义不能实现的,通过leveldb才发现原来纯虚函数也是可以实现的,然后被显式调用。leveldb::DB中的Put方法如下:
<code class="hljs cs has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;">Status DB::Put(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> WriteOptions& opt, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> Slice& key, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> Slice& <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>) { WriteBatch batch; batch.Put(key, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">value</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//将key,value组织成一条记录存放在batch中</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> Write(opt, &batch);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//调用Write方法写入记录</span> }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>
一条记录包含如下内容:
Type、Key、Value
当要插入记录时,Type为kTypeValue,当要删除记录时,Type为kTypeDeletion,同时中每一个batch都有一个对当前批处理记录信息的统计(sequence(8字节)和count(4字节),共12字节)
由此可见,当我们要删除一个数据时,并不是直接从内存中删除,而是插入一条带有删除标志的记录
在本例中要插入数据:key=”lili”; value=”hihi”;
由之前对WriterBatch的分析可知,得到的batch为:
01 00 00 00 00 00 00 00 01 00 00 00 (前8字节表示是第一个batch,后4字节表示此batch中只有一条记录)
01(kTypeValue) 04(Key.size) 6C 69 6C 69(lili) 04(value.size) 68 69 68 69(hihi)
共12+1+1+4+1+4=23字节=0x17
3、然后调用leveldb::DBImpl->Write()写入记录:
<code class="hljs lasso has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;">Status DBImpl<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::Write</span>(const WriteOptions<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span> options, WriteBatch<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span> my_batch) { Writer w(<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span>mutex_); w<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>batch <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> my_batch; w<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>sync <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> options<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>sync;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//default is false</span> w<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>done <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">false</span>; MutexLock l(<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span>mutex_); writers_<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>push_back(<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span>w);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//将writer加入任务队列deque</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!</span>w<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>done <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&&</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span>w <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span> writers_<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>front()) {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//未执行,且不在任务队列首部,则等待</span> w<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>cv<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>Wait(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (w<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>done) {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//已执行完毕,返回status</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> w<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>status; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//确保有Memtable和log文件可以用于数据的写入,对已写满的Memtable后台调度Compaction</span> Status status <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> MakeRoomForWrite(my_batch <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">==</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NULL</span>); uint64_t last_sequence <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> versions_<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>LastSequence(); Writer<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span> last_writer <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span>w; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (status<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>ok() <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&&</span> my_batch <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NULL</span>) {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 当batch为空时,是准备执行compactions操作,否则插入记录</span> WriteBatch<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span> updates <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> BuildBatchGroup(<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span>last_writer);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//将任务队列中所有的非同步任务组织在一起形成一个WriteBatch,一起批量写入,可以极大的提升写的效率</span> WriteBatchInternal<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::SetSequence</span>(updates, last_sequence <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">+</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>); last_sequence <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">+=</span> WriteBatchInternal<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::Count</span>(updates); { mutex_<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>Unlock(); status <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> log_<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>AddRecord(WriteBatchInternal<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::Contents</span>(updates));<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//调用fwrite将记录写入log文件中</span> bool sync_error <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">false</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (status<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>ok() <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&&</span> options<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>sync) { status <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> logfile_<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>Sync();<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//若设置了同步,则每次写成功后都同步一次</span> } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (status<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>ok()) { status <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> WriteBatchInternal<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::InsertInto</span>(updates, mem_);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//将updates中的记录插入到mem_中</span> } mutex_<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>Lock(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (updates <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">==</span> tmp_batch_) tmp_batch_<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>Clear(); versions_<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>SetLastSequence(last_sequence); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span>) {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//等待队列中的其它任务</span> Writer<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span> ready <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> writers_<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>front(); writers_<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>pop_front(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (ready <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span>w) { ready<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>status <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> status; ready<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>done <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span>; ready<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>cv<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>Signal(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (ready <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">==</span> last_writer) break; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Notify new head of write queue</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!</span>writers_<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>empty()) { writers_<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>front()<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>cv<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>Signal(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> status; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li></ul>
通过调用log_->AddRecord()将记录写入到log中,由之前对log文件写操作的分析 可知,log文件每次写入一个batch的时候都会在前面为其加上7字节的首部(CRC(4字节)、记录长度(2字节)、type(1字节)),其中CRC与type有关。
对于本例,length=23=0x17字节
记录为第一个,且不会占满当前block,因此type为 kFullType=0x01
最终在testdb目录下的.log文件中可看到如下结果:
00000000h: 66 5F 61 EE 17 00 01 01 00 00 00 00 00 00 00 01 ; f_a?………..
00000010h: 00 00 00 01 04 6C 69 6C 69 04 68 69 68 69 ; …..lili.hihi
向log文件中写入成功后,会调用WriteBatchInternal::InsertInto()将记录插入到Memtable中,记录在Memtable中是按照user_key升序,sequence降序排列的,这样所有user _key相同的记录都是聚集在一起的,且其中第一个就是最新的记录,在后面的合并操作中,我们只需要处理相同user _key的第一条记录即可,后面的都可以丢弃。
写操作可能会导致Memtable写满,此时就需要将其转化为immutable memtable,并在后台调用合并操作将其转化为SSTable。这是在MakeRoomForWrite()中完成的。
Get操作
db->Get()会调用DBImpl::Get(const ReadOptions& options,const Slice& key,std::string* value),查找key对应的值存放到value中。
<code class="hljs lasso has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;">Status DBImpl<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::Get</span>(const ReadOptions<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span> options, const Slice<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span> key, std<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::string</span><span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span> value) { Status s; MutexLock l(<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span>mutex_); MemTable<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span> mem <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> mem_; MemTable<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span> imm <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> imm_; Version<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span> current <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> versions_<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>current(); mem<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>Ref(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (imm <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NULL</span>) imm<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>Ref(); current<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>Ref(); bool have_stat_update <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">false</span>; Version<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::GetStats</span> stats; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Unlock while reading from files and memtables</span> {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//主要的查找操作,,</span> mutex_<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>Unlock(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// First look in the memtable, then in the immutable memtable (if any).</span> LookupKey lkey(key, snapshot); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mem<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>Get(lkey, value, <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span>s)) {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//首先在memtable中查找</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Done</span> } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (imm <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NULL</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&&</span> imm<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>Get(lkey, value, <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span>s)) {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//若没找到则继续在immutable memtable中查找</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Done</span> } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//若还没找到,则继续在sstable中查找</span> s <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> current<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>Get(options, lkey, value, <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span>stats); have_stat_update <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span>; } mutex_<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>Lock(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (have_stat_update <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&&</span> current<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>UpdateStats(stats)) { MaybeScheduleCompaction();<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//可能进行campact操作</span> } mem<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>Unref(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (imm <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NULL</span>) imm<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>Unref(); current<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>Unref(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> s; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li></ul>
由上可知,leveldb是按照Memtable、immutable memtable,SSTable的优先级来进行查找的。其中每个SSTable文件都是有查找次数限制的,在FileMetaData(记录每个.sst文件信息的数据结构)中被初始化的。因此在SSTable中查找时,也可能会触发合并操作。
在查找时用到了version,leveldb 使用 version 来保存数据库的状态,Version 保存了所有level的所有的SSTable文件信息,通过version->Current()可用来获取”current” version(当前版本)。
在SSTable中查找时,首先是从低到高遍历当前Version中所有level中的所有文件,逐个找出Key值范围覆盖了目标Key值的文件,然后依次在这些文件中进行查找。
每一个数据库中都有一个缓存变量table_cache,用于缓存最近使用的.sst文件信息,由于内存访问速度比磁盘访问速度快得多,这样可以极大的提高查找的效率。因此在查找.sst文件时,若.sst文件不在缓存中,则将其加入缓存。