Crates.io | reed-solomon-16 |
lib.rs | reed-solomon-16 |
version | 0.1.0 |
source | src |
created_at | 2022-01-04 12:57:12.740159 |
updated_at | 2022-01-04 12:57:12.740159 |
description | Reed-Solomon GF(2^16) erasure coding with O(n log n) complexity |
homepage | |
repository | https://github.com/malaire/reed-solomon-16 |
max_upload_size | |
id | 507782 |
size | 226,493 |
A library for Reed-Solomon GF(2^16)
erasure coding, featuring:
O(n log n)
complexity.reed_solomon_16::encode
.reed_solomon_16::decode
.
Divide data into 3 original shards of 64 bytes each and generate 5 recovery shards. Assume then that original shards #0 and #2 are lost and restore them by providing 1 original shard and 2 recovery shards.
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>(())
ReedSolomonEncoder
and ReedSolomonDecoder
give more control
of the encoding/decoding process.
Here's the above example using these instead:
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>(())
See rate
module for advanced encoding/decoding
using chosen Engine
and Rate
.
cargo bench main
with 3.4 GHz i5-3570K (Ivy Bridge, 3rd gen.).add_original_shard
and
encode
of ReedSolomonEncoder
.add_original_shard
,
add_recovery_shard
and
decode
of ReedSolomonDecoder
.original : recovery | MiB/s (encode) | MiB/s (decode) |
---|---|---|
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 |
Use cargo run --release --example quick-comparison
to run few simple benchmarks against reed-solomon-erasure
and reed-solomon-novelpoly
crates.
This crate is fastest when shard count exceeds 256 shards, except for one-time initialization (< 10 ms) which can dominate at really small data amounts.
Some larger tests are marked #[ignore]
and are not run with cargo test
.
Use cargo test -- --ignored
to run those.
This crate doesn't currently use any unsafe
code.
However planned SIMD-optimized engines will need to use unsafe
,
but the intention is that nothing else will use unsafe
.
This crate is based on Leopard-RS by Christopher A. Taylor.