Apple的LZF算法解析
有关LZF算法的相关解析文档比较少,但是Apple对LZF的开源,可以让我们对该算法进行一个简单的解析。LZFSE 基于 Lempel-Ziv ,并使用了有限状态熵编码。LZF采用类似lz77和lzss的混合编码。使用3种“起始标记”来代表每段输出的数据串。
接下来看一下开源的LZF算法的实现源码。
1.定义的全局字段:
private readonly long[] _hashTable = new long[Hsize]; private const uint Hlog = ; private const uint Hsize = ( << ); private const uint MaxLit = ( << ); private const uint MaxOff = ( << ); private const uint MaxRef = (( << ) + ( << ));
2.使用LibLZF算法压缩数据:
/// <summary>
/// 使用LibLZF算法压缩数据
/// </summary>
/// <param name="input">需要压缩的数据</param>
/// <param name="inputLength">要压缩的数据的长度</param>
/// <param name="output">引用将包含压缩数据的缓冲区</param>
/// <param name="outputLength">压缩缓冲区的长度(应大于输入缓冲区)</param>
/// <returns>输出缓冲区中压缩归档的大小</returns>
public int Compress(byte[] input, int inputLength, byte[] output, int outputLength)
{
Array.Clear(_hashTable, , (int)Hsize);
uint iidx = ;
uint oidx = ;
var hval = (uint)(((input[iidx]) << ) | input[iidx + ]);
var lit = ;
for (; ; )
{
if (iidx < inputLength - )
{
hval = (hval << ) | input[iidx + ];
long hslot = ((hval ^ (hval << )) >> (int)((( * - Hlog)) - hval * ) & (Hsize - ));
var reference = _hashTable[hslot];
_hashTable[hslot] = iidx;
long off;
if ((off = iidx - reference - ) < MaxOff
&& iidx + < inputLength
&& reference >
&& input[reference + ] == input[iidx + ]
&& input[reference + ] == input[iidx + ]
&& input[reference + ] == input[iidx + ]
)
{
uint len = ;
var maxlen = (uint)inputLength - iidx - len;
maxlen = maxlen > MaxRef ? MaxRef : maxlen;
if (oidx + lit + + >= outputLength)
return ;
do
len++;
while (len < maxlen && input[reference + len] == input[iidx + len]);
if (lit != )
{
output[oidx++] = (byte)(lit - );
lit = -lit;
do
output[oidx++] = input[iidx + lit];
while ((++lit) != );
}
len -= ;
iidx++;
if (len < )
{
output[oidx++] = (byte)((off >> ) + (len << ));
}
else
{
output[oidx++] = (byte)((off >> ) + ( << ));
output[oidx++] = (byte)(len - );
}
output[oidx++] = (byte)off;
iidx += len - ;
hval = (uint)(((input[iidx]) << ) | input[iidx + ]);
hval = (hval << ) | input[iidx + ];
_hashTable[((hval ^ (hval << )) >> (int)((( * - Hlog)) - hval * ) & (Hsize - ))] = iidx;
iidx++;
hval = (hval << ) | input[iidx + ];
_hashTable[((hval ^ (hval << )) >> (int)((( * - Hlog)) - hval * ) & (Hsize - ))] = iidx;
iidx++;
continue;
}
}
else if (iidx == inputLength)
break;
lit++;
iidx++;
if (lit != MaxLit) continue;
if (oidx + + MaxLit >= outputLength)
return ; output[oidx++] = (byte)(MaxLit - );
lit = -lit;
do
output[oidx++] = input[iidx + lit];
while ((++lit) != );
}
if (lit == ) return (int)oidx;
if (oidx + lit + >= outputLength)
return ;
output[oidx++] = (byte)(lit - );
lit = -lit;
do
output[oidx++] = input[iidx + lit];
while ((++lit) != ); return (int)oidx;
}
3.
/// <summary>
/// 使用LibLZF算法解压缩数据
/// </summary>
/// <param name="input">参考数据进行解压缩</param>
/// <param name="inputLength">要解压缩的数据的长度</param>
/// <param name="output">引用包含解压缩数据的缓冲区</param>
/// <param name="outputLength">输出缓冲区中压缩归档的大小</param>
/// <returns>返回解压缩大小</returns>
public int Decompress(byte[] input, int inputLength, byte[] output, int outputLength)
{
uint iidx = ;
uint oidx = ;
do
{
uint ctrl = input[iidx++]; if (ctrl < ( << ))
{
ctrl++; if (oidx + ctrl > outputLength)
{
return ;
} do
output[oidx++] = input[iidx++];
while ((--ctrl) != );
}
else
{
var len = ctrl >> ;
var reference = (int)(oidx - ((ctrl & 0x1f) << ) - );
if (len == )
len += input[iidx++];
reference -= input[iidx++];
if (oidx + len + > outputLength)
{
return ;
}
if (reference < )
{
return ;
}
output[oidx++] = output[reference++];
output[oidx++] = output[reference++];
do
output[oidx++] = output[reference++];
while ((--len) != );
}
}
while (iidx < inputLength); return (int)oidx;
}
以上是LZF算法的代码。
Apple的LZF算法解析的更多相关文章
- 地理围栏算法解析(Geo-fencing)
地理围栏算法解析 http://www.cnblogs.com/LBSer/p/4471742.html 地理围栏(Geo-fencing)是LBS的一种应用,就是用一个虚拟的栅栏围出一个虚拟地理边界 ...
- KMP串匹配算法解析与优化
朴素串匹配算法说明 串匹配算法最常用的情形是从一篇文档中查找指定文本.需要查找的文本叫做模式串,需要从中查找模式串的串暂且叫做查找串吧. 为了更好理解KMP算法,我们先这样看待一下朴素匹配算法吧.朴素 ...
- Peterson算法与Dekker算法解析
进来Bear正在学习巩固并行的基础知识,所以写下这篇基础的有关并行算法的文章. 在讲述两个算法之前,需要明确一些概念性的问题, Race Condition(竞争条件),Situations lik ...
- python常见排序算法解析
python——常见排序算法解析 算法是程序员的灵魂. 下面的博文是我整理的感觉还不错的算法实现 原理的理解是最重要的,我会常回来看看,并坚持每天刷leetcode 本篇主要实现九(八)大排序算法 ...
- Java虚拟机对象存活标记及垃圾收集算法解析
一.对象存活标记 1. 引用计数算法 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器就加1:当引用失效时,计数器就减1:任何时刻计数器都为0的对象就是不可能再被使用的. 引用计数算法(Re ...
- JVM垃圾回收算法解析
JVM垃圾回收算法解析 标记-清除算法 该算法为最基础的算法.它分为标记和清除两个阶段,首先标记出需要回收的对象,在标记结束后,统一回收.该算法存在两个问题:一是效率问题,标记和清除过程效率都不太高, ...
- DeepFM算法解析及Python实现
1. DeepFM算法的提出 由于DeepFM算法有效的结合了因子分解机与神经网络在特征学习中的优点:同时提取到低阶组合特征与高阶组合特征,所以越来越被广泛使用. 在DeepFM中,FM算法负责对一阶 ...
- GBDT+LR算法解析及Python实现
1. GBDT + LR 是什么 本质上GBDT+LR是一种具有stacking思想的二分类器模型,所以可以用来解决二分类问题.这个方法出自于Facebook 2014年的论文 Practical L ...
- 最长上升子序列(LIS)n2 nlogn算法解析
题目描述 给定一个数列,包含N个整数,求这个序列的最长上升子序列. 例如 2 5 3 4 1 7 6 最长上升子序列为 4. 1.O(n2)算法解析 看到这个题,大家的直觉肯定都是要用动态规划来做,那 ...
随机推荐
- 关于DOM的一些笔记(一)
这篇文章整理的是关于DOM的一些学习笔记,这样以后查找起来也方便许多.(以前js看的是入门经典和DOM编程艺术,现在在看高级程序设计,本文就以高级程序为主整理) 1.Node (1):类型 node. ...
- 如何在Windows7上完全卸载Oracle 11g(转)
http://blog.csdn.net/haishu_zheng/article/details/19180081
- Amoeba -- 阿里巴巴工程师的开源项目之一陈思儒
http://www.kuqin.com/opensource/20081023/24026.html 个人博客 http://dbanotes.net/web/page/44 阿里巴巴分布式服务框架 ...
- ASP.NET Core 十种方式扩展你的 Views
原文地址:http://asp.net-hacker.rocks/2016/02/18/extending-razor-views.html 作者:Jürgen Gutsch 翻译:杨晓东(Savor ...
- 框架设计之ADO.NET Command的ExecuteScalar误用情景及底层解说
最近下载了点资料,学了学Android,发现Android入门还算简单,从.NET过渡到Android,也就三七十一天的事. 大伙有空也可以学学... 好了,言归正文,那日,有网友发了一个他们公司的数 ...
- Nodejs之MEAN栈开发(三)---- 使用Mongoose创建模型及API
继续开扒我们的MEAN栈开发之路,前面两节我们学习了Express.Jade引擎并创建了几个静态页面,最后通过Heroku部署了应用. Nodejs之MEAN栈开发(一)---- 路由与控制器 Nod ...
- 如何让你的JavaScript代码更加语义化
语义化这个词在 HTML 中用的比较多,即根据内容的结构化选择合适的标签.其作用不容小觑: 赋予标签含义,让代码结构更加清晰,虽然我们可以在标签上添加 class 来标识,但这种通过属性来表示本体的形 ...
- Windows错误码解析
C或者C++开发肯定经常会遇到各种错误码,由于每个错误码只是一个枚举或者一个整形数值,调试或者输出日志的时候,无法知道这个错误码的具体含义,这时候就需要将此错误码解释出来.对于自己定义的错误码,可以通 ...
- Web3DGame之路,Babylonjs 和TypeScript学习笔记(一)
一个开源的Webgl3D引擎,javascript or typescript http://www.babylonjs.com 啥是WebGL WebGL 网页图形库,简称WebGL,是一个JS库, ...
- .Net组件程序设计之异步调用
.Net组件程序设计之异步调用 说到异步调用,在脑海中首先想到就是BeginInvoke(),在一些常用对象中我们也会常常见到Invoke()和BeginInvoke(), 要想让自己的组件可以被客户 ...