当 STORE.YES 的域生成了倒排表以后,将文档的域值信息写入到。fdt(field data)、.fdx(field index)文件中。
数据结构
.fdt
图 1:
ChunkSize
ChunkSize 用来描述压缩存储域值信息的方式,后面会详细介绍。
PackedIntsVersion
PackedIntsVersion 描述了压缩使用的方式,当前版本中是 VERSION_MONOTONIC_WITHOUT_ZIGZAG。
Chunk
图 2:
生成一个 chunk 的条件是 文档个数达到 128 或者 所有文档的域值信息的总长度 达到 ChunkSize。
DocBase
当前 chunk 中第一个文档的文档号,因为根据这个文档号来差值存储,在读取的阶段需要根据该值恢复其他文档号。
ChunkDocs
图 3:
ChunkDocs 是一个 numBufferedDocs 跟 slicedBit 的组合值。ChunkDocs = (numBufferedDocs |slicedBit )。
numBufferedDocs
numBufferedDocs 描述了当前 chunk 中的文档数量。numBufferedDocs 是一个 ≤ 128 的值。
slicedBit
如果待处理的域值信息的长度超过 2 倍的 chunkSize(默认值 16384),那么需要分块压缩,下文会具体介绍。
DocFieldCounts
根据 chunk 中包含的文档个数 numBufferedDocs、每篇文档包含的存储域的个数 numStoredFields 分为不同的情况。
numBufferedDocs 的个数为 1
图 4:
numBufferedDocs 的个数 > 1 并且每篇文档中的 numStoredFields 都是相同的
图 5:
只要存储一个 numStoredFields 的值就行啦。
numBufferedDocs 的个数 > 1 并且每篇文档中的 numStoredFields 不都相同的
图 6:
使用 PackedInt 来存储所有的 numStoredFields,这里不赘述了,点击这里可以看其中的一种压缩方式。
DocLengths
同 DocFieldCounts 类似,据 chunk 中包含的文档个数 numBufferedDocs、每篇文档中域值信息的长度分为不同的情况。
numBufferedDocs 的个数为 1
图 7:
numBufferedDocs 的个数 > 1 并且每篇文档中的域值信息长度都是相同的
图 8:
numBufferedDocs 的个数 > 1 并且每篇文档中的域值信息长度不都是相同的
图 9:
- 本文地址:Lucene 源码系列——fdx fdt 索引文件
- 本文版权归作者和AIQ共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出
使用 PackedInt 来存储所有的域值信息长度,这里不赘述了,点击这里可以看其中的一种压缩方式。
CompressedDocs
图 10:
CompressedDocs 中使用 LZ4 算法将域值信息压缩存储。域值信息包含如下内容:
- Doc 的个数为 chunk 中包含的文档个数
- 域的编号
- 域值的类型:String、BinaryValue、Int、Float、Long、Double
- 域值的编号跟域值的类型组合存储为 FieldNumAndType
- Value:域值
DirtyChunkCount
chunk 的个数。
.fdt 整体数据结构
图 11:
上图中是其中一种 .fdt 文件数据结构。
图 12:
Block
图 13:
在。fdt 中,每当 chunk 的个数达到 1024(blockSzie),在。fdx 文件中就会生成一个 block,block 中的信息作为索引来映射。fdt 中的数据区间。
BlockChunks
block 中包含的 chunk 的个数,即 1024 个。
DocBases
图 14:
DocBases 中描述了文档号的信息。
DocBase
block 中第一个文档的文档号。用来在读取阶段,恢复所有 chunk 中其他被编码的文档号。
AvgChunkDocs
AvgChunkDocs 描述了 block 中平均一个 chunk 中包含的文档数。
BitsPerDocBaseDelta
BitsPerDocBaseDelta 描述了存储文档号的需要固定 bit 个数。
DocBaseDeltas
一个 block 中用 docBaseDeltas[]数组来存放每个 chunk 中的文档个数,而每一个 chunk 中的文档个数是不一样的,出于最大化优化空间存储,不直接对文档数量值进行存储,而是存储差值 docDelta。又因为 docBaseDeltas[]数组又不能保证数组元素递增,所以不能使用相邻数组元素的差值来作为 docDelta,Lucene 提供的方法就是计算 docBaseDeltas[]中数组元素平均值 avgChunkDocs,对每一个数组元素存储一个 docDelta 的值,docDelta 的计算公式为:docDelta = ( docBase - avgChunkDocs * i), 其中 i 为数组的下标值,docBase 是下标值为 i 的数组元素前所有的数组元素之和,然后对所有 docDelta 使用 PackedInts 进行压缩编码,即 DocBaseDeltas。
StartPointers
图 15:
StartPointers 中描述了。fdt 文件中每一个 chunk 的索引映射信息。
StartPointerBase
当前 block 中第一个 chunk 的索引值。
AvgChunkSize
block 中平均每一个 chunk 的大小。
BitsPerStartPointerDelta
存储每一个 chunk 大小需要固定 bit 个数。
StartPointerDeltas
逻辑跟 DocBaseDeltas 一样,不赘述。
.fdx 整体数据结构
图 16:
注意:本文归作者所有,未经作者允许,不得转载