在前面的文章中,我们介绍了在 Lucene7.5.0 中 索引文件.dim&&.dii 的数据结构,从本篇文章开始介绍其生成索引文件。dim&&.dii 的内容,注意的是,由于是基于 Lucene8.4.0 来描述其生成过程,故如果出现跟 Lucene7.5.0 中不一致的地方会另外指出,最后建议先阅读下文章 Bkd-Tree 简单的了解下 Lucene 中点数据的使用。

  在文章 索引文件的生成(一)之 doc&&pay&&pos 中,简单的介绍了生成索引文件。dim&&.dii 的时机点,为了能更好的理解其生成过程,会首先介绍下在生成索引文件之前,Lucene 是如何收集每篇文档的点数据信息(Point Value),随后在 flush 阶段,会根据收集到的信息生成索引文件。dim&&.dii。

收集文档的点数据信息

  在源码中,通过 PointValuesWriter 对象来实现文档的点数据的收集,并且具有相同域名的点数据使用同一个 PointValuesWriter 对象来收集,例如下图中添加三篇文档:

图 1:

  在图 1 中,由于第 49 行、50 行、55 行。60 行、61 行,添加了具有相同的域名“content”的点数据,故他们三个的点数据信息会使用同一个 PointValuesWriter 对象来收集,同理第 51 行、56 行。

  PointValuesWriter 对象收集的内容主要包括以下信息:

numPoints:

  int 类型,numPoints 是一个从 0 开始递增的值,可以理解为是每一个点数据的一个唯一编号,并且通过这个编号能映射出该点数据属于哪一个文档(document)(下面会介绍),由于是每一个点数据的唯一编号,所以该值还可以用来统计某个域的点数据的个数,在图 1 中,域名为"content"的点数据共有 5 个,那么这么 5 个点数据的 numPoints 的值分别为 0、1、2、3、4。

docIDs

  int 类型数组,每添加一条点数据,会将该点数据所属文档号作为数组元素添加到 docIDs 数组中 ,并且数组下标为该点数据对应的 numPoints,对于域名为"content"的点数据,在完成三篇文档的添加后,docIds 数组如下所示:

图 2:

numDocs

  该值描述的是对于某个点数据域,包含它的文档数量,例如在图 1 中,域名为"content"的点数据,包含该域的文档有文档 0、文档 1、文档 2,故 numDocs 的值为 3,同理对于域名为"titile"的点数据,numDocs 的值为 1。

bytes

  该值是 ByteBlockPool 类型,ByteBlockPool 为 Lucene 中的类,在这里我们只需要知道,在这个类中使用了 buff(byte[ ]数组)来存储点数据的域值,在 Lucene 中,数值类型的域值需要通过转化为字节类型来存储,故我们先介绍下在 Lucene 中数值类型到字节类型的转化实现。

数值类型到字节类型(无符号)的转化

  Lucene 中的提供了 BigInteger、int、long、float、double 到字节类型 byte 的转化,在 NumericUtils 类中有具体的实现,本文通过例子只介绍下 int 类型到 byte 类型的转化。

  待转化的数值为 3,过程分为两个步骤:

步骤一:将待转化的数值跟 0x80000000 执行异或操作

为什么要执行异或操作

  • 等介绍完步骤二再做解释
步骤二:写入到数组大小为 4 的字节数组中

  由于 int 类型的数�