lucene的IndexReader的初始化过程

在使用Lucene时,有一条建议”不要频繁去打开关闭硬盘索引”。为什么会有这条建议?这就需要在IndexReader的实例化过程中找答案。先说一个结论“IndexReader的实例化过程是一个非常耗时的过程”。由于IndexReader只是一个抽象类,在调用代码:

真正得到的是StandardDirectoryReader对象。首先来看一下StandardDirectoryReader的类图:

最重要的一个类就是SegmentCoreReader,它关联着整个segment中的所有文件。SegmentCoreReader是通过Codec来得到各个文件的处理对象,结构图如下:(可以在新标签页面中查看大图,会更清晰一些)

初始化过程的关键的JAVA代码如下:

在SegmentInfos.FindSegmentsFile.run(commit)方法执行的过程中,会读取segments.gen文件,确定segments的最大的generation。在StandardDirectoryReader.open(Directory)方法执行的过程中,sis.read(directory,segmentFileName)在执行过程中步骤如下:

1、  通过segments_N的文件名得到N的最大值,即索引的最后CommitPoint。

2、  对比segments.gen文件中写入的两个generation值,得到N的最大值。

3、  从segments_N中读取到索引段的总体信息,并依次读取出所有si文件。

4、  从每个_N.si 文件中读取索引段的相关信息(操作系统信息,Lucene版本信息,当前段管理的文件信息),形成SegmentInof对象,最后汇总得到SegmentInfos对象

5、  用CRC32校验segments_N文件的正确性。

对于每个SegmentInfo对象,都会生成一个SegmentReader对象,即代码:

readers[i]=new SegmentReader(sis.info(i),termInfosIndexDivisor,IOContext.READ);

这段代码就是读取每个segment的总体信息,比如docCount,totalTermFreq等信息,并把segment中的相关文件关联起来。在SegmentCoreReader类的构造函数里,把索引的核心文件都打开且读取了相关信息。

1、  依次读取每个段的文件信息。

2、  从_N.fnm文件中读取每个Field的配置信息,得到相当段的所有FieldInfo,组成FieldInfos。

3、  打开倒排表的相关文件(doc/pos/pay)

4、  打开词典文件(tim/tip)

5、  读取索引的统计信息(docFreq,tatalTermFreq,docCount等信息)

6、  读取nvm/nvd文件,得到相关norms信息。

7、  读取fdx/fdt文件。

通过这些初始化过程,就完成了IndexReader的初始化。当索引的数据很大时,这个加载过程就比较耗时了。所以“不要频繁去打开关闭硬盘索引”。

lucene的IndexReader的初始化过程

时间: 2024-07-31 14:44:54

lucene的IndexReader的初始化过程的相关文章

一步一步跟我学习lucene(7)---lucene搜索之IndexSearcher构建过程

最近一直在写一步一步跟我学习lucene系列(http://blog.csdn.net/wuyinggui10000/article/category/3173543),个人的博客也收到了很多的访问量,谢谢大家的关注,这也是对我个人的一个激励,O(∩_∩)O哈哈~,个人感觉在博客的编写过程中自己收获了很多,我会一直继续下去,在工作的过程中自己也会写出更多类似系列的博客,也算是对自己只是的一种积累: IndexSearcher 搜索引擎的构建分为索引内容和查询索引两个大方面,这里要介绍的是luce

java代码的初始化过程研究

刚刚在ITeye上看到一篇关于java代码初始化的文章,看到代码我试着推理了下结果,虽然是大学时代学的知识了,没想到还能做对.(看来自己大学时掌握的基础还算不错,(*^__^*) 嘻嘻--)但是博主写的不够详细具体,我想在这详细谈一下java代码的具体初始化过程. 首先要清楚,初始化分为两个过程:类初始化.对象初始化. 类初始化是指类加载器将类加载到内存时,对类成员的初始化过程,也就是有static修饰的变量.对于加载完的类,它的类变量都会赋一个默认值,即使你定义时就赋值了.比如int类型就是0

JAVA对象的初始化过程

出处:http://blog.csdn.net/andrew323/article/details/4665379 下面我们通过两个例题来说明对象的实例化过程. 例1:   编译并运行该程序会有以下输出 Static Block Employee Company:china soft Non-Static Block Employee phone:0755-51595599 Employee(String) Empoloyee() 下面我们来对结果做分析: 1 在代码34行实例化对象时, 先对给

Java对象相关元素的初始化过程

1.类的成员变量.构造函数.成员方法的初始化过程 当一个类使用new关键字来创建新的对象的时候,比如Person per = new Person();JVM根据Person()寻找匹配的类,然后找到这个类相匹配的构造方法,这里是无参构造,如果程序中没有给出任何构造方法,则JVM默认会给出一个无参构造.当创建一个对象的时候一定对调用该类的构造方法,构造方法就是为了对对象的数据进行初始化.JVM会对给这个对象分配内存空间,也就是对类的成员变量进行分配内存空间,如果类中在定义成员变量就赋值的话,就按

对Socket CAN的理解(5)——【Socket CAN控制器的初始化过程】

转载请注明出处:http://blog.csdn.net/Righthek 谢谢! 对于一般的CAN模块,进行初始化时,最关键的是以下两步: 1.  配置CAN的位时序: 2.  配置CAN的消息报文: 下面,我们来详细分析上面提到的关键两步. 一.初始化步骤: 1.  第一步,进入初始化模式,在CAN控制寄存器中,将Init位置1: 2.  第二步,在CAN控制寄存器中,将CCE位置1: 3.  第三步,等待Init位置1,此步聚为了确保已经进入初始化模式: 4.  第四步,将位时序的值写入到

IOC容器的初始化过程

1.ClassPathXmlApplicationContext类体系结构 左边的黄色部分是ApplicationContext体系继承结构,右边是BeanFactory结构体系,两个体系是典型的模板方法设计模式的使用. 从该继承体系可以看出: (1)BeanFactory是一个bean工厂的最基本定义,里面包含了一个bean工厂的几个最基本方法:getBean(),containsBean()等,是一个很纯粹的bean工厂,不关注资源.资源位置.事件等. ApplicationContext是

Java初始化过程

以下程序执行的结果是: class X{ Y y=new Y(); public X(){ System.out.print("X"); } } class Y{ public Y(){ System.out.print("Y"); } } public class Z extends X{ Y y=new Y(); public Z(){ System.out.print("Z"); } public static void main(Stri

启动期间的内存管理之初始化过程概述----Linux内存管理(九)

日期 内核版本 架构 作者 GitHub CSDN 2016-06-14 Linux-4.7 X86 & arm gatieme LinuxDeviceDrivers Linux内存管理 在内存管理的上下文中, 初始化(initialization)可以有多种含义. 在许多CPU上, 必须显式设置适用于Linux内核的内存模型. 例如在x86_32上需要切换到保护模式, 然后内核才能检测到可用内存和寄存器. 而我们今天要讲的boot阶段就是系统初始化阶段使用的内存分配器. 1 前景回顾 1.1

继承的初始化过程

看think in java 7.9.1继承的初始化过程的例子,并没有讲到static 代码块的初始化顺序 类在初次使用的时候才会被加载,static代码会在加载的时候初始化,所以一个类按照先加载static变量—>static 代码块->普通变量->构造器代码 的顺序进行初始化 而出现继承的时候,类的初始化顺序如下 1.父类的static 变量 2.父类的static 代码块 3.子类的static 变量 4.子类的static 代码块 5.父类的变量 6 父类的构造器 7 子类的变量