#erasure-coding #reed-solomon #erasure #original #gf #shards #data

reed-solomon-16

Reed-Solomon GF(2^16) 纠删码,具有 O(n log n) 复杂度

1 个不稳定版本

0.1.0 2022年1月4日

#773算法

每月 22 次下载
用于 reed-solomon-simd

MIT 和 BSD-3-Clause

185KB
4K SLoC

reed-solomon-16

一个用于 Reed-Solomon GF(2^16) 纠删码的库,具有

  • O(n log n) 复杂度。
  • 1 - 32768 个原始碎片和 1 - 32768 个恢复碎片的任意组合。
  • 最多 65535 个原始或恢复碎片,存在一些限制。
  • 计划进行SIMD优化,但尚未实现。

简单用法

  1. 将数据分成等大小的原始碎片。碎片大小必须是64字节的倍数。
  2. 决定你想要的恢复碎片的数量。
  3. 使用 reed_solomon_16::encode 生成恢复碎片。
  4. 当一些原始碎片丢失时,使用 reed_solomon_16::decode 恢复它们。
    • 你必须提供至少与原始碎片总数相同数量的碎片,可以是原始碎片和恢复碎片的任何组合。

示例

将数据分成3个64字节的原始碎片,并生成5个恢复碎片。假设原始碎片#0和#2丢失,通过提供1个原始碎片和2个恢复碎片来恢复它们。

let original = [
    b"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do ",
    b"eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut e",
    b"nim ad minim veniam, quis nostrud exercitation ullamco laboris n",
];

let recovery = reed_solomon_16::encode(
    3, // total number of original shards
    5, // total number of recovery shards
    original, // all original shards
)?;

let restored = reed_solomon_16::decode(
    3, // total number of original shards
    5, // total number of recovery shards
    [  // provided original shards with indexes
        (1, &original[1]),
    ],
    [  // provided recovery shards with indexes
        (1, &recovery[1]),
        (4, &recovery[4]),
    ],
)?;

assert_eq!(restored[&0], original[0]);
assert_eq!(restored[&2], original[2]);
# Ok::<(), reed_solomon_16::Error>(())

基本用法

ReedSolomonEncoderReedSolomonDecoder 提供了更多对编码/解码过程的控制。

以下是使用这些内容的示例

use reed_solomon_16::{ReedSolomonDecoder, ReedSolomonEncoder};
use std::collections::HashMap;

let original = [
    b"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do ",
    b"eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut e",
    b"nim ad minim veniam, quis nostrud exercitation ullamco laboris n",
];

let mut encoder = ReedSolomonEncoder::new(
    3, // total number of original shards
    5, // total number of recovery shards
    64, // shard size in bytes
)?;

for original in original {
    encoder.add_original_shard(original)?;
}

let result = encoder.encode()?;
let recovery: Vec<_> = result.recovery_iter().collect();

let mut decoder = ReedSolomonDecoder::new(
    3, // total number of original shards
    5, // total number of recovery shards
    64, // shard size in bytes
)?;

decoder.add_original_shard(1, original[1])?;
decoder.add_recovery_shard(1, recovery[1])?;
decoder.add_recovery_shard(4, recovery[4])?;

let result = decoder.decode()?;
let restored: HashMap<_, _> = result.restored_original_iter().collect();

assert_eq!(restored[&0], original[0]);
assert_eq!(restored[&2], original[2]);
# Ok::<(), reed_solomon_16::Error>(())

高级用法

有关使用所选 EngineRate 进行高级编码/解码的信息,请参阅 rate 模块。

基准测试

  • 这些基准测试是从 3.4 GHz i5-3570K (Ivy Bridge,第三代) 的 cargo bench main 生成的。
  • 数据分片大小为1024字节。
  • MiB/s表示总数据量,即原始分片加上恢复分片。
    • 对于解码器,这包括缺失的分片。
  • 编码基准
  • 解码基准
原始 : 恢复 MiB/s(编码) MiB/s(解码)
100 : 100 229 73 ; 71
100 : 1 000 229 66 ; 66
1 000 : 100 222 65 ; 64
1 000 : 1 000 171 77 ; 74
1 000 : 10 000 149 53 ; 53
10 000 : 1 000 154 55 ; 55
10 000 : 10 000 103 39 ; 38
16 385 : 16 385 89 31 ; 31
32 768 : 32 768 107 50 ; 49

与其他crate的基准比较

使用cargo run --release --example quick-comparison运行对reed-solomon-erasurereed-solomon-novelpoly crate的几个简单基准测试。

当分片数量超过256个时,此crate运行最快,除了初始化(<10毫秒)可能在极小数据量时占主导地位。

运行测试

一些较大的测试被标记为#[ignore],并且不会与cargo test一起运行。使用cargo test -- --ignored运行这些测试。

安全性

此crate目前不使用任何unsafe代码。

然而,计划中的SIMD优化引擎将需要使用unsafe,但意图是其他代码将不使用unsafe

致谢

此crate基于Christopher A. Taylor的Leopard-RS

依赖关系

~265KB