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