3.1.1.5. Repeat Offsets (重复偏移)
如上所述,前三个值定义重复偏移;我们将它们称为 Repeated_Offset1、Repeated_Offset2 和 Repeated_Offset3。它们按最近性顺序排序,Repeated_Offset1 表示 "最近的一个"。
如果 offset_value 为 1,则使用的偏移量是 Repeated_Offset1,依此类推。
有一个例外:当当前序列的 literals_length 为 0 时,重复偏移会移位 1,因此:
- offset_value 为 1 表示 Repeated_Offset2
- offset_value 为 2 表示 Repeated_Offset3
- offset_value 为 3 表示 Repeated_Offset1 - 1_byte
初始化
对于第一个块,起始偏移历史用以下值填充:
- Repeated_Offset1 = 1
- Repeated_Offset2 = 4
- Repeated_Offset3 = 8
除非使用字典,在这种情况下它们来自字典。
然后每个块从最近的 Compressed_Block 的结束值中获取其起始偏移历史。请注意,非 Compressed_Block 的块被跳过;它们不影响偏移历史。
更新规则
在执行 Compressed_Block 的序列期间,Repeated_Offsets 的值保持最新,以便它们始终表示最近使用的三个偏移量。为了实现这一点,它们在执行每个序列后以以下方式更新:
情况 1: 非重复偏移
当序列的 offset_value 不引用 Repeated_Offsets 之一时(当它具有大于 3 的值,或当它具有值 3 且序列的 literals_length 为零时):
- Repeated_Offsets 的值向后移位一个
- Repeated_Offset1 采用刚刚使用的偏移量的值
更新公式:
Repeated_Offset3 = Repeated_Offset2
Repeated_Offset2 = Repeated_Offset1
Repeated_Offset1 = 新偏移量
情况 2: 重复偏移
当序列的 offset_value 引用 Repeated_Offsets 之一时(当它具有值 1 或 2,或当它具有值 3 且序列的 literals_length 非零时):
- Repeated_Offsets 被重新排序
- Repeated_Offset1 采用所使用的 Repeated_Offset 的值
- 现有值从第一个 Repeated_Offset 推回到 offset_value 选择的 Repeated_Offset
这有效地执行了这些偏移值的单步环绕旋转,使得它们的顺序再次反映其使用的最近性。
更新示例表
下表显示了在对 Repeated_Offsets 应用一系列序列时的值:
| offset_value | literals_length | Repeated_Offset1 | Repeated_Offset2 | Repeated_Offset3 | Comment (注释) |
|---|---|---|---|---|---|
| - | - | 1 | 4 | 8 | 起始值 |
| 1114 | 11 | 1111 | 1 | 4 | 非重复 |
| 1 | 22 | 1111 | 1 | 4 | 重复1;无变化 |
| 2225 | 22 | 2222 | 1111 | 1 | 非重复 |
| 1114 | 111 | 1111 | 2222 | 1111 | 非重复 |
| 3336 | 33 | 3333 | 1111 | 2222 | 非重复 |
| 2 | 22 | 1111 | 3333 | 2222 | 重复2;交换1和2 |
| 3 | 33 | 2222 | 1111 | 3333 | 重复3;旋转3到1 |
| 1 | 0 | 2221 | 2222 | 1111 | 插入解析的偏移 |
| 1 | 0 | 2222 | 2221 | 3333 | 重复2 |
表 18: Repeated_Offsets
特殊情况处理
literals_length = 0 的情况
当 literals_length = 0 时,offset_value 的解释会移位:
| offset_value | 实际使用的偏移 |
|---|---|
| 1 | Repeated_Offset2 |
| 2 | Repeated_Offset3 |
| 3 | Repeated_Offset1 - 1 |
这种特殊处理是为了优化连续的匹配复制操作。
关键要点
- 最近性原则: Repeated_Offset1 始终是最近使用的偏移
- 自动更新: 每次序列执行后自动更新偏移历史
- 字典支持: 初始值可以来自字典
- 特殊移位: literals_length=0 时偏移解释会移位