索引文件的读取(十五)之fdx&&fdt&&fdm(Lucene 8.4.0)
Lu Xugang Lv6

  本文承接文章索引文件的读取(十四)之fdx&&fdt&&fdm,继续介绍剩余的内容。为了更好的理解下文中的内容,建议先阅读文章DirectMonotonicWriter&&Reader。下面先给出读取索引文件fdx&&fdt&&fdm的流程图。

读取索引文件fdx&&fdt&&fdm的流程图

图1:

读取一个Chunk

图2:

  当图1的流程点文档号是否在BlockState不满足条件后,需要根据文档号(段内文档号)重新找到文档号所属的chunk,大致分为四个步骤:

图3:

点击查看大图

  在介绍每个步骤之前, 我们先回顾下文章索引文件的读取(十四)之fdx&&fdt&&fdm中很重要的内容,即索引文件.fdm中的信息在生成reader阶段就已经被全量读取到内存的,而索引文件.fdx的NumDocBlock字段以及StartPointBlock字段则是off-heap方式读取。

步骤一

  执行步骤一的目的是找出一个index,该index描述的是第index个chunk,因为在文章索引文件的生成(二十四)之fdx&&fdt&&fdm我们说到,在flush阶段,每1024(2<< BlockShitf)个chunk就会生成一个NumDocsMeta,所以通过索引文件.fdm的TotalChunks得到chunk的数量以及二分法,随后通过下面的代码一判断出属于哪一个NumDocMeta,随后通过代码二判断出NumDocMeta这个block中的块内索引blockIndex

代码一:

1
(index >>> blockShift)

代码二:

1
blockIndex = index & ((1 << blockShift) - 1)

  获得了blockIndex之后,就可以根据Min、AngInc获得一个存放文档号最大跟最小的区间bounds,最后判断段内文档号是否在这个区间中,如果存在那么就进一步去索引文件.fdx中的NumDocsBlock中读取对应的NumDoc,最终获得一个index,即第index 个chunk中包含段内文档号,但是到这一步我们无法知道第index个chunk在索引文件.fdx中的起始读取位置,所以我们需要执行后面的步骤才能获得。

  如果你看阅读过文章DirectMonotonicWriter&&Reader就会知道,根据NumDocMeta中的四个编码元数据只能获得一个粗略的文档号的区间,要获得准确的文档号信息,需要去NumDocsBlock中获取(I/O操作)。

步骤二、步骤三、步骤四

  在步骤一中我们获得了段内文档号所在的chunk是第index个chunk,那么通过上文中的代码一跟代码二在步骤二中获得索引文件.fdm中的StartPointMeta以及在步骤三中获得索引文件.fdx中的StartPointBlock中的StartPoint 就可以获得一个pointer,根据该pointer执行步骤四之后就获得了索引文件.fdx中某个chunk的起始读取位置。

更新BlockState

图4:

  在上一个流程点获得一个chunk的信息后,那么读取该chunk中的内容用于更新BlockState。读取的过程就是将索引文件.fdx中chunk中的内容写入到内存中。

结语

  从上文中的介绍可以看出,当随机读取某个文档中的存储域信息时,会导致频繁的读取一个Chunk的值,意味着更多的I/O操作,所以顺序读取才能保证性能最大化。

点击下载附件

 Comments