本文的代码以lucene-core 6.3.0为准,包含CompressingStoredFieldsWriter具体实现。转载请注明出处。
0 - 基本信息
CompressingStoredFieldsWriter
类是Lucene将每个Document的所有Field写入文件的具体实现类,在DefaultIndexingChain类中被调用,调用顺序是startDocument
-> writeField
-> finishDocument
,过程比较简单。
通过构造函数中可以了解到,Document需要存两部分数据,.fdt中存的是Document的每个Field的数据,.fdx存的是Document的索引数据。这里需要了解到的一个背景是,.fdx文件中,将16K(1 << 14)大小的或者数量为128的Document组成一个chunk
,每个chunk
是用LZ4函数压缩存储的。在整个.fdx中快速定位一个文档,需要先定位到文档的chunk
位置,然后解压缩这个chunk
的数据,最后找到文档在chunk
中的位置才能找到文档的所有数据。
在构造函数中fieldsStream
和indexWriter
分别可以写入.fdt和.fdx文件,了解背景,再看源码相对比较简单。
1 - CompressingStoredFieldsWriter 源码分析
writeField
函数实现了将一个Field的内容写入到内存中。
public void writeField(FieldInfo info, IndexableField field)
throws IOException {
++numStoredFieldsInDoc;
int bits = 0;
final BytesRef bytes;
final String string;
// 判断Field的类型,数字,字符串或者二进制,并计算长度
Number number = field.numericValue();
if (number != null) {
if (number instanceof Byte || number instanceof Short || number instanceof Integer) {
bits = NUMERIC_INT;
} else if (number instanceof Long) {
bits = NUMERIC_LONG;
} else if (number instanceof Float) {
bits = NUMERIC_FLOAT;
} else if (number instanceof Double) {
bits = NUMERIC_DOUBLE;
} else {
throw new IllegalArgumentException("cannot store numeric type " + number.getClass