上篇文章緣起: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++大佬多多指正,多多交流。
另外,你們能夠關注個人微信公衆號,博客會同步更新的喲~
白嫖多很差,關注下再走唄~