XAPIAN简单介绍(三)
今天主要介紹的是Xapian::Database這個類。先上圖
看上去就非常恐怖的吧,我們一點點的說。
首先一切的開始都來自那個include目錄中的database.h,他的直接實現是在omdatabase.cc中,此外在common目錄中另一個database.h這個文件是DataBase的私有類指針的聲明,在backends/database.cc中給出了這個私有類的實現,當然這個類事實上是個抽象類,他把Database的所要實現的功能都抽象出來了。而且他也是個私有類,對外也是隱藏的。而且代碼的編譯速度也會變快。由于pimpl技術。
那么既然抽象類關鍵的就在于new的地方了。由于這里會實現多態的。在這里xapian把Database這個類的實現寫在了兩個文件!!
!相對擺架子的部分在前面我說的omdatabase.cc中。
而真正最關鍵的就是這個類的構造函數。這里會給出internal的實現。這個關鍵的代碼在dbfactory.cc中。在dbfactory.h和dbfactory.cc中我們在這里被多態了。
在使用中xapian大家有時候可能會這種寫法Xapian::WritableDatabase(Xapian::Brass::open(fullpath, Xapian::DB_CREATE_OR_OPEN, XAPIAN_BLOCK_SIZE))
在這里我們open()的方法事實上調用的是不同的backends的writedatabase的構造函數,然后得到這個類再去用Xapian::WritableDatabase的拷貝構造函數實現了不同的backends做事。此外internal是個接口類這里依據宏我們對其進行了不同的new。
在這里我們才進入了真正的database的處理。以下我就以brassdatabase為例,講述database的實現。各位看官趕緊刷卡上車,我們開車了。
class BrassDatabase : public Xapian::Database::Internal,說個有意思的,他把基類的虛函數寫在了子類的私有方法里面。當然多態之后,還是進入了子類中的那個方法。
在這個類中我們能夠清晰的看到了Xapian的數據庫文件的構成了,這個BrassDatabase類聚合了7個類:
BrassPostListTable(不壓縮數據)
BrassPositionListTable(不壓縮數據)
BrassTermListTable(壓縮數據)
BrassValueManager
BrassSynonymTable(壓縮數據)
BrassSpellingTable(壓縮數據)
BrassRecordTable(壓縮數據)
這里的類大家對他的第一印象參照我第一篇文章給出的xapian的概念。這里不再反復。我主要給大家說下各自的實現。
首先BrassPostListTable,BrassTermListTable,BrassSynonymTable。BrassSpellingTable這四個類繼承于BrassLazyTable。而BrassRecordTable。BrassPostListTable這兩個類繼承于BrassTable。
BrassValueManager這個類比較有意思他事實上能夠看成是BrassPositionListTable,BrassTermListTable這兩個類的組合。在這里我把xapian的value概念看成了特殊的term。value除了維護了一個和term一樣的概念PostListTable,而且本身的value是排序的放置的,當中維護全部Value的狀態
Xapian::doccount freq; (一個slots相應的value相應的document的個數)
std::string lower_bound;(一個slots相應的value最低值)
std::string upper_bound;(一個slots相應的value最大值)
在Xapian里面的基類都不是擺設,非常多時候做事的主要都是基類在做,(此基類非抽象類)。
在這個BrassTable中使用了 BrassTable_base完畢了B樹的數據結構。也就是插入樹的相應位置(原諒小弟才疏學淺這個充滿位運算和B樹的數據結構類我基本是略過了。
。
。),在完畢了B樹的插入之后調用write_to_file方法完畢數據寫入也就是相似于fopen,Xapian本身是單寫多讀的。他運用了fcntrl文件鎖的方式。這個部分也是寫在了BrassTable類中。
BrassTable位于最底層真正讀寫數據庫文件就在這里,而在這之上的那6個類維護了數據在進程中的關系。Value這個類應該是被拆解出BrassPositionListTable,BrassTermListTable記錄到數據庫中。
說究竟。我們再回來到最開始Xapian::Database中,Xapian::WritableDatabase繼承自Xapian::Database,前面Xapian::Database有的他都有,你結合我的第一章和這一章,我認為你應該有一個數據分析存儲提交的大概流程了吧。這里的PositionListTable即傳說中的倒排索引的概念我講得不好,推薦大家看下這個http://www.cnblogs.com/chenying99/p/3149233.html
然后再到我們xapian來。他是一層層最后到BrassTable中寫入了數據。
最后說下Xapian::WritableDatabase中事務的實現。
begin_transaction(bool flushed)
commit_transaction()
cancel_transaction()
begin_transaction對外是默認flushed=true。調用他的時候,他會把開始事務之前的數據從內存也就是我前面提到的七個類維護的數據結構中寫到文件里。再然后他會把transaction_state = TRANSACTION_FLUSHED;然后你開始數據寫操作,數據先寫入了七個類中的數據結構中,當你須要cancel_transaction()就清除七個類的數據結構中保存的數據就好了,你commit_transaction()就提交到磁盤。由于數據不是隨寫隨提交,而是有個寫數據先到內存保存依據你的commit請求再從內存到文件,才有了可方便的撤銷事務。
有些的不好的地方大家多多不吝賜教。我這邊文章事實上重點還是說數據的寫,以下一篇會寫到數據的讀。
上面的UML可能圖太大。我截取了兩個局部的。
總結
以上是生活随笔為你收集整理的XAPIAN简单介绍(三)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从汉诺塔讲递归的思考方式
- 下一篇: 快速学习nodejs系列:六、nodej