本文及后面关于Lucene的文章所采用的lucene 版本为8.1.0.
1. 什么是fdx文件
fdx
文件是fdt文件的索引. 当查询到满足条件的doc Id时,如何能够快速的通过docId定位到对应的内容呢?Lucuce的做法是
- 首先加载
fdx
文件,拿到对应数据在fdt
位置 - 加载
fdt
文件获取对应的数据
fdx
文件在Lucene中对应的数据结构为CompressingStoredFieldsWriter
2. fdx文件格式
说明:
每一个Block记录128个chunk的索引信息(最后一个block中的chunk数可能少于128个), 不知道chunk结构,请参考Lucene fdt 文件格式详解
-
Chunk num in block
: block中chunk数 -
Block Doc Base
: block的Doc Id base, 实际上也就是block中第一个chunk的base -
Doc Avg size
: Doc id 平均大小 -
Doc Id
: doc id 编码值,采用IntPack编码 -
Block fdt offset base
: 该Block所对应数据在fdt的位置,即Block中第一个Chunk在fdt中的offset -
offset avg size
: offset 平均大小 -
offsets
: offsets 编码, 采用IntPack编码 -
Max position in fdt
: 最后一个Block最后一个chunk的在fdt结束位置
3. 测试代码及结果
代码请参考Lucene tim文件格式详解的第三部分
4. 范例fdx文件内容
5. fdx文件内容分析
5.1 文件头
文件头部分主要内容为标识此文件类型为Lucene50StoredFieldsFastIndex
, 源码部分在CompressingStoredFieldsWriter
的120行,主要内容如下:
-
3fd7 6c17
固定头MAGIC -
1d
为Lucene50StoredFieldsFastIndex
长度29, 其中Lucene50StoredFieldsFast
中的Fast代表data区采用Fast压缩方式,Index
这个代表是Index``文件,与
data`文件相对应 - 23个字节
Lucene50StoredFieldsFastData
-
00 0000 01
4个字节的CompressingStoredFieldsWriter.VERSION_CURRENT
- 16个字节的segmentId, 这个是随机生成的
-
00
segment suffix 长度 0 -
02
即2, 指的是PackedInts.VERSION_CURRENT
5.2 fdx data 部分
-
01
该block的chunk数 -
00
该block的docBase, 查看Lucene fdt 文件格式详解可知, 第一个chunk的docBase恰好是0 -
00
doc Id 平均大小, 当block中的总的doc数为1时,平均大小直接设置成0,否则按正常计算,请参考CompressingStoredFieldsWriter
的第118行 -
01
bitsPerDocBase -
00
bitPack 对docId 编码值
结果可以参考CompressingStoredFieldsIndexWriter
132行
该区主要分为两个部分 -
3a
第一个doc在fdt中偏移大小, 请看上图,3a
位置的值为00
, 查看Lucene fdt 文件格式详解可知,这一位置恰好是第一个chunk在fdt
文件的起始位置 -
00
平均偏移大小 -
01
bitsPerStartPointer -
00
bitPack 对offset 编码值
结果可以参考CompressingStoredFieldsIndexWriter
132行 -
00
固定值 -
70
在fdt文件中数据区的结束位置,即最后一个chunk最后一个doc的结束位置(不包括), 查看Lucene fdt 文件格式详解, 这个值恰好是是chunk data结束, chunk meta(chunk 总个数)开始
fdx
与fdt
文件映射关系如下:
5.3 footer区
footer区主要有以下内容
-
c0 2893 e8
MAGIC值,为header值的反码 -
00 0000 00
固定4个字节int 值为0 -
0000 0000 565c f3f0
8个字节的CRC码
觉得本文有帮助的话,请关注我的简书,一同进步!