在文章SegmentReader(一)中,我们介绍了SegmentReader对象,它用于描述一个段中的索引信息,并且说到SegmentReader对象中包含了一个SegmentCoreReaders对象。
图1:
图1中,蓝框标注的两个对象用于描述DocValues的索引信息,而红框标注的SegmentCoreReader则描述了下面的索引信息,注意的是在文章SegmentReader(一)中是基于Lucene 7.5.0的:
表一:
对象 | 描述 |
---|---|
StoredFieldsReader | 从索引文件fdx&&fdt中读取存储域的索引信息 |
FieldsProducer | 从索引文件tim&&tip、索引文件doc、索引文件pos&&pay中读取域的倒排信息 |
TermVectorsReader | 从索引文件tvx&&tvd读取词向量的索引信息(用于高亮优化查询) |
PointsReader | 从索引文件dim&&dii中读取域值为数值类型的索引信息 |
NormsProducer | 从索引文件nvd&&nvm中读取域的打分信息(作为对文档进行打分的参数) |
FieldInfos | 从索引文件fnm读取域的信息 |
在文章SegmentReader(一)中,并没有对每一种索引文件进行详细的读取过程的介绍,故索引文件的载入
的系列文章对此将详细的展开。
该系列文章将要介绍的内容可以概述为这么一句话:在初始化一个读取索引信息的reader期间,索引文件如何被读取(载入)。由于只是初始化一个reader,而不是处于一个查询阶段,所以只有部分索引文件的信息会被载入到内存中。
索引文件的载入顺序
在SegmentCoreReader类的构造函数中可以看出表一中对应的索引文件的载入顺序:
图2:
上文中说到,SegmentCoreReader对象是被包含在SegmentReader对象中,故在SegmentReader类的构造函数中,还可以看出DocValues对应的索引文件跟SegmentCoreReader对象中包含的索引文件的载入顺序:
图3:
从图3可以看出,在构造SegmentReader对象时,先载入SegmentCoreReader对象,即表一中包含的索引文件, 随后再载入DocValues对应的索引文件。
为什么图3中第98行处又载入了索引文件.fnm,在图2中不是已经载入过了吗?
图3跟图2中载入的索引信息是不相同的,他们的区别在于索引文件.fnm的版本不同。这两个索引文件的区别在文章构造IndexWriter对象中介绍流程点更新SegmentInfos的metaData
中详细介绍了,不赘述。
由于会依赖之前写过的跟索引文件的数据结构相关的文章,而那些文章又是依赖不同的Lucene版本,故注意版本区分。
为什么之前介绍索引文件的文章会依赖不同的版本
原因是Lucene版本迭代更新太快,索引文件的数据结构一直在优化,由于本人精力有限,无法对每一次的数据结构的优化重新写文章。
索引文件fdx&&fdt&&fdm的载入(Lucene 8.6.0)
描述存储域的索引文件fdx&&fdt&&fdm的载入顺序依次如下所示:
1 | .fdt --> .fdm --> fdx --> .fdt |
索引文件.fdt的载入
索引文件.fdt中存放了存储域的信息,载入过程中只会将部分信息读入到内存,如下所示:
图4:
图4中,红框标注的字段将会被读取到内存中。
对于Header、ChunkSize、PackedIntsVersion字段,可以从索引文件的第一个字节依次读取出这三个字段。下面是读取这三个字段的代码:
图5:
图4中的Footer字段如何读取?
由于Footer占用固定的16个字节,随后根据索引文件.fdt的总长度,那么这两者的差值就是Footer字段在索引文件.fdt中的起始读取位置。
索引文件.fdm的载入
索引文件.fdm中的内容将被全量读取到内存中,如下所示:
图6:
索引文件.fdx的载入
索引文件.fdx的Header、PackedIntsVersion、Footer先被读取到内存中:
图7:
在图6中,从索引文件.fdm中读取了NumDocsIndex、StartPointsIndex字段,这两个字段用来描述图7中的NumDocs字段在索引文件.fdx中的位置区间。同理图6中读取的StartPointsIndex、SPEndPointer用来描述图7中StartPoints字段在索引文件.fdx中的位置区间。随后将NumDocs、StartPoints这两个字段的信息读取到内存中。
所以索引文件.fdx也是全量读取到内存的。
图8:
索引文件.fdt的载入
图4中,索引文件.fdt的ChunkCount、DirtyChunkCount字段也要被读取到内存中,通过图6中从索引文件.fdm中读取的maxPointer来获取这两个字段在索引文件.fdt中的起始读取位置:
图9:
至此可以看出,对于描述存储域的索引文件fdx&&fdt&&fdm,除了索引文件.fdt的Chunk字段,其他索引文件的所有字段都会被读取到内存中。
对于索引文件fdx&&fdt&&fdm详细的读取过程可以阅读系列文章索引文件的读取(十四)之fdx&&fdt&&fdm,该系列的文章介绍了索引文件.fdt的Chunk字段的读取方式。
结语
基于篇幅,其他索引文件的载入将在后面的文章中展开。