以前对压缩算法一无所知,只是知道哈弗曼编码能做这种事情,但是感觉这样的方法奇慢无比。昨天下午看了下号称世界上最快的压缩算法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. nload 命令

    网卡 流量监控命令 // 安装 yum intall nload nload 上下page 键 切换网卡查看

  2. android实例讲解----Tomcat部署Web应用方法总结

      参考文档:http://blog.csdn.net/yangxueyong/article/details/6130065  Tomcat部署Web应用方法总结             一.架构介 ...

  3. Cent OS下发送邮件

    首先安装发送邮件的服务: yum install -y sendmail 安装完成之后在安装mutt yum install -y mutt 安装完成之后我们就可以发送邮件了 mutt     tes ...

  4. windows下redis安装以及简单配置

    1.下载redis 下载地址https://github.com/dmajkic/redis/downloads.有32bit和64bit根据自己需要选择就可以了. 2.安装redis 首先使用cmd ...

  5. Android Volley分析(一)——结构

    Volley是Android系统下的一个网络通信库.为Android提供简单高速的网络操作(Volley:Esay, Fast Networking for Android),以下是它的结构: 既然是 ...

  6. Java EJB JBoss

    JBoss:JBoss是web服务器的一种,主要做EJB容器,和tomcat集成就可以jsp,servlet,ejb通吃了JBoss有两种版本,一种是独立的,一种是和tomcat集成的,当然都是免费的 ...

  7. poj 3233 Matrix Power Series(矩阵二分,高速幂)

    Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 15739   Accepted:  ...

  8. LeetCode:判断最长前缀

    之前一直忽略了一个问题就是:给定的空字符串数组 char* longestCommonPrefix(char** strs, int strsSize) { char* result; if(strs ...

  9. NTAG 标签

    NTAG 标签 这里描述针对 NTAG213.而 NTAG215/216只是容量不同,其它功能都一样.  UID UID 有 7 bytes.上图中有 9 bytes 的 serial number ...

  10. JavaScript根据Json数据来做的模糊查询功能

    类似于百度搜索框的模糊查找功能 需要有有已知数据,实现搜索框输入字符,然后Js进行匹配,然后可以通过鼠标点击显示的内容,把内容显示在搜索框中 当然了,正则只是很简单的字符匹配,不具备多么复杂的判断 & ...