最近遇到一个需求,需要使用LZ4的流式压缩来减少流量开销。笔者也是第一次接触LZ4算法,但速度之王的名声早已如雷贯耳。需求本身要求我使用go语言来编写一套LZ4压缩工具库,因为github上的go语言版本是残废的(它不支持流式压缩),而CGO又会带来很多额外的开销(C栈和go栈的内存分布差距很大,有着很大的上下文切换开销),于是我受命编写纯go版本的LZ4压缩工具库。
压缩的通用原理就是,假如当前位置的一个字符串序列,在以前的历史数据中也出现过,那么现在用一种特殊的格式或者特殊的小序列来表示它,就可以起到压缩的效果,因为特殊格式或者特殊小序列通常都是比原本的字符串序列更小的。
先把LZ4的压缩实现抛在一边,LZ4是一种压缩算法,它的实现可以变幻莫测,只要可以生成合乎规范的压缩数据即可。LZ4算法最重要,也是最容易出错的地方,也就是它的格式了。下面,先来看一下LZ4的格式:
Sequence:它是LZ4最小的数据单元,格式如下:
Token(1字节) |
字面序列长度(0~n字节) |
字面序列序列 |
Offset (2字节) |
|