增量压缩工具Xdelta3源码解析——地址编码

本文深入探讨Xdelta3增量压缩工具的地址编码,包括VCD_SELF、VCD_HERE、NEAR缓存和SAME缓存四种类型。通过概念介绍、实例演示及源码解析,阐述如何根据数据地址和指令进行高效编码和解码操作,以减少内存开销并优化压缩效果。
摘要由CSDN通过智能技术生成

前言

通过系列的前面几篇文章,我们对Xdelta3的使用、增量指令以及增量文件都有了详细的了解,从本章开始,我们将通过结合源码来深入讲解整个增量压缩的编码和解码过程。

文章中贴源码的部分,我大多数情况下会以注释的形式进行解释,以便更准确地定位代码位置。

概念介绍

在之前讲解增量文件Window部分的时候,我们说COPY指令的数据地址被单独存放在addr数组中。

然而,为了最大程度上压缩增量文件的大小,ADDR数组中的元素大多数情况下都不是数据的实际地址。因为Base-128编码方式的特点,在编码数据地址的时候,我们期望能用少量的字节数(编码后)来表示一个地址,甚至于仅使用一个字节的低7位来表示,以避免额外的内存开销,这就需要用到我们今天要介绍的地址编码技术。

不知道大家还记不记得在讲解增量指令的那篇文章中,我们介绍过在指令代码表中每条指令都是通过一个三元组(inst,size,mode)来表示。

而这三元组中的mode就是地址编码的类型,因此该值也只有在COPY指令中才有意义。

地址编码总共分为4类,每一类对应的mode值也不同,在开始讲解之前,我们先定义几个名词:

  1. data:当前COPY指令要拷贝的数据
  2. addr:拷贝数据data的起始地址
  3. here:当前COPY指令的位置(即目标窗口的当前输入位置)
  4. en_addraddr通过地址编码后实际存入ADDR数组中的值
  • VCD_SELF(mode = 0)
    addr的值小于128,或不满足其他地址缓存类型的情况下,使用该类型,ADDR数组中存放的是addr本身的数值(en_addr = addr)。

  • VCD_HERE(mode = 1)
    使用here作为参照地址,计算相对于addr的偏移值(here - addr)。当偏移值小于128,或偏移值小于addr且不满足NEARSAME缓存的情况下,使用该类型。ADDR数组中存放的是偏移值(en_addr = here - addr)。

  • NEAR缓存(mode = [2, 5])
    NEAR缓存使用前s_nearCOPY指令的地址addr作为参照地址,计算当前指令的addr相对于NEAR缓存中的addr的偏移值(addr - near_addr)。当偏移值小于128,或偏移值小于前两种地址编码后的结果且不满足SAME缓存的情况下,使用该类型,ADDR数组中存放的是偏移值(en_addr = addr - near_addr)。
    s_near是一个预设的整数值,用来表示NEAR缓存的数量。在VCDIFF的默认指令代码表中s_near的值为4,因此mode的取值范围在2~5之间,用户也可以通过自定义代码表来修改这个值。
    NEAR缓存

  • SAME缓存(mode = [6, 8])
    每次编码一条COPY指令时,其地址addr都将被保存至SAME缓存中,每次新编码一个地址时,都会检索SAME缓存,若其中有与之相等的addr值,则该地址被编码为SAME缓存中的索引值,该索引就对应addr值。
    SAME缓存总共可以存储s_same*256个不重复的地址,s_same是一个预设的整数值,用来表示SAME缓存区域的数量,在VCDIFF的默认指令代码表中s_same的值为3,因此mode的取值范围在6~8之间,用户也可以通过自定义代码表来修改这个值。每块区域最多可以含有256个地址,因此一块区域内的索引值仅需一个字节长度即可表示。但实际上这s_same块区域的索引值是连续的,也就是说,在存值取值时,SAME缓存所能取到最大索引值为(s_same*256)-1
    SAME缓存采用哈希表的方式存储addr,其哈希函数为:i_same = addr % (s_same * 256)i_same为存放addr的索引值,ADDR数组中存放的是索引值i_same
    SAME缓存

实例演示

这么说可能有点抽象,我们照例还是通过例子来进一步理解,假设某个将要编码的目标窗口和其对应的源窗口如下:
源窗口和目标窗口
如果全部使用COPY指令编码该目标窗口的前33个字节,则将生成以下六条COPY指令(指令格式为COPY(size, addr))。我们将依次解析每条COPY指令的地址编码:

  1. COPY(4, 4306)
    此时here=10000,指令的addr=4306,使用here作为参照地址的偏移值(here-addr)=5694>4306NEARSAME缓存都为空,因此只能选择VCD_SELF类型编码地址(mode = 0),en_addr=4306并存入ADDR数组中,同时将addr存入NEARSAME缓存,其中SAME缓存的索引值i_same=4306%(3*256)=376
    第一条COPY指令
  2. COPY(7, 4399)
    此时here=10004,指令的addr=4399,使用here作为参照地址的偏移值(here-addr)=5605>4399NEAR缓存中的最小偏移值(4399-4306)为93,小于128,因此选择NEAR缓存类型编码地址(4306NEAR缓存中的索引值为0,所以mode = 2),en_addr=93并存入ADDR数组中,同时将addr存入NEARSAME缓存,其中SAME缓存的索引值i_same=4399%(3*256)=559
    第二条COPY指令
  3. COPY(3, 9909)
    此时here=10011,指令的addr=9909,使用here作为参照地址的偏移值(here-addr)=102<128,因此选择VCD_HERE类型编码地址(mode = 1),en_addr=102并存入ADDR数组中,同时将addr存入NEARSAME缓存,其中SAME缓存的索引值i_same=9909%(3*256)=693
    第三条COPY指令
  4. COPY(9, 8888)
    此时here=10014,指令的addr=8888,使用here作为参照地址的偏移值(h
  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
YAXBPC1.6.1 老朽痴拙汉化版(一款 xdelta3 的补丁生成器 GUI) 软件推荐:xdelta、xdelta3 “非常实用”用的二进制diff 与patch 工具,此工具只需母盘和很小的xdelta 补丁文件,即可方便的生成和母盘差异不大的目标文件,在大文件领域非常有用, 如大型游戏到ROM,大型软件文件、镜像 xdelta3用法: 1. 生成补丁:xdelta3 -v -e -s [母盘文件] [目标文件] 生成的差异文件[补丁文件] 2. 应用补丁:xdelta3 -v -d -s [母盘文件] 生成的差异文件[补丁文件] [目标文件] 3. 下载地址:http://xdelta.googlecode.com/files/xdelta3.0u.x86-32.exe 4. 官方主页:http://xdelta.org/ 5. 其中的-e -s 和-d -s 是必备参数,-v 输出详细处理信息;每个文件之间都有一个空隔着。 xdelta 用法: 1. 生成补丁:xdelta delta [母盘文件] [目标文件] 生成的差异文件[补丁文件] 2. 应用补丁:xdelta patch 生成的差异文件[补丁文件] [母盘文件] [目标文件] 3. 下载地址:http://evanjones.ca/software/xdelta.exe 4. 官方主页:http://evanjones.ca/ 5. 其中delta是生成补丁文件必备参数patch 是应用补丁的必备参数;-m用来设置内存缓冲大小 特别说明: 1. Xdelta的命令简单、方便处理小于2G的文件;Xdelta3命令复杂/功能强大, 2. 能方便的处理大于2G 的文件,在大文件横行的当今也不可或缺,以上仅给出了最简单的补丁生成和应用命令. 3. 更多的命令和参数选项您可以使用-help 命令自己查看。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值