1. 程式人生 > >談談lucene倒排索引的儲存方式(3-1)

談談lucene倒排索引的儲存方式(3-1)

現在開啟lucene倒排索引之詞的索引儲存之旅也就是對BlockTreeTermsWriter類分析,這是lucene中難啃的骨頭之一,為了方便記憶和理解,還有保持內容的跟進,先準備對著程式碼一步步描述,而前面所有關於lucene的內容都是看完程式碼再總結的,因此可以想象這塊內容的複雜度。

當寫入一個詞的時候會先寫入該詞的posting,然後將再寫入返回的posting狀態資訊和詞本身。posting的寫入過程在談談lucene倒排索引的儲存方式(一)和(二)中已經說明。

假設minItemsInBlock=3,根據下面的程式碼

當輸入abc時:

   prefixStarts=[0,0,0]        pendingSize=1;

當輸入abcd時:

   prefixStarts=[0,0,0,1]        pendingSize=2;

當輸入abcde時:

   prefixStarts=[0,0,0,1,2]        pendingSize=3;

當輸入abe時:

    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為字首的高。下篇分