以前对压缩算法一无所知,只是知道哈弗曼编码能做这种事情,但是感觉这样的方法奇慢无比。昨天下午看了下号称世界上最快的压缩算法Quicklz,对压缩的基本思路有了一定的了解。一般的压缩程序的要求读入文件之后以便压缩一边输出,而不是去先分析整个文件中的情况之后才做决定采取哪种算法。

  Quicklz也不例外也是争取利用文件中重复出现的字节来进行压缩,管理结构如下:

在压缩的过程中不断地读入3个字节,然后根据这3个字节得到一个hash值,根据这个hash值就可以找到offset,这个offset就是上次这个hash值出现的位置,而通过cache可以判断出这次出现的和最近一次出现相同hash值的时候的3个字节是不是相同(可能hash相同而实际的值不同)。

  如果相同的长度在3到18之间,那么这些情况可以用4个位来表示。而大于18小于255的情况则需要8位来表示,刚才用于表示长度的低4为则全部变为0,以区别两种情况。在Level=1的时候就只有这两种情况了。在压缩的过程中用4个字节来记录压缩操作,如果有压缩则为1,否则为0。下面是level=1时候的情况:

  level=1的时候有个很明显的问题是只记录了一个hash相同时候的cache,这样的话只能等到与上次的值相同才能压缩,而与以前的值相同也不行。在level=2和level=3的时候弥补了这个缺陷,但是代价就是压缩的时间变长。在level=2的时候保存了4个offset(相同hash的位置),然后在这四个中取到重复字节长度最长的一个作为压缩选项(这个值保存在最低的2位中),而重复的长度信息保存在接下来的3个位中(如果够的话,不然初始化这3个位为0,在hash值后面的一个字节中保存),其他的地方就和level=1的时候相同了。压缩后文件的格式如下:

  在上面的情况中我们发现如果是3个字节相同的话只能把它压缩成2个字节。而在level=3的时候弥补了这个缺陷,在level=3的时候与前两个的不同之处是最低的两位统一作为标志,记录进行了什么操作,具体的代码如下:

if(matchlen == 3 && offset <= 63)
{
*dst = (unsigned char)(offset << 2);
dst++;
}
else if (matchlen == 3 && offset <= 16383)
{
ui32 f = (ui32)((offset << 2) | 1);
fast_write(f, dst, 2);
dst += 2;
}
else if (matchlen <= 18 && offset <= 1023)
{
ui32 f = ((matchlen - 3) << 2) | ((ui32)offset << 6) | 2;
fast_write(f, dst, 2);
dst += 2;
}
else if(matchlen <= 33)
{
ui32 f = ((matchlen - 2) << 2) | ((ui32)offset << 7) | 3;
fast_write(f, dst, 3);
dst += 3;
}
else
{
ui32 f = ((matchlen - 3) << 7) | ((ui32)offset << 15) | 3;
fast_write(f, dst, 4);
dst += 4;
}

虽然最后的两种情况的最低两位都是11,但是从下面的格式图中一眼就能看出区别(对应上面的代码看):

  这里知道了文件被压缩后保存的存储格式,下面考虑一下怎么解压。在level=3的时候解压方法还是很好理解的。但是在level=1和level=2的时候怎么解压呢?毕竟压缩文件中只是存储了hash值,而没有指出重复的字节串,甚至连offset都没有给出。这里其实很好理解,因为第一次遇到一个hash的时候当然是不会去压缩它的,那么在解压程序中我们就得到了offset的值,并且随着解压的进行,hash和offset的值与压缩时候的变化是相同的,所有不必保存这些值也能保证正确的解压。

Quicklz压缩算法的更多相关文章

  1. 【大数据之数据仓库】GreenPlum优化器对比测试

    在< [大数据之数据仓库]选型流水记>一文中有提及,当时没有测试GreenPlum的quicklz压缩算法和ORCA查询优化器,考虑到quicklz压缩算法因为版权问题不会开源(详情请参阅 ...

  2. Facebook开源Zstandard新型压缩算法代替Zlib 简单使用

    简介 Zstandard(缩写为Zstd)是由Facebook的Yann Collet开发的一个无损数据压缩算法.Zstandard在设计上与DEFLATE(.zip.gzip)算法有着差不多的压缩比 ...

  3. 速度之王 — LZ4压缩算法(一)

    LZ4 (Extremely Fast Compression algorithm) 项目:http://code.google.com/p/lz4/ 作者:Yann Collet 本文作者:zhan ...

  4. 字符串解压缩类库(zip、GZIP、QuickLz、snappy、lzf、jzlib)介绍

    1.ZIP. GZIP  计算机文件压缩算法,JDK中java.util.zip.*中实现.主要包括ZipInputStream/ ZipOutputStream.GZipInputStream/Zi ...

  5. ZIP压缩算法详细分析及解压实例解释

    最近自己实现了一个ZIP压缩数据的解压程序,觉得有必要把ZIP压缩格式进行一下详细总结,数据压缩是一门通信原理和计算机科学都会涉及到的学科,在通信原理中,一般称为信源编码,在计算机科学里,一般称为数据 ...

  6. LZ77压缩算法编码原理详解(结合图片和简单代码)

    前言 LZ77算法是无损压缩算法,由以色列人Abraham Lempel发表于1977年.LZ77是典型的基于字典的压缩算法,现在很多压缩技术都是基于LZ77.鉴于其在数据压缩领域的地位,本文将结合图 ...

  7. Java数据结构之对称矩阵的压缩算法---

    特殊矩阵 特殊矩阵是指这样一类矩阵,其中有许多值相同的元素或有许多零元素,且值相同的元素或零元素的分布有一定规律.一般采用二维数组来存储矩阵元素.但是,对于特殊矩阵,可以通过找出矩阵中所有值相同元素的 ...

  8. HBase中的压缩算法比较 GZIP、LZO、Zippy、Snappy [转]

    网址: http://www.cnblogs.com/panfeng412/archive/2012/12/24/applications-scenario-summary-of-compressio ...

  9. LZW压缩算法

    转载自http://www.cnblogs.com/jillzhang/archive/2006/11/06/551298.html 记录此处仅自己供学习之用 lzw解压缩算法: 用单个字符初始化字符 ...

随机推荐

  1. 数据结构与算法系列----AC自己主动机

    一:概念 首先简要介绍一下AC自己主动机:Aho-Corasick automation,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之中的一个.一个常见的样例就是给出n个单词,再给出一段 ...

  2. python(3)- 循环语句:从最内层跳出多层循环

    跳出多层循环:三层循环,最里层直接跳出3层 方法一: 在Python中,函数运行到return这一句就会停止,因此可以利用这一特性,将功能写成函数,终止多重循环 def work(): #定义函数 f ...

  3. error MSB8011: 未能注冊输出。请尝试启用“逐用户重定向”

    初试MFC就遇到困难了.vs2010创建一个MFC ActiveX控件项目. 什么都还没做呢,就出现故障了? 郁闷呀.! ! 1>C:\Program Files\MSBuild\Microso ...

  4. 为Redmine的项目加上起止时间

    没有时间约束的项目不是好项目. 要给项目配置起止时间,须要用到自己定义属性. 我们须要管理员身份登录.才干够定义自己定义属性. 自己定义属性 看图吧,先是点击页面导航条(最上面那排菜单,有主页.我的工 ...

  5. 微信热补丁 Tinker 的实践演进之路

    http://dev.qq.com/topic/57ad7a70eaed47bb2699e68e http://dev.qq.com/topic/57a30878ac3a1fb613dd40eb ht ...

  6. iOS之简单瀑布流的实现

    iOS之简单瀑布流的实现   前言 超简单的瀑布流实现,这里说一下笔者的思路,详细代码在这里. 实现思路 collectionView能实现各中吊炸天的布局,其精髓就在于UICollectionVie ...

  7. JAR、WAR、EAR(转载)

    转自:http://blog.csdn.net/mashengwang/article/details/6105189 区别:Jar.war.EAR.在文件结构上,三者并没有什么不同,它们都采用zip ...

  8. Struts2 (三) (转载)

    前面一直在说Action可以是一个普通的Java类,与Servlet API完全分离,但是为了实现业务逻辑,Action需要使用HttpServletRequest内容.Struts 2设计的精巧之处 ...

  9. android studio 程序真机执行中文显示乱码

    代码里中文显示正常,真机执行后中文显示乱码,解决的方法: build.gradle中加入一句 android { compileOptions.encoding = "GBK" }

  10. windows 打开文件夹

    @echo off rem 建立链接 net use \\192.168.2.3\share /user:username password rem 打开共享文件夹 explorer \\192.16 ...