如今開啓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方法。