LZ4壓縮算法是LZ算法系列中的一種,並且網上也號稱是目前最快的壓縮算法之一,現沒時間親測也不對LZ系列算法展開討論只分析LZ4。LZ4算法有兩種壓縮方法,一種側重於壓縮速度,另外一種側重於壓縮比,現討論的是側重於壓縮速度的方法。算法
現給定字符串dfabcdefghijklmnabcdkkkkkk,後面出現的「abcd」能夠用前面的「abcd」經過偏移量offset與匹配長度matchLength進行代替,實際上這就是LZ4算法的主要思想。LZ4算法的最小匹配長度是4,最後5個字符按照字面量存儲,也就是說當字節數<=9時是不壓縮的(最後會給出解釋)。測試
詳細的LZ4編碼數據涉及到的變量以下:優化
一、字面量值literalValue,即dfabcdefghijklmn編碼
二、字面量值長度literalLength=16token
三、匹配長度matchLength=4字符串
四、偏移量offset=16-2=14源碼
編碼格式以下:it
token_literalLength(可選)_literalValue_offset_matchLength(可選)變量
token佔用1個字節,前4位表明字面量值長度,若是長度值>=15與255(1個字節的無符號數)進行比較,若是比255大則減去255並寫入1個字節,將剩餘的值如此循環比較,反之直接寫入1個字節。如字面量長度值爲512,token前4位等於15, literalLength等於512-15=255+242佔用兩個字節。後四位表示匹配的長度,原理和前面同樣,在實現的時候能夠優化一下,由於默認最小匹配長度爲4,因此能夠將值減4。如匹配長度爲512,token後4位等於15,matchLength等於512-4-15=255+238佔用兩個字節。literalLength與matchLength爲何要加入可選,就是這個緣由,由於值小於15的時候,4個比特位已經足夠表示了。offset佔用2個字節,即最大值爲65535。原理
上面的字符串壓縮後的字節序列是(0b11110000)_(1)_(dfabcdefghijklmn)_(14)------(0b01100000)_(kkkkkk)
問題一:爲何最小匹配值爲4?
我我的的理解是由於token佔1個字節、offset佔2個字節,只有匹配值大於3的時候纔有可能起到壓縮效果。注:爲何是「有可能」呢,由於壓縮算法是基於機率的,好比上面的例子並無起到壓縮效果,反而多佔一個字節。
問題二:爲何最後的5個字節按照字面量直接存儲?
我我的的理解是假設給定9個字節的字符串abcdabcde,按照正常流程壓縮時格式以下:(0b01000000)_(abcd)_(4)------(0b00010000)_(e),一樣佔了9個字節,沒有起到壓縮效果。注意(4)是佔2個字節的。
有興趣的能夠對着lucene的LZ4源碼,照着上面的例子驗證一下,本人已經測試過了。