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

            經過談談lucene倒排索引的存儲方式(3-2)談談lucene倒排索引的存儲方式(3-1)的分析可知,當有公共前綴的詞的數量達到指定閾值時會寫入到一個Block中,不過尚未對其中的細節進行分析,現經過給定的輸入abc、abcd、abcde、abcdef、abcdf、abcdg、abe、abf、abg、abh,以及參數閾值MIN_BLOCK_SIZE = 3和MAX_BLOCK_SIZE = 4來對倒排索引的構成進一步研究。數組

            當輸入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中的,最後將pending列表中的abcd、abcde、abcdef、abcdf、abcdg替換成該Block,因而pending列表中的元素爲pendingTerm:abc、pendingBlock:abcd以及新增的pendingTerm:abe。多線程

           繼續添加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的文件指針,而後term:abf、abg、abh也會造成一個新的Block,最後這兩個新的Block會按照前面所述的方式一塊兒寫入FST中並保存在第一個Block中。至此倒排索引的存儲方式算是分析結束了,其實lucene的倒排索引的邏輯視圖仍是樹狀的(最終會以FST的形式保存索引數據因爲FST能夠共享後綴因此FST是個圖,可是它也能夠認爲是對樹的一種優化,咱們能夠認爲FST是一種共享後綴的前綴樹),早期實現的跳躍鏈表也是樹狀的,而關係庫中經常使用的B樹也是樹狀的,它們在查詢的效率以及讀寫的實時性上有必定的差別性,之後對這三種形式的樹進行仔細的分析。後面仍是着重對lucene的索引合併、多線程寫入、實時性以及事務性方面進行分析!post

相關文章
相關標籤/搜索