levelDB-源碼解讀日誌二

上一篇我們隊leveldb功能和靜態結構有個基礎的認識,那麼現在我們主要對leveldb源碼下各個文件的作用和結構做一個梳理。搞清楚各個類的功能和層級關係。

首先時include下的頭文件:

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    => 使多個寫操作成爲原子寫的接口

c.h作用是爲了leveldb的C綁定。可用作穩定的ABI,可由將leveldb保留在共享庫中的程序使用,也可以用於JNI api。

(我們這裏主要關注c++11版本的leveldb,所以做個瞭解就好,用c將大部分c++的接口進行了封裝,讓c語言也可以使用leveldb。)

cache.h

顧名思義就是緩存啦,這裏採用的時LRU策略,同時對於不同條目會有動態的空間花費。觀察相應成員,成員函數:插入,查找,釋放,刪除,注意到這裏定義了一個空的結構體handler,handler的作用時在cache中實現kv之間的映射,至於爲什麼時空的,查閱博客知道所以Handle僅僅是一個虛的結構體.在具體實現時,可以參考leveldb.先自己定義一個結構體,在實現Cache相應的函數時,在返回或使用時調用reinterpret_cast<Cache::Handle*>。個人理解是先聲明一個空的結構體佔位一下,日後可以具體實現。私有成員以及函數沒理解。在LRUCache中果然也沒有對應實現。所以暫時不說。

slice.h

slice是google定義的一個簡單的結構體,其中只有兩個成員,一個指向外存的指針,一個是大小。

slice的使用必須保證對應的外存沒有被釋放,同時多線程可以調用一個slice的常量方法無需同步,非常量則需要同步。

slice其實是google對字符串操作的精簡版,相較c++ 自帶的string,slice更加精簡,本身無法動態開闢空間,從拷貝函數可以看出,拷貝的僅僅是一個指針。因此,開銷會小很多。同時,C++ string和以null結尾的C風格字符串可以很方便的轉換成Slice

status.h

status.h中包含了Status的聲明.Status是leveldb大多數函數調用的返回值.其作用類似於errno,只不過封裝的更爲完善,也更爲c++.

Status的數據存儲在state_中.state_是一個長度至少爲6的字符串.前四位爲message的length,第5位爲status的狀態,再之後的爲message.

table.h

table是一個字符串排序後的表,它是不可改動的。成員函數包括了從文件中讀取table等一些操作

table_builder.h

table_builder主要是提供構建table的相關接口函數。

option.h

option主要定義了數據庫中各個部分的參數,數據壓縮類型,比較函數,block的size,讀的參數,寫的參數,等。

writebatch.h

定義了插入,刪除數據的一些原子操作,以及利用handler對數據的批量操作。這裏提到了append要比用iterate然後每個都put要快,這裏我還沒看具體實現,還不知道爲啥,先mark。

env.h

env.h 將系統調用,文件操作,文件鎖,線程庫等系統調用進行了封裝,成爲了Env.另外將文件抽象成了RandomAccessFile,SequentialFile,WritableFile.這麼抽象的好處顯而易見: 跨平臺更爲簡單.客戶端調用接口抽象出來的一致方法.使得不同平臺下的代碼更爲一致.而實現跨平臺也很簡單.無論是windows,還是*nix,甚至是android及ios,各個平臺只需要實現相應的方法就能完成port的工作.這種方式在開發跨平臺代碼時很值得借鑑.

filter_policy.h

filter_policy.h 作用是利用過濾器來查找key值的有無,https://www.jianshu.com/p/2104d11ee0a2這篇文章講的很好。關於布隆過濾器的。

db.h

db.h是使用leveldb時最經常include的頭文件.在這個頭文件中提供了DB的接口的定義,也是我們需要的部分.在db.h中,定義了Snapshot,Range,DB三個接口.Range爲一個Slice對,定義了[start,end).符合C++的習慣.Snapshot爲DB的某個特定狀態.由於其只讀,因此多線程訪問並不需要鎖.還有一些相應的函數,文檔寫的很清楚。就不過多贅述了。

 

這次主要解讀了include文件夾下頭文件的意義。下一章我們將從靜態結構入手,逐步仔細分析各組件的具體實現。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章