談談lucene倒排索引的儲存方式(3-3)
當輸入abe時由於abcd、abcde、abcdef、abcdf、abcdg以abcd為字首的個數為5個已經超過MIN_BLOCK_SIZE個數,因此達到寫成一個Block的條件,由於MAX_BLOCK_SIZE=4所以對這5個item需要進一步按照MIN_BLOCK_SIZE3個為一組進行拆分,即abcd、abcde、abcdef會寫到一個Block(該Block也是一個leafBlock,因為它的元素只有詞)中,除了字首abcd,其餘的字尾以及postings元資料(經過壓縮)會全部寫入到termsOut檔案流中,對於該Block有以下重要屬性prefix, startFP, hasTerms, isFloor, floorLeadLabel, subIndices,其中prefix表示公共字首即abcd,startFP表示termsOut檔案流指標(通過該指標可以從tim檔案中解析出該Block中每個詞的資訊),hasTerms表示該塊是否包含詞(很明顯該Block中全部都是詞),isFloor為True表示該塊由於超過MAX_BLOCK_SIZE個數進行了進一步分塊,floorLeadLabel該塊中第一個詞的第prefixLen個字元(該塊為-1),subIndices表示子塊的索引(該塊沒有子塊)。然後abcdf與abcdg會同樣寫入到一個新塊中,不過此時prefix記錄的是abcdf,floorLeadLabel記錄的是f。寫完這兩個塊就得想辦法如何能定位這兩個Block了:首先這兩個塊的Floor都為True,先寫入第一個塊的fp、hasTerm標記和isFloor,再寫入剩餘Block的個數對每個Block寫入floorLeadLabel(主要用於查詢某個詞時可以預判,如果不存在就無需載入該塊下所有的詞),這些資訊最終會轉換成位元組陣列並且和字首abcd一起寫入FST中,該FST是儲存在第一個Block中的
繼續新增abf、abg、abh,此時pending列表中有6個entry,其中5個term,1個block。最後需將這6個entry按照MIN_BLOCK_SIZE和MAX_BLOCK_SIZE設定的閾值繼續分塊:首先term:abc、block:abcd、term:abe會組成一個新的Block,其中在寫入block:abcd時記錄的是block的檔案指標,