如今开启lucene倒排索引之词的索引存储之旅也就是对BlockTreeTermsWriter类分析,这是lucene中难啃的骨头之一,为了方便记忆和理解,还有保持内容的跟进,先准备对着代码一步步描述,而前面全部关于lucene的内容都是看完代码再总结的,所以能够想象这块内容的复杂度。post
当写入一个词的时候会先写入该词的posting,而后将再写入返回的posting状态信息和词自己。posting的写入过程在谈谈lucene倒排索引的存储方式(一)和(二)中已经说明。.net
假设minItemsInBlock=3,根据下面的代码blog
当输入abc时:索引
prefixStarts=[0,0,0] pendingSize=1;get
当输入abcd时:it
prefixStarts=[0,0,0,1] pendingSize=2;效率
当输入abcde时:lucene
prefixStarts=[0,0,0,1,2] pendingSize=3;方法
当输入abe时:im
prefixStarts 从理应的[0, 0, 3, 1, 2]变成[0, 0, 1, 1, 2] pendingSize=4;
若是只看输入abe时prefixStarts=[0, 0, 3, 1, 2],从输入abc时prefixStarts的变化状况,结合prefixTopSize能够看出prefixStarts下标记录的是公共前缀的长度,值记录的是pending列表中元素的id,经过pending.size–id能够求得公共长度prefixTopSize的长度。例如当输入abe时,从上一个词abcde的最后一个e开始扫描,计算abc、abcd、abcde中与abcde有公共前缀的词的个数为1,而后从d开始计算abc、abcd、abcde与abcd有公共前缀的词的个数为2,以此类推计算abc、abcd、abcde与abc有公共前缀的词个数为3正好达到minItemsInBlock的阈值,因此最终结论是每次写入一个新词时,当已有词列表最长公共前缀达到给定阈值时会写入到一个block中(这里还没具体看代码分析可是从writeBlocks方法能够看出来),为何是最长公共前缀呢由于在输入abe前以a和ab为前缀的词一样有3个,这样压缩效率没有以abc为前缀的高。下篇分析writeBlocks方法。