复合索引文件格式cfs
复合索引文件格式(.cfs)是如何产生的?从这个问题出发,研究索引文件是如何合并的,这都是IndexWriter类中定义的一些重要的方法。
在建立索引过程中,生成的索引文件的格式有很多种。
在文章 Lucene-2.2.0 源代码阅读学习(4) 中测试的那个例子,没有对IndexWriter进行任何的客户化设置,完全使用Lucene 2.2.0默认的设置(以及,对Field的设置使用了Lucene自带的Demo中的设置)。
运行程序以后,在本地磁盘的索引目录中生成了一些.扩展名为.cfs的索引文件,即复合索引格式文件。如图(该图在文章 Lucene-2.2.0 源代码阅读学习(4) 中介绍过)所示:
从上面生成的那些.cfs复合索引文件可以看出,Lucene 2.2.0版本,IndexWriter索引的一个成员useCompoundFile的设置起了作用,可以在IndexWriter类的内部看到定义和默认设置:
private boolean useCompoundFile = true;
即,默认使用复合索引文件格式来存储索引文件。
在IndexWriter类的addDocument(Document doc, Analyzer analyzer)方法中可以看到,最后调用了 maybeFlushRamSegments()方法,这个方法的作用可是很大的,看它的定义:
protected final void maybeFlushRamSegments() throws CorruptIndexException, IOException {
if (ramSegmentInfos.size() >= minMergeDocs || numBufferedDeleteTerms >= maxBufferedDeleteTerms) {
flushRamSegments();
}
}
这里,minMergeDocs是指:决定了合并索引段文件时指定的最小的Document的数量,在IndexWriter类中默认值为10,可以在IndexWriter类中查看到:
private int minMergeDocs = DEFAULT_MAX_BUFFERED_DOCS;
public final static int DEFAULT_MAX_BUFFERED_DOCS = 10;
其中SegmentInfos ramSegmentInfos中保存了Document的数量的信息,如果Document的数量小于10,则调用flushRamSegments()方法进行处理,flushRamSegments()方法的定义如下所示:
private final synchronized void flushRamSegments() throws CorruptIndexException, IOException {
flushRamSegments(true);
}
在flushRamSegments()方法中又调用到了该方法的一个重载的方法,带一个boolean型参数。该重载的方法定义如下:
protected final synchronized void flushRamSegments(boolean triggerMerge)
throws CorruptIndexException, IOException {
if (ramSegmentInfos.size() > 0 || bufferedDeleteTerms.size() > 0) {
mergeSegments(ramSegmentInfos, 0, ramSegmentInfos.size());
if (triggerMerge) maybeMergeSegments(minMergeDocs);
}
}
同样,如果Document的数量小于10,则调用mergeSegments()方法,先看一下该方法的参数:
private final int mergeSegments(SegmentInfos sourceSegments, int minSegment, int end)
第一个参数指定了一个SegmentInfos(上面调用传递了ramSegmentInfos) ;第二个参数是minSegment是最小的索引段数量(上面调用传递了0,说明如果存在>=0个索引段文件时就开始合并索引文件);第三个参数是end,指要合并索引段文件的个数(上面调用传递了ramSegmentInfos.size(),即对所有的索引段文件都执行合并操作)。
继续看mergeSegments()方法的实现:
private final int mergeSegments(SegmentInfos sourceSegments, int minSegment, int end)
throws CorruptIndexException, IOException {
// doMerge决定了是否执行合并操作,根据end的值,如果end为0说明要合并的索引段文件为0个,即不需要合并,doMerge=false
boole