上篇文章缘起:BigTable能够说是已经把论文Bigtable: A Distributed Storage System for Structured Data
中的内容掰扯的明明白白,若是哪位小伙伴感受还有不理解的点,能够点链接进去再反复琢磨几遍,说不定就顿悟了呢~html
之因此先花时间把BigTable掰扯了一篇,就是为了引出今天的主人公,LevelDB,接下来呢,我会一点点分享本身阅读LevelDB源码遇到的问题和学习到的一些技术,但愿你们多多关注,若有问题,也请你们多多留言,一块儿学习,一块儿Happy~linux
LevelDB是对BigTable中KV存储分片Tablet的高度复刻,是由Jeff Dean和Sanjay Ghemawat,这两位大牛也是BigTable论文的做者,尽管咱们不能对BigTable的底层实现一探究竟,不过,开源的LevelDB仍是可让咱们对其管中窥豹呢~ios
简而言之,LevelDB就是一个由Google开源的高效的单机Key/Value存储系统,该存储系统提供了Key到Value的有序映射。c++
Put(key, value)
,Get(key)
,Delete(key)
这些基本操做这部分呢,先简单介绍了LevelDB的特性以及使用限制,其实呢,也从侧面给出了LevelDB的使用场景,比较适合单机KV存储。程序员
ε=(´ο`*)))唉、其实呢,我如今的主语言是Java,并非C/C++,过久不用C/C++了,若是有啥错误,各位看官多多提点~算法
Windows下编译LevelDB太恶心了,TM有毒,放弃了、我只是想编译调试下而已,各类拦路虎,算了,爱谁谁,真心感受Windows下除了他自家的全家桶外,别的都很差用,就TM有毒,真是服气了,不搞了,想在Windows下用LevelDB的,本身掂量着办~shell
相比于Windows下LevelDB的编译,Linux环境下简直不要太友好,惟一的缺点就是,用Idea用习惯了,调试有点不太在行~数据库
[root@cos leveldb-1.22]# mkdir -p build && cd build # 注意:为了调试时能够进入LevelDB库源码,这里最好编译成Debug版本 # 编译成Debug版本 [root@cos build]# cmake -DCMAKE_BUILD_TYPE=Debug .. && cmake --build . # 编译成Release版本 [root@cos build]# cmake -DCMAKE_BUILD_TYPE=Release .. && cmake --build . # 将连接文件拷贝到/usr/local/lib目录下,以便程序调用 [root@cos build]# cp libleveldb.a /usr/local/lib/ # 将头文件拷贝到/usr/local/include中,以便程序引用 [root@cos leveldb-1.22]# cp -r include/leveldb/ /usr/local/include/
#include <cassert> #include <iostream> #include <string> #include <leveldb/db.h> int main() { leveldb::DB* db; leveldb::Options options; // 配置项:若是LevelDB数据库目录不存在,则自动建立 options.create_if_missing = true; leveldb::Status status = leveldb::DB::Open(options, "/root/testdb", &db); assert(status.ok()); std::string key = "apple"; std::string value = "Apple"; // 将key/value键值对写入LevelDB数据库 leveldb::Status s = db->Put(leveldb::WriteOptions(), key, value); std::string get; // 写入成功后,尝试根据key进行检索 if(s.ok()) { s = db->Get(leveldb::ReadOptions(), key, &get); } if(s.ok()) { std::cout << "读取到Key=" << key << "对应的Value=" << get << "." << std::endl; } else { std::cout << "读取失败!" << std::endl; } delete db; return 0; }
编译并执行程序,结果以下:windows
# 对main.cc源文件进行编译 [root@cos leveldb]# g++ -o main main.cc -pthread -lleveldb -std=c++11 # 执行main可执行程序 [root@cos leveldb]# ./main 读取到Key=apple对应的Value=Apple.
额(⊙o⊙)…前面说了,我不是作C/C++开发的,Linux是最小化安装的,想调试下代码,难为死我了,高手直接跳过就好~数组
诸如GDB等代码调试器的无外乎两种功能:
基本上每种语言都有代码调试器,而调试器的功能也无非就上面说的这两种功能。
GDB能作的事情,大概能够分为四类,这四类功能能够帮助程序员快速定位Bug。
经过Shell命令gdb
能够启动GDB,一旦GDB启动成功,程序员就能够不断地在终端中输入命令来告知GDB下一步要干吗,若是想要终止的话,则须要输入quit
命令。
用户能够执行gdb
命令的同时不输入任何参数,可是,大多数场景下,用户会输入1到2个参数,以下所示。
# 将可执行程序做为参数,程序编译时须要添加-g参数 gdb program # 将可执行程序以及core文件做为参数 gdb program core # 若是想要调试正在运行的进程,则须要将进程ID做为第二个参数 gdb program 1234 gdb -p 1234
这里只是介绍一些经常使用的GDB命令,更多的话,你们去看man gdb
文档吧
break [file:]functiop
:在指定文件[file]
的functiop
方法入口设置断点
run [arglist]
:启动程序,参数列表为arglist
bt
:Backtrace: 显示程序栈
print expr
:计算表达式expr
的结果
c
:继续执行程序,直到遇到下一个断点
next
:执行下一行(除非遇到断点);也就是说,该命令不管下一行调用多少方法,会直接跳过,除非函数内部有断点
edit [file:]function
:查看指定文件中的方法的断点信息
list [file:]function
:列出当前断点附近的代码
step
:执行下一行代码,若是该行代码有方法调用则进入该方法
help name
:展现GDB的name命令的帮助信息。
注意:上面命令中,next
缩写为n
,step
缩写为s
,分别是按行调试和单步调试,还有c
命令,都是很是经常使用的~
# 对main.cc源文件进行编译,同时加入调试信息,后续可使用gdb进行调试 [root@cos leveldb]# g++ -o main main.cc -pthread -lleveldb -std=c++11 # 使用gdb对main进行调试 [root@cos leveldb]# gdb -tui main
注意:为了调试方便,最好使用-tui
参数,这样的话,调试时,就能够像Idea那样,边看代码边加断点了~
调试时,大概就是下图的样子~
注意:若是在编译LevelDB时未指定为Debug版本,则没法像图2那样进入到LevelDB源码。
其实吧,LevelDB的核心源码及架构,我已经看的七七八八了,就是,自己我主语言是Java的,而后,我就一直没有勇气去Debug到源码中仔细瞅一瞅,趁着此次梳理的机会,打算一点点跟进去看看、可能会更新的有点慢,不过,好事多磨,但愿你们多多关注,同时也欢迎各位C/C++大佬多多指正,多多交流。
另外,你们能够关注个人微信公众号,博客会同步更新的哟~
白嫖多很差,关注下再走呗~