今天主要介绍的是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最大值)

这个结构体叫ValueStats。然后本身还维护了一个结构。这个结构保存了document id。slots,value三者的相应关系。
std::map<Xapian::valueno, std::map<Xapian::docid, std::string> > changes; 我们接着聊其它的6个类,首先前面说到了BrassLazyTable和BrassTable,BrassLazyTable继承于BrassTable。他们差别就在于BrassTable默认不压缩数据,我们的xapian採用zlib技术来压缩数据。
BrassTable(const char * tablename_, const std::string & path_,
bool readonly_, int compress_strategy_ = DONT_COMPRESS,
bool lazy = false);

在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简单介绍(三)的更多相关文章

  1. Deep learning:三十八(Stacked CNN简单介绍)

    http://www.cnblogs.com/tornadomeet/archive/2013/05/05/3061457.html 前言: 本节主要是来简单介绍下stacked CNN(深度卷积网络 ...

  2. {MySQL数据库初识}一 数据库概述 二 MySQL介绍 三 MySQL的下载安装、简单应用及目录介绍 四 root用户密码设置及忘记密码的解决方案 五 修改字符集编码 六 初识sql语句

    MySQL数据库初识 MySQL数据库 本节目录 一 数据库概述 二 MySQL介绍 三 MySQL的下载安装.简单应用及目录介绍 四 root用户密码设置及忘记密码的解决方案 五 修改字符集编码 六 ...

  3. Android Fragment(三)ListFragment简单介绍以及Fragment之间通信

    一.Fragment通信简单介绍:Fragments之间是不能够直接通信的,他们之间的通信是通过Activity这个中间件来通信的, 为了让Fragment跟它的Activity通信,我们可以在Fra ...

  4. 2、Cocos2dx 3.0游戏开发找小三之引擎简单介绍

    尊重开发人员的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27094663 引擎简单介绍 Cocos2d-x 的 ...

  5. 【转载】salesforce 零基础开发入门学习(三)sObject简单介绍以及简单DML操作(SOQL)

    salesforce 零基础开发入门学习(三)sObject简单介绍以及简单DML操作(SOQL)   salesforce中对于数据库操作和JAVA等语言对于数据库操作是有一定区别的.salesfo ...

  6. 5、Cocos2dx 3.0游戏开发找小三之測试例子简单介绍及小结

    重开发人员的劳动成果.转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27186557 測试例子简单介绍 Cocos2d-x ...

  7. 利用Python进行数据分析(7) pandas基础: Series和DataFrame的简单介绍

    一.pandas 是什么 pandas 是基于 NumPy 的一个 Python 数据分析包,主要目的是为了数据分析.它提供了大量高级的数据结构和对数据处理的方法. pandas 有两个主要的数据结构 ...

  8. 利用Python进行数据分析(4) NumPy基础: ndarray简单介绍

    一.NumPy 是什么 NumPy 是 Python 科学计算的基础包,它专为进行严格的数字处理而产生.在之前的随笔里已有更加详细的介绍,这里不再赘述. 利用 Python 进行数据分析(一)简单介绍 ...

  9. ListView和Adapter数据适配器的简单介绍

    ListView 显示大量相同格式数据 常用属性: listSelector            listView每项在选中.按下等不同状态时的Drawable divider            ...

随机推荐

  1. jmeter生成时间的函数

    在一个接口测试中,需要提交的请求中要带时间,在看完jmeter帮忙文档,正好总结一下 1.需求 在一个http请求中请求数据要带有时间,如下: 2.实现 突然想到jmeter自带的函数助手好像是可以实 ...

  2. offset家族基本简介

    Offset家族简介 offset这个单词本身是--偏移,补偿,位移的意思. js中有一套方便的获取元素尺寸的办法就是offset家族: offsetWidth和offsetHight 以及offse ...

  3. mvc使用linq to sql进行sum统计遇到查询为null的问题

    mvc linq to sql,linq to entity,sum,null 昨天写了段sum的统计语句, decimal sums sums = ( from fac in db.Apply wh ...

  4. quartz在集群环境下的最终解决方案

    在集群环境下,大家会碰到一直困扰的问题,即多个 APP 下如何用 quartz 协调处理自动化 JOB . 大家想象一下,现在有 A , B , C3 台机器同时作为集群服务器对外统一提供 SERVI ...

  5. Sqoop hive 和mysql 交互 完整案例

    本文完成:在hive里建管理表:注入部分数据:利用sqoop导入mysql中 期间:解决中文乱码问题   飞行报告故障表 建表命令 查看表 人工灌入少量数据 Windows系统向Linux系统数据传输 ...

  6. (转)Hibernate框架基础——多对多关联关系映射

    http://blog.csdn.net/yerenyuan_pku/article/details/52756536 多对多关联关系映射 多对多的实体关系模型也是很常见的,比如学生和课程的关系.一个 ...

  7. (转) 淘淘商城系列——Redis集群的搭建

    http://blog.csdn.net/yerenyuan_pku/article/details/72860432 本文我将带领大家如何搭建Redis集群.首先说一下,为何要搭建Redis集群.R ...

  8. 判断点击第几个按钮JS代码的三种方法

    方法一:使用下标实现<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> < ...

  9. 05JavaScript中的事件处理

    JavaScript中的事件处理 在JavaScript中,事件的发生主要是由窗口中内容变化.键盘和鼠标引起的.JavaScript在某些事件发生的时候,可以通过一些相应的事件处理器来捕获这些事件,并 ...

  10. 关于DOS-BOX的使用方法

    将MASM文件夹里的全部文件拷贝到一个目录下,比如E:\masm下,然后将这个目录挂着为DOSBox的一个盘符下,挂载命令为 Mount c e:\masm 切换到E盘 然后编译,运行