DocValues 查找
举个例子,构造如下场景(代码:https://github.com/debuger6/lucene/blob/branch-v9.5.0/lucene/demo/src/java/org/apache/lucene/own/demo/docvalue/NumericDocValuesFieldDemo.java#L76):
共10个 block,block0 不存文档号,缺失。后面 9 个 block,每个 block 的第 20000 个文档号缺失,因此,每个 block 的文档数为 65535,那么 IndexedDISI 的结构大致如下:

这里以最复杂的情况即稠密度为 dense 举例,假设查找文档号 3 * (1 « 16) + 65530 ,即查找第 3 个 block 中第 65530 个文档,那么步骤如下:
找到 target 所属的 block3
通过 JumpTable 找到 block3 对应的 index (第一个有效文档号的段内偏移,即 131070)
通过 JumpTable 找到 block3 对应的 offset (dvd 文件偏移)
定位到 block3
读取 block3 头部,根据 block id 计算 block 第一个文档号(block_id « 16)
读取 block 头部,获取 ranks
定位到 target 所在的 word(target word)
通过 ranks 加速统计 block 内当前 word 到 target word 的文档数
根据下面代码可以判断 target 是否存在以及算出 target 的段内偏移
long leftBits = disi.word >>> target; // 此时 word 为 target word,最低位的 bit 表示 target 是否存在 disi.index = disi.numberOfOnes - Long.bitCount(leftBits); // 计算 target doc 的段内偏移 return (leftBits & 1L) != 0; // 最低位为 1 说明 target doc 存在
上面通过 IndexDISI 找到了 target 在段内的偏移 disi.index(当然,如果文档不存在,下面的步骤就不用做了),