#rsync #diff #rdiff

den

一种通用的差分编码网络差异算法

4个版本 (2个破坏性版本)

0.3.0 2022年7月20日
0.2.1 2021年12月7日
0.2.0 2021年12月7日
0.1.0 2021年11月23日

#1701 in 算法

LGPL-3.0-or-later

81KB
1.5K SLoC

den

den 是一种差异算法。它适用于通用数据,包括二进制和文本。

den 在很大程度上受到了 rsync 和其滚动哈希概念的启发。

有关如何使用 den 的详细信息,请参阅文档


lib.rs:

一个类似于 rsync 的差异库。

性能

den 的性能足够处理大文件,文件大小超过10MB(使用滚动哈希时)。请使用 release 预设编译,以提高性能 10X

与哈希相比,分配数据和将其保留在内存中非常快。未来,Den将支持按位读取数据,从而大大减少内存使用。

如何使用 & 示例

请注意,这并不保证给出完全相同的数据。请使用安全的哈希算法(例如SHA-3)检查数据,以确保一致性。

由于 serde 提供序列化和反序列化,因此可以发送数据。这需要启用 cargo 功能 serde。您可以将此库中的所有结构体序列化到任何格式。

以下示例应涵盖 rsync 所做的工作。

获取远程数据

要获取他人的数据,我们构建一个 Signature 并发送它。远程使用 Signature::diff 计算差异。远程发送 Difference,我们使用 Difference::apply

将我的数据推送到远程

请求远程的 Signature。它们计算它并做出回应。我们计算一个 Signature::diff 并发送给它。它们 Difference::apply 它。它们的数据现在应该等于我的。

获取本地文件的差异

获取一个小的差异以发送给其他人,几乎就像 git 的工作方式。

base_data 被认为是先验知识。 target_data 是修改后的数据。

数据段可以任何大小。性能应该仍然很好。

let base_data = b"This is a document everyone has. It's about some new difference library.";
let target_data = b"This is a document only I have. It's about some new difference library.";

let mut signature = Signature::new(128);
signature.write(base_data);
let signature = signature.finish();

let diff = signature.diff(target_data);

// This is the small diff you could serialize with Serde and send.
let minified = diff.minify(8, base_data)
    .expect("This won't panic, as the data hasn't changed from calling the other functions.");

未来的改进

  • 滚动哈希
  • 多线程的 Signature::diff 由于我们预览并在每次迭代后更改我们正在查看的窗口,因此没有可行的实现方式。现在有了滚动哈希,性能很好。
  • 支持读写
    • 支持对读取器进行差异处理
    • 支持应用到写入器
    • 获取应用的 API 以按需获取数据。
      • 这可能会显著减慢速度。
    • HashBuilder 实现 Write。
  • 使用 SHA(1|256?) 验证数据的完整性。与 Signature 一起打包。 实现者应提供此功能。

依赖项

~320–610KB
~10K SLoC