开源我的基于字节的数据补丁算法库HDiffPatch
作者: HouSisong@GMail.com   2013.05.31

tag: HDiffPatch,diff,patch,补丁


HDiffPatch是一个高效的diff/patch实现,比bsdiff更快(平均1/7时间),占用的内存更小(1/2内存),更容易使用和集成,得到的diff结果压缩后也经常比bsdiff更小或相当(一般小10%以上)!    (  google也在使用bsdiff; 网址: http://www.daemonology.net/bsdiff/  ; 我也是在google的开源代码中的第三方源码库中发现bsdiff的 )

HDiffPatch使用很简单(请阅读项目的readme):
  1.create diff(newData字节数组,oldData字节数组,out diffData);
      生成了oldData到newData的差异信息diffData;
  2. patch(out newData,oldData,diffData);
      用oldData和diffData就可以合成newData。
  (HDiffPatch支持直接压缩补丁包,patch的时候不用提前解压)

HDiffPatch(-m模式)算法特性:
    HDiff算法时间复杂度O(newSize+oldSize),(只能算平均复杂度,妥协是为了优化内存占用),内存使用newSize+oldSize*5+O(1)字节;(oldSize>=2G时 newSize+oldSize*9+O(1)字节 )。
    HPatch算法时间复杂度O(newSize+oldSize),内存使用newSize+oldSize+O(1)字节;可以使用patch by stream特性把O(n)空间复杂度消耗转嫁给硬盘,从而patch时消耗内存O(1)。

  (和bsdiff、xdelta的详细对比测试:  HDiffPatch和BsDiff4.3&xdelta3.1的对比测试 )

HDiffPatch的授权协议:
    HDiffPatch使用的约束非常小的MIT协议(注意: HDiff库里使用的唯一第三方库libdivsufsort,应该也是该协议);

HDiffPatch的由来:
    我们2004年的时候做PC联网游戏,支持给大量客户端自动升级到最新版本; 为了减小需要下载的数据流量,只要传递版本之间的差异就可以了,这就有了做diff和patch算法的需求;  开始的时候时候试用过VPatch,觉得生成补丁速度慢,又接触过后缀数组的概念,就实现了一个自己的版本,参见2006年的blog<一个高效的二进制数据补丁算法>;  
    HDiffPatch是去年在节假日时间重新按diff\ptach算法用C\C++代码实现了一个版本(以前的版本用Delphi写的,2份代码不是移植关系);   其中HDiff用的C++来实现的,HPatch为了更好的移植性完全用纯C语言实现;   所有代码在windows\macosx\linux,x86\x64\小端arm\大端powerPC下都编译运行过;  (当然,环境所限,我没有在更多的系统和CPU体系下编译和运行)
   后来随着游戏的变大,diff(-m模式)的内存和时间占用都有点大,就支持了-s模式,更快内存占用可控(略微增大补丁包为代价),见blog<一个基于字节的流式diff算法>。


HDiffPatch的开源计划:
    项目网址:  GitHub - sisong/HDiffPatch 
    项目计划:  ( 没有明确的开发计划,大家用着高兴就好,作者很懒,可能是如下 )
      .更多环境和CPU体系的使用测试;
      .和其他更多diff/patch的对比测试;
      .英文版的源代码注释; (我的英语能力很差; readme文件都改了好多版! )
      .更大范围使用后的新需求: 比如提供  库提供选择使用LZMA或zlib等压缩的diffData? (新版本已经支持)   文件和文件夹级别的 diff/patch ? (新版本已经提供目录间的diff&patch) 支持apk、zip和jar包?(新仓库 ApkDiffPatch 提供了一个Zip(Jar,Apk) 包的diff&patch工具,对于apk文件,需要自己能够重新签名,因而无法将方案部署于应用商店。 专门针对应用商店的场景开发了一个优化方案 sfpatcher)    

      .针对可执行程序文件的一个特殊优化算法的实现(相信会得到小得多的diff数据;但这样代码就和不同平台的可执行程序文件结构有相关性,比如windows平台需要处理PE文件结构...    ps: 类似7zip中的bcj算法;该类算法统称disasm;google有一个实现该优化的算法设计(小胡瓜Courgette):  newExe和oldExe可执行程序分别反汇编(disasm)为伪代码newCode和oldCode,对伪代码做常规diff得到diffCode(可以选择进一步无损压缩),patch时oldExe反汇编得到oldCode,和diffCode执行常规patch得到newCode,重新汇编newCode得到newExe. 

(ps: github在源代码共享和协作开发方面比以前的方式方便和安全了很多,我的一些'有趣'或可能算有点儿用的代码也会陆续放上去 )

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐