mirror of
https://github.com/cberner/raptorq.git
synced 2024-06-26 00:38:53 +00:00
raptorq: rustfmt whole project
This commit is contained in:
parent
a55116e637
commit
38df97cce1
@ -5,12 +5,11 @@ use criterion::Criterion;
|
||||
use criterion::Throughput;
|
||||
|
||||
use rand::Rng;
|
||||
use raptorq::SourceBlockEncoder;
|
||||
use raptorq::SourceBlockDecoder;
|
||||
use raptorq::Octet;
|
||||
use raptorq::SourceBlockDecoder;
|
||||
use raptorq::SourceBlockEncoder;
|
||||
use raptorq::Symbol;
|
||||
|
||||
|
||||
fn criterion_benchmark(c: &mut Criterion) {
|
||||
let octet1 = Octet::new(rand::thread_rng().gen_range(1, 255));
|
||||
let symbol_size = 512;
|
||||
@ -25,31 +24,48 @@ fn criterion_benchmark(c: &mut Criterion) {
|
||||
|
||||
let symbol1_mul_scalar = symbol1.clone();
|
||||
let octet1_mul_scalar = octet1.clone();
|
||||
c.bench("Symbol mulassign_scalar()", Benchmark::new("", move |b| b.iter(|| {
|
||||
let mut temp = symbol1_mul_scalar.clone();
|
||||
temp.mulassign_scalar(&octet1_mul_scalar);
|
||||
temp
|
||||
})).throughput(Throughput::Bytes(symbol1.len() as u32)));
|
||||
c.bench(
|
||||
"Symbol mulassign_scalar()",
|
||||
Benchmark::new("", move |b| {
|
||||
b.iter(|| {
|
||||
let mut temp = symbol1_mul_scalar.clone();
|
||||
temp.mulassign_scalar(&octet1_mul_scalar);
|
||||
temp
|
||||
})
|
||||
})
|
||||
.throughput(Throughput::Bytes(symbol1.len() as u32)),
|
||||
);
|
||||
|
||||
let symbol1_addassign = symbol1.clone();
|
||||
let symbol2_addassign = symbol2.clone();
|
||||
c.bench("Symbol +=", Benchmark::new("", move |b| b.iter(|| {
|
||||
let mut temp = symbol1_addassign.clone();
|
||||
temp += &symbol2_addassign;
|
||||
temp
|
||||
})).throughput(Throughput::Bytes(symbol1.len() as u32)));
|
||||
c.bench(
|
||||
"Symbol +=",
|
||||
Benchmark::new("", move |b| {
|
||||
b.iter(|| {
|
||||
let mut temp = symbol1_addassign.clone();
|
||||
temp += &symbol2_addassign;
|
||||
temp
|
||||
})
|
||||
})
|
||||
.throughput(Throughput::Bytes(symbol1.len() as u32)),
|
||||
);
|
||||
|
||||
let symbol1_fma = symbol1.clone();
|
||||
let symbol2_fma = symbol2.clone();
|
||||
let octet1_fma = octet1.clone();
|
||||
c.bench("Symbol FMA", Benchmark::new("", move |b| b.iter(|| {
|
||||
let mut temp = symbol1_fma.clone();
|
||||
temp.fused_addassign_mul_scalar(&symbol2_fma, &octet1_fma);
|
||||
temp
|
||||
})).throughput(Throughput::Bytes(symbol1.len() as u32)));
|
||||
c.bench(
|
||||
"Symbol FMA",
|
||||
Benchmark::new("", move |b| {
|
||||
b.iter(|| {
|
||||
let mut temp = symbol1_fma.clone();
|
||||
temp.fused_addassign_mul_scalar(&symbol2_fma, &octet1_fma);
|
||||
temp
|
||||
})
|
||||
})
|
||||
.throughput(Throughput::Bytes(symbol1.len() as u32)),
|
||||
);
|
||||
|
||||
|
||||
let elements = 10*1024;
|
||||
let elements = 10 * 1024;
|
||||
let symbol_size = 512;
|
||||
let mut data: Vec<u8> = vec![0; elements];
|
||||
for i in 0..elements {
|
||||
@ -57,32 +73,50 @@ fn criterion_benchmark(c: &mut Criterion) {
|
||||
}
|
||||
|
||||
let encode_data = data.clone();
|
||||
c.bench("encode 10KB", Benchmark::new("", move |b| b.iter(|| {
|
||||
let encoder = SourceBlockEncoder::new(1, symbol_size, &encode_data);
|
||||
return encoder.source_packets();
|
||||
})).throughput(Throughput::Bytes(data.len() as u32)));
|
||||
c.bench(
|
||||
"encode 10KB",
|
||||
Benchmark::new("", move |b| {
|
||||
b.iter(|| {
|
||||
let encoder = SourceBlockEncoder::new(1, symbol_size, &encode_data);
|
||||
return encoder.source_packets();
|
||||
})
|
||||
})
|
||||
.throughput(Throughput::Bytes(data.len() as u32)),
|
||||
);
|
||||
|
||||
let roundtrip_data = data.clone();
|
||||
c.bench("roundtrip 10KB", Benchmark::new("", move |b| b.iter(|| {
|
||||
let encoder = SourceBlockEncoder::new(1, symbol_size, &roundtrip_data);
|
||||
let mut decoder = SourceBlockDecoder::new(1, symbol_size, elements as u64);
|
||||
let mut result = None;
|
||||
for packet in encoder.source_packets() {
|
||||
result = decoder.decode(packet);
|
||||
}
|
||||
return result
|
||||
})).throughput(Throughput::Bytes(data.len() as u32)));
|
||||
c.bench(
|
||||
"roundtrip 10KB",
|
||||
Benchmark::new("", move |b| {
|
||||
b.iter(|| {
|
||||
let encoder = SourceBlockEncoder::new(1, symbol_size, &roundtrip_data);
|
||||
let mut decoder = SourceBlockDecoder::new(1, symbol_size, elements as u64);
|
||||
let mut result = None;
|
||||
for packet in encoder.source_packets() {
|
||||
result = decoder.decode(packet);
|
||||
}
|
||||
return result;
|
||||
})
|
||||
})
|
||||
.throughput(Throughput::Bytes(data.len() as u32)),
|
||||
);
|
||||
|
||||
let repair_data = data.clone();
|
||||
c.bench("roundtrip repair 10KB", Benchmark::new("", move |b| b.iter(|| {
|
||||
let encoder = SourceBlockEncoder::new(1, symbol_size, &repair_data);
|
||||
let mut decoder = SourceBlockDecoder::new(1, symbol_size, elements as u64);
|
||||
let mut result = None;
|
||||
for packet in encoder.repair_packets(0, (elements / symbol_size as usize) as u32) {
|
||||
result = decoder.decode(packet);
|
||||
}
|
||||
return result
|
||||
})).throughput(Throughput::Bytes(data.len() as u32)));
|
||||
c.bench(
|
||||
"roundtrip repair 10KB",
|
||||
Benchmark::new("", move |b| {
|
||||
b.iter(|| {
|
||||
let encoder = SourceBlockEncoder::new(1, symbol_size, &repair_data);
|
||||
let mut decoder = SourceBlockDecoder::new(1, symbol_size, elements as u64);
|
||||
let mut result = None;
|
||||
for packet in encoder.repair_packets(0, (elements / symbol_size as usize) as u32) {
|
||||
result = decoder.decode(packet);
|
||||
}
|
||||
return result;
|
||||
})
|
||||
})
|
||||
.throughput(Throughput::Bytes(data.len() as u32)),
|
||||
);
|
||||
}
|
||||
|
||||
criterion_group!(benches, criterion_benchmark);
|
||||
|
@ -1,9 +1,8 @@
|
||||
use rand::Rng;
|
||||
use raptorq::SourceBlockEncoder;
|
||||
|
||||
|
||||
fn main() {
|
||||
let elements = 10*1024;
|
||||
let elements = 10 * 1024;
|
||||
let symbol_size = 512;
|
||||
let mut data: Vec<u8> = vec![0; elements];
|
||||
for i in 0..elements {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use raptorq::extended_source_block_symbols;
|
||||
use raptorq::generate_constraint_matrix;
|
||||
use raptorq::IntermediateSymbolDecoder;
|
||||
use raptorq::Octet;
|
||||
use raptorq::generate_constraint_matrix;
|
||||
use raptorq::extended_source_block_symbols;
|
||||
use raptorq::Symbol;
|
||||
|
||||
fn main() {
|
||||
@ -17,18 +17,28 @@ fn main() {
|
||||
}
|
||||
}
|
||||
}
|
||||
println!("Original density for {}x{}: {} of {}", a.height(), a.width(), density, a.height() * a.width());
|
||||
println!(
|
||||
"Original density for {}x{}: {} of {}",
|
||||
a.height(),
|
||||
a.width(),
|
||||
density,
|
||||
a.height() * a.width()
|
||||
);
|
||||
|
||||
let symbols = vec![Symbol::zero(1); a.width()];
|
||||
let mut decoder = IntermediateSymbolDecoder::new(a, symbols, num_symbols);
|
||||
decoder.execute();
|
||||
println!("Optimized decoder mul ops: {} ({:.1} per symbol), add ops: {} ({:.1} per symbol)",
|
||||
decoder.get_symbol_mul_ops(),
|
||||
decoder.get_symbol_mul_ops() as f64 / num_symbols as f64,
|
||||
decoder.get_symbol_add_ops(),
|
||||
decoder.get_symbol_add_ops() as f64 / num_symbols as f64);
|
||||
println!("By phase mul ops: {:?}, add ops: {:?}",
|
||||
decoder.get_symbol_mul_ops_by_phase(),
|
||||
decoder.get_symbol_add_ops_by_phase());
|
||||
println!(
|
||||
"Optimized decoder mul ops: {} ({:.1} per symbol), add ops: {} ({:.1} per symbol)",
|
||||
decoder.get_symbol_mul_ops(),
|
||||
decoder.get_symbol_mul_ops() as f64 / num_symbols as f64,
|
||||
decoder.get_symbol_add_ops(),
|
||||
decoder.get_symbol_add_ops() as f64 / num_symbols as f64
|
||||
);
|
||||
println!(
|
||||
"By phase mul ops: {:?}, add ops: {:?}",
|
||||
decoder.get_symbol_mul_ops_by_phase(),
|
||||
decoder.get_symbol_add_ops_by_phase()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use rand::Rng;
|
||||
use rand::seq::SliceRandom;
|
||||
use rand::Rng;
|
||||
use raptorq::{Decoder, Encoder, EncodingPacket};
|
||||
|
||||
fn main() {
|
||||
@ -13,7 +13,9 @@ fn main() {
|
||||
let encoder = Encoder::with_defaults(&data, 1400);
|
||||
|
||||
// Perform the encoding, and serialize to Vec<u8> for transmission
|
||||
let mut packets: Vec<Vec<u8>> = encoder.get_encoded_packets(15).iter()
|
||||
let mut packets: Vec<Vec<u8>> = encoder
|
||||
.get_encoded_packets(15)
|
||||
.iter()
|
||||
.map(|packet| packet.serialize())
|
||||
.collect();
|
||||
|
||||
@ -40,4 +42,4 @@ fn main() {
|
||||
|
||||
// Check that even though some of the data was lost we are able to reconstruct the original message
|
||||
assert_eq!(result.unwrap(), data);
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
#[derive(Clone)]
|
||||
pub struct ArrayMap<T> {
|
||||
offset: usize,
|
||||
elements: Vec<Option<T>>
|
||||
elements: Vec<Option<T>>,
|
||||
}
|
||||
|
||||
impl <T: std::clone::Clone> ArrayMap<T> {
|
||||
impl<T: std::clone::Clone> ArrayMap<T> {
|
||||
pub fn new(start_key: usize, end_key: usize) -> ArrayMap<T> {
|
||||
ArrayMap {
|
||||
offset: start_key,
|
||||
elements: vec![None; end_key - start_key]
|
||||
elements: vec![None; end_key - start_key],
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,14 +38,14 @@ impl <T: std::clone::Clone> ArrayMap<T> {
|
||||
#[derive(Clone)]
|
||||
pub struct UsizeArrayMap {
|
||||
offset: usize,
|
||||
elements: Vec<usize>
|
||||
elements: Vec<usize>,
|
||||
}
|
||||
|
||||
impl UsizeArrayMap {
|
||||
pub fn new(start_key: usize, end_key: usize) -> UsizeArrayMap {
|
||||
UsizeArrayMap {
|
||||
offset: start_key,
|
||||
elements: vec![0; end_key - start_key]
|
||||
elements: vec![0; end_key - start_key],
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,14 +73,14 @@ impl UsizeArrayMap {
|
||||
#[derive(Clone)]
|
||||
pub struct BoolArrayMap {
|
||||
offset: usize,
|
||||
elements: Vec<bool>
|
||||
elements: Vec<bool>,
|
||||
}
|
||||
|
||||
impl BoolArrayMap {
|
||||
pub fn new(start_key: usize, end_key: usize) -> BoolArrayMap {
|
||||
BoolArrayMap {
|
||||
offset: start_key,
|
||||
elements: vec![false; end_key - start_key]
|
||||
elements: vec![false; end_key - start_key],
|
||||
}
|
||||
}
|
||||
|
||||
|
87
src/base.rs
87
src/base.rs
@ -10,7 +10,7 @@ use crate::systematic_constants::SYSTEMATIC_INDICES_AND_PARAMETERS;
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct PayloadId {
|
||||
source_block_number: u8,
|
||||
encoding_symbol_id: u32
|
||||
encoding_symbol_id: u32,
|
||||
}
|
||||
|
||||
impl PayloadId {
|
||||
@ -19,14 +19,14 @@ impl PayloadId {
|
||||
assert!(encoding_symbol_id < 16777216);
|
||||
PayloadId {
|
||||
source_block_number,
|
||||
encoding_symbol_id
|
||||
encoding_symbol_id,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deserialize(data: &[u8; 4]) -> PayloadId {
|
||||
PayloadId {
|
||||
source_block_number: data[0],
|
||||
encoding_symbol_id: ((data[1] as u32) << 16) + ((data[2] as u32) << 8) + data[3] as u32
|
||||
encoding_symbol_id: ((data[1] as u32) << 16) + ((data[2] as u32) << 8) + data[3] as u32,
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@ impl PayloadId {
|
||||
self.source_block_number,
|
||||
(self.encoding_symbol_id >> 16) as u8,
|
||||
((self.encoding_symbol_id >> 8) & 0xFF) as u8,
|
||||
(self.encoding_symbol_id & 0xFF) as u8
|
||||
(self.encoding_symbol_id & 0xFF) as u8,
|
||||
]
|
||||
}
|
||||
|
||||
@ -52,22 +52,19 @@ impl PayloadId {
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct EncodingPacket {
|
||||
payload_id: PayloadId,
|
||||
data: Vec<u8>
|
||||
data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl EncodingPacket {
|
||||
pub fn new(payload_id: PayloadId, data: Vec<u8>) -> EncodingPacket {
|
||||
EncodingPacket {
|
||||
payload_id,
|
||||
data
|
||||
}
|
||||
EncodingPacket { payload_id, data }
|
||||
}
|
||||
|
||||
pub fn deserialize(data: &[u8]) -> EncodingPacket {
|
||||
let payload_data = [data[0], data[1], data[2], data[3]];
|
||||
EncodingPacket {
|
||||
payload_id: PayloadId::deserialize(&payload_data),
|
||||
data: Vec::from(&data[4..])
|
||||
data: Vec::from(&data[4..]),
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,11 +91,17 @@ pub struct ObjectTransmissionInformation {
|
||||
symbol_size: u16,
|
||||
num_source_blocks: u8,
|
||||
num_sub_blocks: u16,
|
||||
symbol_alignment: u8
|
||||
symbol_alignment: u8,
|
||||
}
|
||||
|
||||
impl ObjectTransmissionInformation {
|
||||
pub fn new(transfer_length: u64, symbol_size: u16, source_blocks: u8, sub_blocks: u16, alignment: u8) -> ObjectTransmissionInformation {
|
||||
pub fn new(
|
||||
transfer_length: u64,
|
||||
symbol_size: u16,
|
||||
source_blocks: u8,
|
||||
sub_blocks: u16,
|
||||
alignment: u8,
|
||||
) -> ObjectTransmissionInformation {
|
||||
assert!(transfer_length <= 946270874880);
|
||||
assert_eq!(symbol_size % alignment as u16, 0);
|
||||
ObjectTransmissionInformation {
|
||||
@ -106,18 +109,21 @@ impl ObjectTransmissionInformation {
|
||||
symbol_size,
|
||||
num_source_blocks: source_blocks,
|
||||
num_sub_blocks: sub_blocks,
|
||||
symbol_alignment: alignment
|
||||
symbol_alignment: alignment,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deserialize(data: &[u8; 12]) -> ObjectTransmissionInformation {
|
||||
ObjectTransmissionInformation {
|
||||
transfer_length: ((data[0] as u64) << 32) + ((data[1] as u64) << 24) +
|
||||
((data[2] as u64) << 16) + ((data[3] as u64) << 8) + (data[4] as u64),
|
||||
transfer_length: ((data[0] as u64) << 32)
|
||||
+ ((data[1] as u64) << 24)
|
||||
+ ((data[2] as u64) << 16)
|
||||
+ ((data[3] as u64) << 8)
|
||||
+ (data[4] as u64),
|
||||
symbol_size: ((data[6] as u16) << 8) + data[7] as u16,
|
||||
num_source_blocks: data[8],
|
||||
num_sub_blocks: ((data[9] as u16) << 8) + data[10] as u16,
|
||||
symbol_alignment: data[11]
|
||||
symbol_alignment: data[11],
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,7 +140,7 @@ impl ObjectTransmissionInformation {
|
||||
self.num_source_blocks,
|
||||
(self.num_sub_blocks >> 8) as u8,
|
||||
(self.num_sub_blocks & 0xFF) as u8,
|
||||
self.symbol_alignment
|
||||
self.symbol_alignment,
|
||||
]
|
||||
}
|
||||
|
||||
@ -158,11 +164,14 @@ impl ObjectTransmissionInformation {
|
||||
self.symbol_alignment
|
||||
}
|
||||
|
||||
pub fn with_defaults(transfer_length: u64, max_packet_size: u16) -> ObjectTransmissionInformation {
|
||||
pub fn with_defaults(
|
||||
transfer_length: u64,
|
||||
max_packet_size: u16,
|
||||
) -> ObjectTransmissionInformation {
|
||||
let alignment = 8;
|
||||
assert!(max_packet_size >= alignment);
|
||||
let symbol_size = max_packet_size - (max_packet_size % alignment);
|
||||
let max_memory = 10*1024*1024;
|
||||
let max_memory = 10 * 1024 * 1024;
|
||||
let sub_symbol_size = 8;
|
||||
|
||||
let kt = (transfer_length as f64 / symbol_size as f64).ceil();
|
||||
@ -193,8 +202,7 @@ impl ObjectTransmissionInformation {
|
||||
symbol_size,
|
||||
num_source_blocks: num_source_blocks as u8,
|
||||
num_sub_blocks: n as u16,
|
||||
symbol_alignment: alignment as u8
|
||||
|
||||
symbol_alignment: alignment as u8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -212,9 +220,10 @@ pub fn partition(i: u32, j: u32) -> (u32, u32, u32, u32) {
|
||||
pub fn deg(v: u32, lt_symbols: u32) -> u32 {
|
||||
assert!(v < 1048576);
|
||||
let f: [u32; 31] = [
|
||||
0, 5243, 529531, 704294, 791675, 844104, 879057, 904023, 922747, 937311, 948962,
|
||||
958494, 966438, 973160, 978921, 983914, 988283, 992138, 995565, 998631, 1001391,
|
||||
1003887, 1006157, 1008229, 1010129, 1011876, 1013490, 1014983, 1016370, 1017662, 1048576];
|
||||
0, 5243, 529531, 704294, 791675, 844104, 879057, 904023, 922747, 937311, 948962, 958494,
|
||||
966438, 973160, 978921, 983914, 988283, 992138, 995565, 998631, 1001391, 1003887, 1006157,
|
||||
1008229, 1010129, 1011876, 1013490, 1014983, 1016370, 1017662, 1048576,
|
||||
];
|
||||
|
||||
for d in 1..f.len() {
|
||||
if v < f[d] {
|
||||
@ -226,22 +235,25 @@ pub fn deg(v: u32, lt_symbols: u32) -> u32 {
|
||||
|
||||
// Tuple[K', X] as defined in section 5.3.5.4
|
||||
#[allow(non_snake_case)]
|
||||
pub fn intermediate_tuple(source_block_symbols: u32, internal_symbol_id: u32) -> (u32, u32, u32, u32, u32, u32) {
|
||||
pub fn intermediate_tuple(
|
||||
source_block_symbols: u32,
|
||||
internal_symbol_id: u32,
|
||||
) -> (u32, u32, u32, u32, u32, u32) {
|
||||
let J = systematic_index(source_block_symbols);
|
||||
let W = num_lt_symbols(source_block_symbols);
|
||||
let P1 = calculate_p1(source_block_symbols);
|
||||
|
||||
let mut A = 53591 + J*997;
|
||||
let mut A = 53591 + J * 997;
|
||||
|
||||
if A % 2 == 0 {
|
||||
A = A + 1
|
||||
}
|
||||
|
||||
let B = 10267*(J + 1);
|
||||
let B = 10267 * (J + 1);
|
||||
let y: u32 = ((B as u64 + internal_symbol_id as u64 * A as u64) % 4294967296) as u32;
|
||||
let v = rand(y, 0, 1048576);
|
||||
let d = deg(v, W);
|
||||
let a = 1 + rand(y, 1, W-1);
|
||||
let a = 1 + rand(y, 1, W - 1);
|
||||
let b = rand(y, 2, W);
|
||||
|
||||
let mut d1 = 2;
|
||||
@ -249,7 +261,7 @@ pub fn intermediate_tuple(source_block_symbols: u32, internal_symbol_id: u32) ->
|
||||
d1 = 2 + rand(internal_symbol_id, 3, 2);
|
||||
}
|
||||
|
||||
let a1 = 1 + rand(internal_symbol_id, 4, P1-1);
|
||||
let a1 = 1 + rand(internal_symbol_id, 4, P1 - 1);
|
||||
let b1 = rand(internal_symbol_id, 5, P1);
|
||||
|
||||
(d, a, b, d1, a1, b1)
|
||||
@ -257,19 +269,25 @@ pub fn intermediate_tuple(source_block_symbols: u32, internal_symbol_id: u32) ->
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{EncodingPacket, ObjectTransmissionInformation, PayloadId};
|
||||
use rand::Rng;
|
||||
use crate::{PayloadId, EncodingPacket, ObjectTransmissionInformation};
|
||||
|
||||
#[test]
|
||||
fn payload_id_serialization() {
|
||||
let payload_id = PayloadId::new(rand::thread_rng().gen(), rand::thread_rng().gen_range(0, 256 * 256 * 256));
|
||||
let payload_id = PayloadId::new(
|
||||
rand::thread_rng().gen(),
|
||||
rand::thread_rng().gen_range(0, 256 * 256 * 256),
|
||||
);
|
||||
let deserialized = PayloadId::deserialize(&payload_id.serialize());
|
||||
assert_eq!(deserialized, payload_id);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn encoding_packet_serialization() {
|
||||
let payload_id = PayloadId::new(rand::thread_rng().gen(), rand::thread_rng().gen_range(0, 256 * 256 * 256));
|
||||
let payload_id = PayloadId::new(
|
||||
rand::thread_rng().gen(),
|
||||
rand::thread_rng().gen_range(0, 256 * 256 * 256),
|
||||
);
|
||||
let packet = EncodingPacket::new(payload_id, vec![rand::thread_rng().gen()]);
|
||||
let deserialized = EncodingPacket::deserialize(&packet.serialize());
|
||||
assert_eq!(deserialized, packet);
|
||||
@ -277,7 +295,10 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn oti_serialization() {
|
||||
let oti = ObjectTransmissionInformation::with_defaults(rand::thread_rng().gen_range(0, 256 * 256 * 256 * 256 * 256), rand::thread_rng().gen());
|
||||
let oti = ObjectTransmissionInformation::with_defaults(
|
||||
rand::thread_rng().gen_range(0, 256 * 256 * 256 * 256 * 256),
|
||||
rand::thread_rng().gen(),
|
||||
);
|
||||
let deserialized = ObjectTransmissionInformation::deserialize(&oti.serialize());
|
||||
assert_eq!(deserialized, oti);
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
use crate::rng::rand;
|
||||
use crate::systematic_constants::extended_source_block_symbols;
|
||||
use crate::systematic_constants::num_hdpc_symbols;
|
||||
use crate::systematic_constants::num_ldpc_symbols;
|
||||
use crate::systematic_constants::num_pi_symbols;
|
||||
use crate::systematic_constants::num_lt_symbols;
|
||||
use crate::systematic_constants::num_intermediate_symbols;
|
||||
use crate::base::intermediate_tuple;
|
||||
use crate::matrix::OctetMatrix;
|
||||
use crate::octet::Octet;
|
||||
use crate::rng::rand;
|
||||
use crate::systematic_constants::calculate_p1;
|
||||
use crate::base::intermediate_tuple;
|
||||
use crate::systematic_constants::extended_source_block_symbols;
|
||||
use crate::systematic_constants::num_hdpc_symbols;
|
||||
use crate::systematic_constants::num_intermediate_symbols;
|
||||
use crate::systematic_constants::num_ldpc_symbols;
|
||||
use crate::systematic_constants::num_lt_symbols;
|
||||
use crate::systematic_constants::num_pi_symbols;
|
||||
|
||||
// Generates the GAMMA matrix
|
||||
// See section 5.3.3.3
|
||||
@ -31,8 +31,12 @@ fn generate_mt(H: usize, Kprime: usize, S: usize) -> OctetMatrix {
|
||||
let mut matrix = OctetMatrix::new(H, Kprime + S);
|
||||
for i in 0..H {
|
||||
for j in 0..=(Kprime + S - 2) {
|
||||
if i == rand((j + 1) as u32, 6, H as u32) as usize ||
|
||||
i == ((rand((j + 1) as u32, 6, H as u32) + rand((j + 1) as u32, 7, (H - 1) as u32) + 1) % (H as u32)) as usize {
|
||||
if i == rand((j + 1) as u32, 6, H as u32) as usize
|
||||
|| i == ((rand((j + 1) as u32, 6, H as u32)
|
||||
+ rand((j + 1) as u32, 7, (H - 1) as u32)
|
||||
+ 1)
|
||||
% (H as u32)) as usize
|
||||
{
|
||||
matrix.set(i, j, Octet::one());
|
||||
}
|
||||
}
|
||||
@ -42,8 +46,10 @@ fn generate_mt(H: usize, Kprime: usize, S: usize) -> OctetMatrix {
|
||||
}
|
||||
|
||||
// Simulates Enc[] function to get indices of accessed intermediate symbols, as defined in section 5.3.5.3
|
||||
pub fn enc_indices(source_block_symbols: u32,
|
||||
source_tuple: (u32, u32, u32, u32, u32, u32)) -> Vec<usize> {
|
||||
pub fn enc_indices(
|
||||
source_block_symbols: u32,
|
||||
source_tuple: (u32, u32, u32, u32, u32, u32),
|
||||
) -> Vec<usize> {
|
||||
let w = num_lt_symbols(source_block_symbols);
|
||||
let p = num_pi_symbols(source_block_symbols);
|
||||
let p1 = calculate_p1(source_block_symbols);
|
||||
@ -82,7 +88,10 @@ pub fn enc_indices(source_block_symbols: u32,
|
||||
|
||||
// See section 5.3.3.4.2
|
||||
#[allow(non_snake_case)]
|
||||
pub fn generate_constraint_matrix(source_block_symbols: u32, encoded_symbol_indices: &[u32]) -> OctetMatrix {
|
||||
pub fn generate_constraint_matrix(
|
||||
source_block_symbols: u32,
|
||||
encoded_symbol_indices: &[u32],
|
||||
) -> OctetMatrix {
|
||||
let Kprime = extended_source_block_symbols(source_block_symbols) as usize;
|
||||
let S = num_ldpc_symbols(source_block_symbols) as usize;
|
||||
let H = num_hdpc_symbols(source_block_symbols) as usize;
|
||||
|
@ -1,20 +1,20 @@
|
||||
use std::collections::HashSet;
|
||||
use crate::base::intermediate_tuple;
|
||||
use crate::base::partition;
|
||||
use crate::base::EncodingPacket;
|
||||
use crate::base::ObjectTransmissionInformation;
|
||||
use crate::constraint_matrix::enc_indices;
|
||||
use crate::constraint_matrix::generate_constraint_matrix;
|
||||
use crate::pi_solver::fused_inverse_mul_symbols;
|
||||
use crate::symbol::Symbol;
|
||||
use crate::systematic_constants::extended_source_block_symbols;
|
||||
use crate::systematic_constants::num_ldpc_symbols;
|
||||
use crate::systematic_constants::num_hdpc_symbols;
|
||||
use crate::constraint_matrix::generate_constraint_matrix;
|
||||
use crate::base::intermediate_tuple;
|
||||
use crate::pi_solver::fused_inverse_mul_symbols;
|
||||
use crate::constraint_matrix::enc_indices;
|
||||
use crate::base::ObjectTransmissionInformation;
|
||||
use crate::base::partition;
|
||||
use crate::systematic_constants::num_ldpc_symbols;
|
||||
use std::collections::HashSet;
|
||||
|
||||
pub struct Decoder {
|
||||
config: ObjectTransmissionInformation,
|
||||
block_decoders: Vec<SourceBlockDecoder>,
|
||||
blocks: Vec<Option<Vec<u8>>>
|
||||
blocks: Vec<Option<Vec<u8>>>,
|
||||
}
|
||||
|
||||
impl Decoder {
|
||||
@ -24,21 +24,29 @@ impl Decoder {
|
||||
|
||||
// TODO: support subblocks
|
||||
assert_eq!(1, config.sub_blocks());
|
||||
// let (tl, ts, nl, ns) = partition((config.symbol_size() / config.alignment() as u16) as u32, config.sub_blocks() as u32);
|
||||
// let (tl, ts, nl, ns) = partition((config.symbol_size() / config.alignment() as u16) as u32, config.sub_blocks() as u32);
|
||||
|
||||
let mut decoders = vec![];
|
||||
for i in 0..zl {
|
||||
decoders.push(SourceBlockDecoder::new(i as u8, config.symbol_size(), kl as u64 * config.symbol_size() as u64));
|
||||
decoders.push(SourceBlockDecoder::new(
|
||||
i as u8,
|
||||
config.symbol_size(),
|
||||
kl as u64 * config.symbol_size() as u64,
|
||||
));
|
||||
}
|
||||
|
||||
for i in 0..zs {
|
||||
decoders.push(SourceBlockDecoder::new(i as u8, config.symbol_size(), ks as u64 * config.symbol_size() as u64));
|
||||
decoders.push(SourceBlockDecoder::new(
|
||||
i as u8,
|
||||
config.symbol_size(),
|
||||
ks as u64 * config.symbol_size() as u64,
|
||||
));
|
||||
}
|
||||
|
||||
Decoder {
|
||||
config,
|
||||
block_decoders: decoders,
|
||||
blocks: vec![None; (zl + zs) as usize]
|
||||
blocks: vec![None; (zl + zs) as usize],
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,7 +54,6 @@ impl Decoder {
|
||||
let block_number = packet.payload_id().source_block_number() as usize;
|
||||
if self.blocks[block_number].is_none() {
|
||||
self.blocks[block_number] = self.block_decoders[block_number].decode(packet);
|
||||
|
||||
}
|
||||
for block in self.blocks.iter() {
|
||||
if block.is_none() {
|
||||
@ -71,7 +78,7 @@ pub struct SourceBlockDecoder {
|
||||
repair_packets: Vec<EncodingPacket>,
|
||||
received_source_symbols: u32,
|
||||
received_esi: HashSet<u32>,
|
||||
decoded: bool
|
||||
decoded: bool,
|
||||
}
|
||||
|
||||
impl SourceBlockDecoder {
|
||||
@ -89,23 +96,29 @@ impl SourceBlockDecoder {
|
||||
repair_packets: vec![],
|
||||
received_source_symbols: 0,
|
||||
received_esi,
|
||||
decoded: false
|
||||
decoded: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decode(&mut self, packet: EncodingPacket) -> Option<Vec<u8>> {
|
||||
assert_eq!(self.source_block_id, packet.payload_id().source_block_number());
|
||||
assert_eq!(
|
||||
self.source_block_id,
|
||||
packet.payload_id().source_block_number()
|
||||
);
|
||||
let num_extended_symbols = extended_source_block_symbols(self.source_block_symbols);
|
||||
if self.received_esi.insert(packet.payload_id().encoding_symbol_id()) {
|
||||
if self
|
||||
.received_esi
|
||||
.insert(packet.payload_id().encoding_symbol_id())
|
||||
{
|
||||
if packet.payload_id().encoding_symbol_id() >= num_extended_symbols {
|
||||
// Repair symbol
|
||||
self.repair_packets.push(packet);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Check that this is not an extended symbol (which aren't explicitly sent)
|
||||
assert!(packet.payload_id().encoding_symbol_id() < self.source_block_symbols);
|
||||
// Source symbol
|
||||
self.source_symbols[packet.payload_id().encoding_symbol_id() as usize] = Some(Symbol::new(packet.data().clone()));
|
||||
self.source_symbols[packet.payload_id().encoding_symbol_id() as usize] =
|
||||
Some(Symbol::new(packet.data().clone()));
|
||||
self.received_source_symbols += 1;
|
||||
}
|
||||
}
|
||||
@ -147,11 +160,13 @@ impl SourceBlockDecoder {
|
||||
d.push(Symbol::new(repair_packet.data().clone()));
|
||||
}
|
||||
|
||||
let constraint_matrix = generate_constraint_matrix(self.source_block_symbols, &encoded_indices);
|
||||
let intermediate_symbols = fused_inverse_mul_symbols(constraint_matrix, d, self.source_block_symbols);
|
||||
let constraint_matrix =
|
||||
generate_constraint_matrix(self.source_block_symbols, &encoded_indices);
|
||||
let intermediate_symbols =
|
||||
fused_inverse_mul_symbols(constraint_matrix, d, self.source_block_symbols);
|
||||
|
||||
if intermediate_symbols == None {
|
||||
return None
|
||||
return None;
|
||||
}
|
||||
let intermediate_symbols = intermediate_symbols.unwrap();
|
||||
|
||||
@ -159,8 +174,7 @@ impl SourceBlockDecoder {
|
||||
for i in 0..self.source_block_symbols as usize {
|
||||
if self.source_symbols[i] != None {
|
||||
result.extend(self.source_symbols[i].clone().unwrap().bytes())
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
let rebuilt = self.rebuild_source_symbol(&intermediate_symbols, i as u32);
|
||||
result.extend(rebuilt.bytes());
|
||||
}
|
||||
@ -172,7 +186,11 @@ impl SourceBlockDecoder {
|
||||
None
|
||||
}
|
||||
|
||||
fn rebuild_source_symbol(&self, intermediate_symbols: &Vec<Symbol>, source_symbol_id: u32) -> Symbol {
|
||||
fn rebuild_source_symbol(
|
||||
&self,
|
||||
intermediate_symbols: &Vec<Symbol>,
|
||||
source_symbol_id: u32,
|
||||
) -> Symbol {
|
||||
let tuple = intermediate_tuple(self.source_block_symbols, source_symbol_id);
|
||||
|
||||
let mut rebuilt = Symbol::zero(self.symbol_size as usize);
|
||||
@ -182,4 +200,3 @@ impl SourceBlockDecoder {
|
||||
rebuilt
|
||||
}
|
||||
}
|
||||
|
||||
|
108
src/encoder.rs
108
src/encoder.rs
@ -1,63 +1,77 @@
|
||||
use crate::base::intermediate_tuple;
|
||||
use crate::base::partition;
|
||||
use crate::base::EncodingPacket;
|
||||
use crate::base::PayloadId;
|
||||
use crate::systematic_constants::extended_source_block_symbols;
|
||||
use crate::systematic_constants::num_pi_symbols;
|
||||
use crate::constraint_matrix::generate_constraint_matrix;
|
||||
use crate::pi_solver::fused_inverse_mul_symbols;
|
||||
use crate::symbol::Symbol;
|
||||
use crate::systematic_constants::num_lt_symbols;
|
||||
use crate::systematic_constants::calculate_p1;
|
||||
use crate::systematic_constants::extended_source_block_symbols;
|
||||
use crate::systematic_constants::num_hdpc_symbols;
|
||||
use crate::systematic_constants::num_intermediate_symbols;
|
||||
use crate::systematic_constants::num_ldpc_symbols;
|
||||
use crate::systematic_constants::num_hdpc_symbols;
|
||||
use crate::constraint_matrix::generate_constraint_matrix;
|
||||
use crate::base::intermediate_tuple;
|
||||
use crate::pi_solver::fused_inverse_mul_symbols;
|
||||
use crate::base::partition;
|
||||
use crate::systematic_constants::num_lt_symbols;
|
||||
use crate::systematic_constants::num_pi_symbols;
|
||||
use crate::ObjectTransmissionInformation;
|
||||
|
||||
pub struct Encoder {
|
||||
config: ObjectTransmissionInformation,
|
||||
blocks: Vec<SourceBlockEncoder>
|
||||
blocks: Vec<SourceBlockEncoder>,
|
||||
}
|
||||
|
||||
impl Encoder {
|
||||
pub fn with_defaults(data: &[u8], maximum_transmission_unit: u16) -> Encoder {
|
||||
let config = ObjectTransmissionInformation::with_defaults(data.len() as u64, maximum_transmission_unit);
|
||||
let config = ObjectTransmissionInformation::with_defaults(
|
||||
data.len() as u64,
|
||||
maximum_transmission_unit,
|
||||
);
|
||||
|
||||
let kt = (config.transfer_length() as f64 / config.symbol_size() as f64).ceil() as u32;
|
||||
let (kl, ks, zl, zs) = partition(kt, config.source_blocks() as u32);
|
||||
|
||||
// TODO: support subblocks
|
||||
assert_eq!(1, config.sub_blocks());
|
||||
// let (tl, ts, nl, ns) = partition((config.symbol_size() / config.alignment() as u16) as u32, config.sub_blocks() as u32);
|
||||
// let (tl, ts, nl, ns) = partition((config.symbol_size() / config.alignment() as u16) as u32, config.sub_blocks() as u32);
|
||||
|
||||
let mut data_index = 0;
|
||||
let mut blocks = vec![];
|
||||
for i in 0..zl {
|
||||
let offset = kl as usize * config.symbol_size() as usize;
|
||||
blocks.push(SourceBlockEncoder::new(i as u8, config.symbol_size(), &data[data_index..(data_index + offset)]));
|
||||
blocks.push(SourceBlockEncoder::new(
|
||||
i as u8,
|
||||
config.symbol_size(),
|
||||
&data[data_index..(data_index + offset)],
|
||||
));
|
||||
data_index += offset;
|
||||
}
|
||||
|
||||
for i in 0..zs {
|
||||
let offset = ks as usize * config.symbol_size() as usize;
|
||||
if data_index + offset < data.len() {
|
||||
blocks.push(SourceBlockEncoder::new(i as u8, config.symbol_size(), &data[data_index..(data_index + offset)]));
|
||||
}
|
||||
else {
|
||||
blocks.push(SourceBlockEncoder::new(
|
||||
i as u8,
|
||||
config.symbol_size(),
|
||||
&data[data_index..(data_index + offset)],
|
||||
));
|
||||
} else {
|
||||
// Should only be possible when Kt * T > F. See third to last paragraph in section 4.4.1.2
|
||||
assert!(kt as usize * config.symbol_size() as usize > data.len());
|
||||
// Zero pad the last symbol
|
||||
let mut padded = Vec::from(&data[data_index..]);
|
||||
padded.extend(vec![0; kt as usize * config.symbol_size() as usize - data.len()]);
|
||||
blocks.push(SourceBlockEncoder::new(i as u8, config.symbol_size(), &padded));
|
||||
padded.extend(vec![
|
||||
0;
|
||||
kt as usize * config.symbol_size() as usize - data.len()
|
||||
]);
|
||||
blocks.push(SourceBlockEncoder::new(
|
||||
i as u8,
|
||||
config.symbol_size(),
|
||||
&padded,
|
||||
));
|
||||
}
|
||||
data_index += offset;
|
||||
}
|
||||
|
||||
Encoder {
|
||||
config,
|
||||
blocks
|
||||
}
|
||||
Encoder { config, blocks }
|
||||
}
|
||||
|
||||
pub fn get_config(&self) -> ObjectTransmissionInformation {
|
||||
@ -81,43 +95,57 @@ impl Encoder {
|
||||
pub struct SourceBlockEncoder {
|
||||
source_block_id: u8,
|
||||
source_symbols: Vec<Symbol>,
|
||||
intermediate_symbols: Vec<Symbol>
|
||||
intermediate_symbols: Vec<Symbol>,
|
||||
}
|
||||
|
||||
impl SourceBlockEncoder {
|
||||
pub fn new(source_block_id: u8, symbol_size: u16, data: &[u8]) -> SourceBlockEncoder {
|
||||
assert_eq!(data.len() % symbol_size as usize, 0);
|
||||
let source_symbols: Vec<Symbol> = data.chunks(symbol_size as usize)
|
||||
let source_symbols: Vec<Symbol> = data
|
||||
.chunks(symbol_size as usize)
|
||||
.map(|x| Symbol::new(Vec::from(x)))
|
||||
.collect();
|
||||
let intermediate_symbols = gen_intermediate_symbols(&source_symbols, symbol_size as usize);
|
||||
SourceBlockEncoder {
|
||||
source_block_id,
|
||||
source_symbols,
|
||||
intermediate_symbols
|
||||
intermediate_symbols,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn source_packets(&self) -> Vec<EncodingPacket> {
|
||||
let mut esi: i32 = -1;
|
||||
self.source_symbols.iter().map(|symbol| {
|
||||
esi += 1;
|
||||
EncodingPacket::new(
|
||||
PayloadId::new(self.source_block_id, esi as u32),
|
||||
symbol.bytes().clone()
|
||||
)
|
||||
}).collect()
|
||||
self.source_symbols
|
||||
.iter()
|
||||
.map(|symbol| {
|
||||
esi += 1;
|
||||
EncodingPacket::new(
|
||||
PayloadId::new(self.source_block_id, esi as u32),
|
||||
symbol.bytes().clone(),
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
// See section 5.3.4
|
||||
pub fn repair_packets(&self, start_repair_symbol_id: u32, packets: u32) -> Vec<EncodingPacket> {
|
||||
let start_encoding_symbol_id = start_repair_symbol_id + extended_source_block_symbols(self.source_symbols.len() as u32);
|
||||
let start_encoding_symbol_id = start_repair_symbol_id
|
||||
+ extended_source_block_symbols(self.source_symbols.len() as u32);
|
||||
let mut result = vec![];
|
||||
for i in 0..packets {
|
||||
let tuple = intermediate_tuple(self.source_symbols.len() as u32, start_encoding_symbol_id + i);
|
||||
let tuple = intermediate_tuple(
|
||||
self.source_symbols.len() as u32,
|
||||
start_encoding_symbol_id + i,
|
||||
);
|
||||
result.push(EncodingPacket::new(
|
||||
PayloadId::new(self.source_block_id, start_encoding_symbol_id + i),
|
||||
enc(self.source_symbols.len() as u32, &self.intermediate_symbols, tuple).bytes().clone()
|
||||
enc(
|
||||
self.source_symbols.len() as u32,
|
||||
&self.intermediate_symbols,
|
||||
tuple,
|
||||
)
|
||||
.bytes()
|
||||
.clone(),
|
||||
));
|
||||
}
|
||||
result
|
||||
@ -151,9 +179,11 @@ fn gen_intermediate_symbols(source_block: &Vec<Symbol>, symbol_size: usize) -> V
|
||||
}
|
||||
|
||||
// Enc[] function, as defined in section 5.3.5.3
|
||||
fn enc(source_block_symbols: u32,
|
||||
intermediate_symbols: &Vec<Symbol>,
|
||||
source_tuple: (u32, u32, u32, u32, u32, u32)) -> Symbol {
|
||||
fn enc(
|
||||
source_block_symbols: u32,
|
||||
intermediate_symbols: &Vec<Symbol>,
|
||||
source_tuple: (u32, u32, u32, u32, u32, u32),
|
||||
) -> Symbol {
|
||||
let w = num_lt_symbols(source_block_symbols);
|
||||
let p = num_pi_symbols(source_block_symbols);
|
||||
let p1 = calculate_p1(source_block_symbols);
|
||||
@ -192,10 +222,10 @@ fn enc(source_block_symbols: u32,
|
||||
mod tests {
|
||||
use rand::Rng;
|
||||
|
||||
use crate::symbol::Symbol;
|
||||
use crate::encoder::enc;
|
||||
use crate::base::intermediate_tuple;
|
||||
use crate::encoder::enc;
|
||||
use crate::encoder::gen_intermediate_symbols;
|
||||
use crate::symbol::Symbol;
|
||||
use crate::systematic_constants::num_ldpc_symbols;
|
||||
use crate::systematic_constants::num_lt_symbols;
|
||||
use crate::systematic_constants::num_pi_symbols;
|
||||
|
32
src/lib.rs
32
src/lib.rs
@ -1,32 +1,32 @@
|
||||
mod util;
|
||||
mod arraymap;
|
||||
mod systematic_constants;
|
||||
mod rng;
|
||||
mod base;
|
||||
mod constraint_matrix;
|
||||
mod decoder;
|
||||
mod encoder;
|
||||
mod matrix;
|
||||
mod octet;
|
||||
mod octets;
|
||||
mod symbol;
|
||||
mod matrix;
|
||||
mod constraint_matrix;
|
||||
mod base;
|
||||
mod pi_solver;
|
||||
mod encoder;
|
||||
mod decoder;
|
||||
mod rng;
|
||||
mod symbol;
|
||||
mod systematic_constants;
|
||||
mod util;
|
||||
|
||||
pub use crate::base::PayloadId;
|
||||
pub use crate::base::EncodingPacket;
|
||||
pub use crate::base::ObjectTransmissionInformation;
|
||||
pub use crate::encoder::SourceBlockEncoder;
|
||||
pub use crate::encoder::Encoder;
|
||||
pub use crate::decoder::SourceBlockDecoder;
|
||||
pub use crate::base::PayloadId;
|
||||
pub use crate::decoder::Decoder;
|
||||
pub use crate::decoder::SourceBlockDecoder;
|
||||
pub use crate::encoder::Encoder;
|
||||
pub use crate::encoder::SourceBlockEncoder;
|
||||
|
||||
#[cfg(feature = "benchmarking")]
|
||||
pub use crate::constraint_matrix::generate_constraint_matrix;
|
||||
#[cfg(feature = "benchmarking")]
|
||||
pub use crate::systematic_constants::extended_source_block_symbols;
|
||||
pub use crate::octet::Octet;
|
||||
#[cfg(feature = "benchmarking")]
|
||||
pub use crate::pi_solver::IntermediateSymbolDecoder;
|
||||
#[cfg(feature = "benchmarking")]
|
||||
pub use crate::octet::Octet;
|
||||
#[cfg(feature = "benchmarking")]
|
||||
pub use crate::symbol::Symbol;
|
||||
#[cfg(feature = "benchmarking")]
|
||||
pub use crate::systematic_constants::extended_source_block_symbols;
|
||||
|
@ -1,14 +1,14 @@
|
||||
use std::ops::Mul;
|
||||
use crate::octet::Octet;
|
||||
use crate::octets::fused_addassign_mul_scalar;
|
||||
use crate::octets::add_assign;
|
||||
use crate::octets::fused_addassign_mul_scalar;
|
||||
use crate::util::get_both_indices;
|
||||
use std::ops::Mul;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct OctetMatrix {
|
||||
height: usize,
|
||||
width: usize,
|
||||
elements: Vec<Vec<u8>>
|
||||
elements: Vec<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl OctetMatrix {
|
||||
@ -20,7 +20,7 @@ impl OctetMatrix {
|
||||
OctetMatrix {
|
||||
height,
|
||||
width,
|
||||
elements
|
||||
elements,
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ impl OctetMatrix {
|
||||
Octet::new(self.elements[i][j])
|
||||
}
|
||||
|
||||
pub fn swap_rows(&mut self, i: usize, j:usize) {
|
||||
pub fn swap_rows(&mut self, i: usize, j: usize) {
|
||||
self.elements.swap(i, j);
|
||||
}
|
||||
|
||||
@ -73,8 +73,7 @@ impl OctetMatrix {
|
||||
}
|
||||
if scalar == Octet::one() {
|
||||
add_assign(&mut temp[row], &self.elements[i]);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
fused_addassign_mul_scalar(&mut temp[row], &self.elements[i], &scalar);
|
||||
}
|
||||
}
|
||||
@ -90,8 +89,7 @@ impl OctetMatrix {
|
||||
|
||||
if *scalar == Octet::one() {
|
||||
add_assign(dest_row, temp_row);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
fused_addassign_mul_scalar(dest_row, temp_row, scalar);
|
||||
}
|
||||
}
|
||||
@ -122,9 +120,12 @@ impl<'a, 'b> Mul<&'b OctetMatrix> for &'a OctetMatrix {
|
||||
}
|
||||
if scalar == Octet::one() {
|
||||
add_assign(&mut result.elements[row], &rhs.elements[i]);
|
||||
}
|
||||
else {
|
||||
fused_addassign_mul_scalar(&mut result.elements[row], &rhs.elements[i], &scalar);
|
||||
} else {
|
||||
fused_addassign_mul_scalar(
|
||||
&mut result.elements[row],
|
||||
&rhs.elements[i],
|
||||
&scalar,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
182
src/octet.rs
182
src/octet.rs
@ -1,8 +1,8 @@
|
||||
use std::ops::Add;
|
||||
use std::ops::Mul;
|
||||
use std::ops::Div;
|
||||
use std::ops::Sub;
|
||||
use std::ops::AddAssign;
|
||||
use std::ops::Div;
|
||||
use std::ops::Mul;
|
||||
use std::ops::Sub;
|
||||
|
||||
// As defined in section 5.7.3
|
||||
#[rustfmt::skip]
|
||||
@ -88,7 +88,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(7),
|
||||
calculate_octet_mul_hi_table_inner(8),
|
||||
calculate_octet_mul_hi_table_inner(9),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(10),
|
||||
calculate_octet_mul_hi_table_inner(11),
|
||||
calculate_octet_mul_hi_table_inner(12),
|
||||
@ -99,7 +98,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(17),
|
||||
calculate_octet_mul_hi_table_inner(18),
|
||||
calculate_octet_mul_hi_table_inner(19),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(20),
|
||||
calculate_octet_mul_hi_table_inner(21),
|
||||
calculate_octet_mul_hi_table_inner(22),
|
||||
@ -110,7 +108,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(27),
|
||||
calculate_octet_mul_hi_table_inner(28),
|
||||
calculate_octet_mul_hi_table_inner(29),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(30),
|
||||
calculate_octet_mul_hi_table_inner(31),
|
||||
calculate_octet_mul_hi_table_inner(32),
|
||||
@ -121,7 +118,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(37),
|
||||
calculate_octet_mul_hi_table_inner(38),
|
||||
calculate_octet_mul_hi_table_inner(39),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(40),
|
||||
calculate_octet_mul_hi_table_inner(41),
|
||||
calculate_octet_mul_hi_table_inner(42),
|
||||
@ -132,7 +128,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(47),
|
||||
calculate_octet_mul_hi_table_inner(48),
|
||||
calculate_octet_mul_hi_table_inner(49),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(50),
|
||||
calculate_octet_mul_hi_table_inner(51),
|
||||
calculate_octet_mul_hi_table_inner(52),
|
||||
@ -143,7 +138,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(57),
|
||||
calculate_octet_mul_hi_table_inner(58),
|
||||
calculate_octet_mul_hi_table_inner(59),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(60),
|
||||
calculate_octet_mul_hi_table_inner(61),
|
||||
calculate_octet_mul_hi_table_inner(62),
|
||||
@ -154,7 +148,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(67),
|
||||
calculate_octet_mul_hi_table_inner(68),
|
||||
calculate_octet_mul_hi_table_inner(69),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(70),
|
||||
calculate_octet_mul_hi_table_inner(71),
|
||||
calculate_octet_mul_hi_table_inner(72),
|
||||
@ -165,7 +158,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(77),
|
||||
calculate_octet_mul_hi_table_inner(78),
|
||||
calculate_octet_mul_hi_table_inner(79),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(80),
|
||||
calculate_octet_mul_hi_table_inner(81),
|
||||
calculate_octet_mul_hi_table_inner(82),
|
||||
@ -176,7 +168,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(87),
|
||||
calculate_octet_mul_hi_table_inner(88),
|
||||
calculate_octet_mul_hi_table_inner(89),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(90),
|
||||
calculate_octet_mul_hi_table_inner(91),
|
||||
calculate_octet_mul_hi_table_inner(92),
|
||||
@ -187,7 +178,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(97),
|
||||
calculate_octet_mul_hi_table_inner(98),
|
||||
calculate_octet_mul_hi_table_inner(99),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(100),
|
||||
calculate_octet_mul_hi_table_inner(101),
|
||||
calculate_octet_mul_hi_table_inner(102),
|
||||
@ -198,7 +188,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(107),
|
||||
calculate_octet_mul_hi_table_inner(108),
|
||||
calculate_octet_mul_hi_table_inner(109),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(110),
|
||||
calculate_octet_mul_hi_table_inner(111),
|
||||
calculate_octet_mul_hi_table_inner(112),
|
||||
@ -209,7 +198,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(117),
|
||||
calculate_octet_mul_hi_table_inner(118),
|
||||
calculate_octet_mul_hi_table_inner(119),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(120),
|
||||
calculate_octet_mul_hi_table_inner(121),
|
||||
calculate_octet_mul_hi_table_inner(122),
|
||||
@ -220,7 +208,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(127),
|
||||
calculate_octet_mul_hi_table_inner(128),
|
||||
calculate_octet_mul_hi_table_inner(129),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(130),
|
||||
calculate_octet_mul_hi_table_inner(131),
|
||||
calculate_octet_mul_hi_table_inner(132),
|
||||
@ -231,7 +218,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(137),
|
||||
calculate_octet_mul_hi_table_inner(138),
|
||||
calculate_octet_mul_hi_table_inner(139),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(140),
|
||||
calculate_octet_mul_hi_table_inner(141),
|
||||
calculate_octet_mul_hi_table_inner(142),
|
||||
@ -242,7 +228,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(147),
|
||||
calculate_octet_mul_hi_table_inner(148),
|
||||
calculate_octet_mul_hi_table_inner(149),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(150),
|
||||
calculate_octet_mul_hi_table_inner(151),
|
||||
calculate_octet_mul_hi_table_inner(152),
|
||||
@ -253,7 +238,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(157),
|
||||
calculate_octet_mul_hi_table_inner(158),
|
||||
calculate_octet_mul_hi_table_inner(159),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(160),
|
||||
calculate_octet_mul_hi_table_inner(161),
|
||||
calculate_octet_mul_hi_table_inner(162),
|
||||
@ -264,7 +248,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(167),
|
||||
calculate_octet_mul_hi_table_inner(168),
|
||||
calculate_octet_mul_hi_table_inner(169),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(170),
|
||||
calculate_octet_mul_hi_table_inner(171),
|
||||
calculate_octet_mul_hi_table_inner(172),
|
||||
@ -275,7 +258,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(177),
|
||||
calculate_octet_mul_hi_table_inner(178),
|
||||
calculate_octet_mul_hi_table_inner(179),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(180),
|
||||
calculate_octet_mul_hi_table_inner(181),
|
||||
calculate_octet_mul_hi_table_inner(182),
|
||||
@ -286,7 +268,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(187),
|
||||
calculate_octet_mul_hi_table_inner(188),
|
||||
calculate_octet_mul_hi_table_inner(189),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(190),
|
||||
calculate_octet_mul_hi_table_inner(191),
|
||||
calculate_octet_mul_hi_table_inner(192),
|
||||
@ -297,7 +278,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(197),
|
||||
calculate_octet_mul_hi_table_inner(198),
|
||||
calculate_octet_mul_hi_table_inner(199),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(200),
|
||||
calculate_octet_mul_hi_table_inner(201),
|
||||
calculate_octet_mul_hi_table_inner(202),
|
||||
@ -308,7 +288,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(207),
|
||||
calculate_octet_mul_hi_table_inner(208),
|
||||
calculate_octet_mul_hi_table_inner(209),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(210),
|
||||
calculate_octet_mul_hi_table_inner(211),
|
||||
calculate_octet_mul_hi_table_inner(212),
|
||||
@ -319,7 +298,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(217),
|
||||
calculate_octet_mul_hi_table_inner(218),
|
||||
calculate_octet_mul_hi_table_inner(219),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(220),
|
||||
calculate_octet_mul_hi_table_inner(221),
|
||||
calculate_octet_mul_hi_table_inner(222),
|
||||
@ -330,7 +308,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(227),
|
||||
calculate_octet_mul_hi_table_inner(228),
|
||||
calculate_octet_mul_hi_table_inner(229),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(230),
|
||||
calculate_octet_mul_hi_table_inner(231),
|
||||
calculate_octet_mul_hi_table_inner(232),
|
||||
@ -341,7 +318,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(237),
|
||||
calculate_octet_mul_hi_table_inner(238),
|
||||
calculate_octet_mul_hi_table_inner(239),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(240),
|
||||
calculate_octet_mul_hi_table_inner(241),
|
||||
calculate_octet_mul_hi_table_inner(242),
|
||||
@ -352,7 +328,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_hi_table_inner(247),
|
||||
calculate_octet_mul_hi_table_inner(248),
|
||||
calculate_octet_mul_hi_table_inner(249),
|
||||
|
||||
calculate_octet_mul_hi_table_inner(250),
|
||||
calculate_octet_mul_hi_table_inner(251),
|
||||
calculate_octet_mul_hi_table_inner(252),
|
||||
@ -368,42 +343,35 @@ const fn calculate_octet_mul_hi_table_inner(x: usize) -> [u8; 32] {
|
||||
const_mul(x, 1 << 4),
|
||||
const_mul(x, 2 << 4),
|
||||
const_mul(x, 3 << 4),
|
||||
|
||||
const_mul(x, 4 << 4),
|
||||
const_mul(x, 5 << 4),
|
||||
const_mul(x, 6 << 4),
|
||||
const_mul(x, 7 << 4),
|
||||
|
||||
const_mul(x, 8 << 4),
|
||||
const_mul(x, 9 << 4),
|
||||
const_mul(x, 10 << 4),
|
||||
const_mul(x, 11 << 4),
|
||||
|
||||
const_mul(x, 12 << 4),
|
||||
const_mul(x, 13 << 4),
|
||||
const_mul(x, 14 << 4),
|
||||
const_mul(x, 15 << 4),
|
||||
|
||||
0,
|
||||
const_mul(x, 1 << 4),
|
||||
const_mul(x, 2 << 4),
|
||||
const_mul(x, 3 << 4),
|
||||
|
||||
const_mul(x, 4 << 4),
|
||||
const_mul(x, 5 << 4),
|
||||
const_mul(x, 6 << 4),
|
||||
const_mul(x, 7 << 4),
|
||||
|
||||
const_mul(x, 8 << 4),
|
||||
const_mul(x, 9 << 4),
|
||||
const_mul(x, 10 << 4),
|
||||
const_mul(x, 11 << 4),
|
||||
|
||||
const_mul(x, 12 << 4),
|
||||
const_mul(x, 13 << 4),
|
||||
const_mul(x, 14 << 4),
|
||||
const_mul(x, 15 << 4),
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
@ -418,7 +386,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(7),
|
||||
calculate_octet_mul_low_table_inner(8),
|
||||
calculate_octet_mul_low_table_inner(9),
|
||||
|
||||
calculate_octet_mul_low_table_inner(10),
|
||||
calculate_octet_mul_low_table_inner(11),
|
||||
calculate_octet_mul_low_table_inner(12),
|
||||
@ -429,7 +396,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(17),
|
||||
calculate_octet_mul_low_table_inner(18),
|
||||
calculate_octet_mul_low_table_inner(19),
|
||||
|
||||
calculate_octet_mul_low_table_inner(20),
|
||||
calculate_octet_mul_low_table_inner(21),
|
||||
calculate_octet_mul_low_table_inner(22),
|
||||
@ -440,7 +406,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(27),
|
||||
calculate_octet_mul_low_table_inner(28),
|
||||
calculate_octet_mul_low_table_inner(29),
|
||||
|
||||
calculate_octet_mul_low_table_inner(30),
|
||||
calculate_octet_mul_low_table_inner(31),
|
||||
calculate_octet_mul_low_table_inner(32),
|
||||
@ -451,7 +416,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(37),
|
||||
calculate_octet_mul_low_table_inner(38),
|
||||
calculate_octet_mul_low_table_inner(39),
|
||||
|
||||
calculate_octet_mul_low_table_inner(40),
|
||||
calculate_octet_mul_low_table_inner(41),
|
||||
calculate_octet_mul_low_table_inner(42),
|
||||
@ -462,7 +426,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(47),
|
||||
calculate_octet_mul_low_table_inner(48),
|
||||
calculate_octet_mul_low_table_inner(49),
|
||||
|
||||
calculate_octet_mul_low_table_inner(50),
|
||||
calculate_octet_mul_low_table_inner(51),
|
||||
calculate_octet_mul_low_table_inner(52),
|
||||
@ -473,7 +436,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(57),
|
||||
calculate_octet_mul_low_table_inner(58),
|
||||
calculate_octet_mul_low_table_inner(59),
|
||||
|
||||
calculate_octet_mul_low_table_inner(60),
|
||||
calculate_octet_mul_low_table_inner(61),
|
||||
calculate_octet_mul_low_table_inner(62),
|
||||
@ -484,7 +446,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(67),
|
||||
calculate_octet_mul_low_table_inner(68),
|
||||
calculate_octet_mul_low_table_inner(69),
|
||||
|
||||
calculate_octet_mul_low_table_inner(70),
|
||||
calculate_octet_mul_low_table_inner(71),
|
||||
calculate_octet_mul_low_table_inner(72),
|
||||
@ -495,7 +456,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(77),
|
||||
calculate_octet_mul_low_table_inner(78),
|
||||
calculate_octet_mul_low_table_inner(79),
|
||||
|
||||
calculate_octet_mul_low_table_inner(80),
|
||||
calculate_octet_mul_low_table_inner(81),
|
||||
calculate_octet_mul_low_table_inner(82),
|
||||
@ -506,7 +466,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(87),
|
||||
calculate_octet_mul_low_table_inner(88),
|
||||
calculate_octet_mul_low_table_inner(89),
|
||||
|
||||
calculate_octet_mul_low_table_inner(90),
|
||||
calculate_octet_mul_low_table_inner(91),
|
||||
calculate_octet_mul_low_table_inner(92),
|
||||
@ -517,7 +476,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(97),
|
||||
calculate_octet_mul_low_table_inner(98),
|
||||
calculate_octet_mul_low_table_inner(99),
|
||||
|
||||
calculate_octet_mul_low_table_inner(100),
|
||||
calculate_octet_mul_low_table_inner(101),
|
||||
calculate_octet_mul_low_table_inner(102),
|
||||
@ -528,7 +486,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(107),
|
||||
calculate_octet_mul_low_table_inner(108),
|
||||
calculate_octet_mul_low_table_inner(109),
|
||||
|
||||
calculate_octet_mul_low_table_inner(110),
|
||||
calculate_octet_mul_low_table_inner(111),
|
||||
calculate_octet_mul_low_table_inner(112),
|
||||
@ -539,7 +496,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(117),
|
||||
calculate_octet_mul_low_table_inner(118),
|
||||
calculate_octet_mul_low_table_inner(119),
|
||||
|
||||
calculate_octet_mul_low_table_inner(120),
|
||||
calculate_octet_mul_low_table_inner(121),
|
||||
calculate_octet_mul_low_table_inner(122),
|
||||
@ -550,7 +506,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(127),
|
||||
calculate_octet_mul_low_table_inner(128),
|
||||
calculate_octet_mul_low_table_inner(129),
|
||||
|
||||
calculate_octet_mul_low_table_inner(130),
|
||||
calculate_octet_mul_low_table_inner(131),
|
||||
calculate_octet_mul_low_table_inner(132),
|
||||
@ -561,7 +516,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(137),
|
||||
calculate_octet_mul_low_table_inner(138),
|
||||
calculate_octet_mul_low_table_inner(139),
|
||||
|
||||
calculate_octet_mul_low_table_inner(140),
|
||||
calculate_octet_mul_low_table_inner(141),
|
||||
calculate_octet_mul_low_table_inner(142),
|
||||
@ -572,7 +526,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(147),
|
||||
calculate_octet_mul_low_table_inner(148),
|
||||
calculate_octet_mul_low_table_inner(149),
|
||||
|
||||
calculate_octet_mul_low_table_inner(150),
|
||||
calculate_octet_mul_low_table_inner(151),
|
||||
calculate_octet_mul_low_table_inner(152),
|
||||
@ -583,7 +536,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(157),
|
||||
calculate_octet_mul_low_table_inner(158),
|
||||
calculate_octet_mul_low_table_inner(159),
|
||||
|
||||
calculate_octet_mul_low_table_inner(160),
|
||||
calculate_octet_mul_low_table_inner(161),
|
||||
calculate_octet_mul_low_table_inner(162),
|
||||
@ -594,7 +546,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(167),
|
||||
calculate_octet_mul_low_table_inner(168),
|
||||
calculate_octet_mul_low_table_inner(169),
|
||||
|
||||
calculate_octet_mul_low_table_inner(170),
|
||||
calculate_octet_mul_low_table_inner(171),
|
||||
calculate_octet_mul_low_table_inner(172),
|
||||
@ -605,7 +556,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(177),
|
||||
calculate_octet_mul_low_table_inner(178),
|
||||
calculate_octet_mul_low_table_inner(179),
|
||||
|
||||
calculate_octet_mul_low_table_inner(180),
|
||||
calculate_octet_mul_low_table_inner(181),
|
||||
calculate_octet_mul_low_table_inner(182),
|
||||
@ -616,7 +566,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(187),
|
||||
calculate_octet_mul_low_table_inner(188),
|
||||
calculate_octet_mul_low_table_inner(189),
|
||||
|
||||
calculate_octet_mul_low_table_inner(190),
|
||||
calculate_octet_mul_low_table_inner(191),
|
||||
calculate_octet_mul_low_table_inner(192),
|
||||
@ -627,7 +576,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(197),
|
||||
calculate_octet_mul_low_table_inner(198),
|
||||
calculate_octet_mul_low_table_inner(199),
|
||||
|
||||
calculate_octet_mul_low_table_inner(200),
|
||||
calculate_octet_mul_low_table_inner(201),
|
||||
calculate_octet_mul_low_table_inner(202),
|
||||
@ -638,7 +586,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(207),
|
||||
calculate_octet_mul_low_table_inner(208),
|
||||
calculate_octet_mul_low_table_inner(209),
|
||||
|
||||
calculate_octet_mul_low_table_inner(210),
|
||||
calculate_octet_mul_low_table_inner(211),
|
||||
calculate_octet_mul_low_table_inner(212),
|
||||
@ -649,7 +596,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(217),
|
||||
calculate_octet_mul_low_table_inner(218),
|
||||
calculate_octet_mul_low_table_inner(219),
|
||||
|
||||
calculate_octet_mul_low_table_inner(220),
|
||||
calculate_octet_mul_low_table_inner(221),
|
||||
calculate_octet_mul_low_table_inner(222),
|
||||
@ -660,7 +606,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(227),
|
||||
calculate_octet_mul_low_table_inner(228),
|
||||
calculate_octet_mul_low_table_inner(229),
|
||||
|
||||
calculate_octet_mul_low_table_inner(230),
|
||||
calculate_octet_mul_low_table_inner(231),
|
||||
calculate_octet_mul_low_table_inner(232),
|
||||
@ -671,7 +616,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(237),
|
||||
calculate_octet_mul_low_table_inner(238),
|
||||
calculate_octet_mul_low_table_inner(239),
|
||||
|
||||
calculate_octet_mul_low_table_inner(240),
|
||||
calculate_octet_mul_low_table_inner(241),
|
||||
calculate_octet_mul_low_table_inner(242),
|
||||
@ -682,7 +626,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
|
||||
calculate_octet_mul_low_table_inner(247),
|
||||
calculate_octet_mul_low_table_inner(248),
|
||||
calculate_octet_mul_low_table_inner(249),
|
||||
|
||||
calculate_octet_mul_low_table_inner(250),
|
||||
calculate_octet_mul_low_table_inner(251),
|
||||
calculate_octet_mul_low_table_inner(252),
|
||||
@ -698,42 +641,35 @@ const fn calculate_octet_mul_low_table_inner(x: usize) -> [u8; 32] {
|
||||
const_mul(x, 1),
|
||||
const_mul(x, 2),
|
||||
const_mul(x, 3),
|
||||
|
||||
const_mul(x, 4),
|
||||
const_mul(x, 5),
|
||||
const_mul(x, 6),
|
||||
const_mul(x, 7),
|
||||
|
||||
const_mul(x, 8),
|
||||
const_mul(x, 9),
|
||||
const_mul(x, 10),
|
||||
const_mul(x, 11),
|
||||
|
||||
const_mul(x, 12),
|
||||
const_mul(x, 13),
|
||||
const_mul(x, 14),
|
||||
const_mul(x, 15),
|
||||
|
||||
0,
|
||||
const_mul(x, 1),
|
||||
const_mul(x, 2),
|
||||
const_mul(x, 3),
|
||||
|
||||
const_mul(x, 4),
|
||||
const_mul(x, 5),
|
||||
const_mul(x, 6),
|
||||
const_mul(x, 7),
|
||||
|
||||
const_mul(x, 8),
|
||||
const_mul(x, 9),
|
||||
const_mul(x, 10),
|
||||
const_mul(x, 11),
|
||||
|
||||
const_mul(x, 12),
|
||||
const_mul(x, 13),
|
||||
const_mul(x, 14),
|
||||
const_mul(x, 15),
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
@ -748,7 +684,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(7),
|
||||
calculate_octet_mul_table_inner(8),
|
||||
calculate_octet_mul_table_inner(9),
|
||||
|
||||
calculate_octet_mul_table_inner(10),
|
||||
calculate_octet_mul_table_inner(11),
|
||||
calculate_octet_mul_table_inner(12),
|
||||
@ -759,7 +694,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(17),
|
||||
calculate_octet_mul_table_inner(18),
|
||||
calculate_octet_mul_table_inner(19),
|
||||
|
||||
calculate_octet_mul_table_inner(20),
|
||||
calculate_octet_mul_table_inner(21),
|
||||
calculate_octet_mul_table_inner(22),
|
||||
@ -770,7 +704,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(27),
|
||||
calculate_octet_mul_table_inner(28),
|
||||
calculate_octet_mul_table_inner(29),
|
||||
|
||||
calculate_octet_mul_table_inner(30),
|
||||
calculate_octet_mul_table_inner(31),
|
||||
calculate_octet_mul_table_inner(32),
|
||||
@ -781,7 +714,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(37),
|
||||
calculate_octet_mul_table_inner(38),
|
||||
calculate_octet_mul_table_inner(39),
|
||||
|
||||
calculate_octet_mul_table_inner(40),
|
||||
calculate_octet_mul_table_inner(41),
|
||||
calculate_octet_mul_table_inner(42),
|
||||
@ -792,7 +724,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(47),
|
||||
calculate_octet_mul_table_inner(48),
|
||||
calculate_octet_mul_table_inner(49),
|
||||
|
||||
calculate_octet_mul_table_inner(50),
|
||||
calculate_octet_mul_table_inner(51),
|
||||
calculate_octet_mul_table_inner(52),
|
||||
@ -803,7 +734,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(57),
|
||||
calculate_octet_mul_table_inner(58),
|
||||
calculate_octet_mul_table_inner(59),
|
||||
|
||||
calculate_octet_mul_table_inner(60),
|
||||
calculate_octet_mul_table_inner(61),
|
||||
calculate_octet_mul_table_inner(62),
|
||||
@ -814,7 +744,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(67),
|
||||
calculate_octet_mul_table_inner(68),
|
||||
calculate_octet_mul_table_inner(69),
|
||||
|
||||
calculate_octet_mul_table_inner(70),
|
||||
calculate_octet_mul_table_inner(71),
|
||||
calculate_octet_mul_table_inner(72),
|
||||
@ -825,7 +754,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(77),
|
||||
calculate_octet_mul_table_inner(78),
|
||||
calculate_octet_mul_table_inner(79),
|
||||
|
||||
calculate_octet_mul_table_inner(80),
|
||||
calculate_octet_mul_table_inner(81),
|
||||
calculate_octet_mul_table_inner(82),
|
||||
@ -836,7 +764,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(87),
|
||||
calculate_octet_mul_table_inner(88),
|
||||
calculate_octet_mul_table_inner(89),
|
||||
|
||||
calculate_octet_mul_table_inner(90),
|
||||
calculate_octet_mul_table_inner(91),
|
||||
calculate_octet_mul_table_inner(92),
|
||||
@ -847,7 +774,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(97),
|
||||
calculate_octet_mul_table_inner(98),
|
||||
calculate_octet_mul_table_inner(99),
|
||||
|
||||
calculate_octet_mul_table_inner(100),
|
||||
calculate_octet_mul_table_inner(101),
|
||||
calculate_octet_mul_table_inner(102),
|
||||
@ -858,7 +784,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(107),
|
||||
calculate_octet_mul_table_inner(108),
|
||||
calculate_octet_mul_table_inner(109),
|
||||
|
||||
calculate_octet_mul_table_inner(110),
|
||||
calculate_octet_mul_table_inner(111),
|
||||
calculate_octet_mul_table_inner(112),
|
||||
@ -869,7 +794,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(117),
|
||||
calculate_octet_mul_table_inner(118),
|
||||
calculate_octet_mul_table_inner(119),
|
||||
|
||||
calculate_octet_mul_table_inner(120),
|
||||
calculate_octet_mul_table_inner(121),
|
||||
calculate_octet_mul_table_inner(122),
|
||||
@ -880,7 +804,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(127),
|
||||
calculate_octet_mul_table_inner(128),
|
||||
calculate_octet_mul_table_inner(129),
|
||||
|
||||
calculate_octet_mul_table_inner(130),
|
||||
calculate_octet_mul_table_inner(131),
|
||||
calculate_octet_mul_table_inner(132),
|
||||
@ -891,7 +814,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(137),
|
||||
calculate_octet_mul_table_inner(138),
|
||||
calculate_octet_mul_table_inner(139),
|
||||
|
||||
calculate_octet_mul_table_inner(140),
|
||||
calculate_octet_mul_table_inner(141),
|
||||
calculate_octet_mul_table_inner(142),
|
||||
@ -902,7 +824,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(147),
|
||||
calculate_octet_mul_table_inner(148),
|
||||
calculate_octet_mul_table_inner(149),
|
||||
|
||||
calculate_octet_mul_table_inner(150),
|
||||
calculate_octet_mul_table_inner(151),
|
||||
calculate_octet_mul_table_inner(152),
|
||||
@ -913,7 +834,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(157),
|
||||
calculate_octet_mul_table_inner(158),
|
||||
calculate_octet_mul_table_inner(159),
|
||||
|
||||
calculate_octet_mul_table_inner(160),
|
||||
calculate_octet_mul_table_inner(161),
|
||||
calculate_octet_mul_table_inner(162),
|
||||
@ -924,7 +844,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(167),
|
||||
calculate_octet_mul_table_inner(168),
|
||||
calculate_octet_mul_table_inner(169),
|
||||
|
||||
calculate_octet_mul_table_inner(170),
|
||||
calculate_octet_mul_table_inner(171),
|
||||
calculate_octet_mul_table_inner(172),
|
||||
@ -935,7 +854,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(177),
|
||||
calculate_octet_mul_table_inner(178),
|
||||
calculate_octet_mul_table_inner(179),
|
||||
|
||||
calculate_octet_mul_table_inner(180),
|
||||
calculate_octet_mul_table_inner(181),
|
||||
calculate_octet_mul_table_inner(182),
|
||||
@ -946,7 +864,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(187),
|
||||
calculate_octet_mul_table_inner(188),
|
||||
calculate_octet_mul_table_inner(189),
|
||||
|
||||
calculate_octet_mul_table_inner(190),
|
||||
calculate_octet_mul_table_inner(191),
|
||||
calculate_octet_mul_table_inner(192),
|
||||
@ -957,7 +874,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(197),
|
||||
calculate_octet_mul_table_inner(198),
|
||||
calculate_octet_mul_table_inner(199),
|
||||
|
||||
calculate_octet_mul_table_inner(200),
|
||||
calculate_octet_mul_table_inner(201),
|
||||
calculate_octet_mul_table_inner(202),
|
||||
@ -968,7 +884,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(207),
|
||||
calculate_octet_mul_table_inner(208),
|
||||
calculate_octet_mul_table_inner(209),
|
||||
|
||||
calculate_octet_mul_table_inner(210),
|
||||
calculate_octet_mul_table_inner(211),
|
||||
calculate_octet_mul_table_inner(212),
|
||||
@ -979,7 +894,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(217),
|
||||
calculate_octet_mul_table_inner(218),
|
||||
calculate_octet_mul_table_inner(219),
|
||||
|
||||
calculate_octet_mul_table_inner(220),
|
||||
calculate_octet_mul_table_inner(221),
|
||||
calculate_octet_mul_table_inner(222),
|
||||
@ -990,7 +904,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(227),
|
||||
calculate_octet_mul_table_inner(228),
|
||||
calculate_octet_mul_table_inner(229),
|
||||
|
||||
calculate_octet_mul_table_inner(230),
|
||||
calculate_octet_mul_table_inner(231),
|
||||
calculate_octet_mul_table_inner(232),
|
||||
@ -1001,7 +914,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(237),
|
||||
calculate_octet_mul_table_inner(238),
|
||||
calculate_octet_mul_table_inner(239),
|
||||
|
||||
calculate_octet_mul_table_inner(240),
|
||||
calculate_octet_mul_table_inner(241),
|
||||
calculate_octet_mul_table_inner(242),
|
||||
@ -1012,7 +924,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
|
||||
calculate_octet_mul_table_inner(247),
|
||||
calculate_octet_mul_table_inner(248),
|
||||
calculate_octet_mul_table_inner(249),
|
||||
|
||||
calculate_octet_mul_table_inner(250),
|
||||
calculate_octet_mul_table_inner(251),
|
||||
calculate_octet_mul_table_inner(252),
|
||||
@ -1034,7 +945,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 7),
|
||||
const_mul(x, 8),
|
||||
const_mul(x, 9),
|
||||
|
||||
const_mul(x, 10),
|
||||
const_mul(x, 11),
|
||||
const_mul(x, 12),
|
||||
@ -1045,7 +955,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 17),
|
||||
const_mul(x, 18),
|
||||
const_mul(x, 19),
|
||||
|
||||
const_mul(x, 20),
|
||||
const_mul(x, 21),
|
||||
const_mul(x, 22),
|
||||
@ -1056,7 +965,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 27),
|
||||
const_mul(x, 28),
|
||||
const_mul(x, 29),
|
||||
|
||||
const_mul(x, 30),
|
||||
const_mul(x, 31),
|
||||
const_mul(x, 32),
|
||||
@ -1067,7 +975,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 37),
|
||||
const_mul(x, 38),
|
||||
const_mul(x, 39),
|
||||
|
||||
const_mul(x, 40),
|
||||
const_mul(x, 41),
|
||||
const_mul(x, 42),
|
||||
@ -1078,7 +985,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 47),
|
||||
const_mul(x, 48),
|
||||
const_mul(x, 49),
|
||||
|
||||
const_mul(x, 50),
|
||||
const_mul(x, 51),
|
||||
const_mul(x, 52),
|
||||
@ -1089,7 +995,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 57),
|
||||
const_mul(x, 58),
|
||||
const_mul(x, 59),
|
||||
|
||||
const_mul(x, 60),
|
||||
const_mul(x, 61),
|
||||
const_mul(x, 62),
|
||||
@ -1100,7 +1005,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 67),
|
||||
const_mul(x, 68),
|
||||
const_mul(x, 69),
|
||||
|
||||
const_mul(x, 70),
|
||||
const_mul(x, 71),
|
||||
const_mul(x, 72),
|
||||
@ -1111,7 +1015,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 77),
|
||||
const_mul(x, 78),
|
||||
const_mul(x, 79),
|
||||
|
||||
const_mul(x, 80),
|
||||
const_mul(x, 81),
|
||||
const_mul(x, 82),
|
||||
@ -1122,7 +1025,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 87),
|
||||
const_mul(x, 88),
|
||||
const_mul(x, 89),
|
||||
|
||||
const_mul(x, 90),
|
||||
const_mul(x, 91),
|
||||
const_mul(x, 92),
|
||||
@ -1133,7 +1035,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 97),
|
||||
const_mul(x, 98),
|
||||
const_mul(x, 99),
|
||||
|
||||
const_mul(x, 100),
|
||||
const_mul(x, 101),
|
||||
const_mul(x, 102),
|
||||
@ -1144,7 +1045,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 107),
|
||||
const_mul(x, 108),
|
||||
const_mul(x, 109),
|
||||
|
||||
const_mul(x, 110),
|
||||
const_mul(x, 111),
|
||||
const_mul(x, 112),
|
||||
@ -1155,7 +1055,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 117),
|
||||
const_mul(x, 118),
|
||||
const_mul(x, 119),
|
||||
|
||||
const_mul(x, 120),
|
||||
const_mul(x, 121),
|
||||
const_mul(x, 122),
|
||||
@ -1166,7 +1065,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 127),
|
||||
const_mul(x, 128),
|
||||
const_mul(x, 129),
|
||||
|
||||
const_mul(x, 130),
|
||||
const_mul(x, 131),
|
||||
const_mul(x, 132),
|
||||
@ -1177,7 +1075,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 137),
|
||||
const_mul(x, 138),
|
||||
const_mul(x, 139),
|
||||
|
||||
const_mul(x, 140),
|
||||
const_mul(x, 141),
|
||||
const_mul(x, 142),
|
||||
@ -1188,7 +1085,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 147),
|
||||
const_mul(x, 148),
|
||||
const_mul(x, 149),
|
||||
|
||||
const_mul(x, 150),
|
||||
const_mul(x, 151),
|
||||
const_mul(x, 152),
|
||||
@ -1199,7 +1095,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 157),
|
||||
const_mul(x, 158),
|
||||
const_mul(x, 159),
|
||||
|
||||
const_mul(x, 160),
|
||||
const_mul(x, 161),
|
||||
const_mul(x, 162),
|
||||
@ -1210,7 +1105,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 167),
|
||||
const_mul(x, 168),
|
||||
const_mul(x, 169),
|
||||
|
||||
const_mul(x, 170),
|
||||
const_mul(x, 171),
|
||||
const_mul(x, 172),
|
||||
@ -1221,7 +1115,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 177),
|
||||
const_mul(x, 178),
|
||||
const_mul(x, 179),
|
||||
|
||||
const_mul(x, 180),
|
||||
const_mul(x, 181),
|
||||
const_mul(x, 182),
|
||||
@ -1232,7 +1125,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 187),
|
||||
const_mul(x, 188),
|
||||
const_mul(x, 189),
|
||||
|
||||
const_mul(x, 190),
|
||||
const_mul(x, 191),
|
||||
const_mul(x, 192),
|
||||
@ -1243,7 +1135,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 197),
|
||||
const_mul(x, 198),
|
||||
const_mul(x, 199),
|
||||
|
||||
const_mul(x, 200),
|
||||
const_mul(x, 201),
|
||||
const_mul(x, 202),
|
||||
@ -1254,7 +1145,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 207),
|
||||
const_mul(x, 208),
|
||||
const_mul(x, 209),
|
||||
|
||||
const_mul(x, 210),
|
||||
const_mul(x, 211),
|
||||
const_mul(x, 212),
|
||||
@ -1265,7 +1155,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 217),
|
||||
const_mul(x, 218),
|
||||
const_mul(x, 219),
|
||||
|
||||
const_mul(x, 220),
|
||||
const_mul(x, 221),
|
||||
const_mul(x, 222),
|
||||
@ -1276,7 +1165,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 227),
|
||||
const_mul(x, 228),
|
||||
const_mul(x, 229),
|
||||
|
||||
const_mul(x, 230),
|
||||
const_mul(x, 231),
|
||||
const_mul(x, 232),
|
||||
@ -1287,7 +1175,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 237),
|
||||
const_mul(x, 238),
|
||||
const_mul(x, 239),
|
||||
|
||||
const_mul(x, 240),
|
||||
const_mul(x, 241),
|
||||
const_mul(x, 242),
|
||||
@ -1298,43 +1185,36 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
|
||||
const_mul(x, 247),
|
||||
const_mul(x, 248),
|
||||
const_mul(x, 249),
|
||||
|
||||
const_mul(x, 250),
|
||||
const_mul(x, 251),
|
||||
const_mul(x, 252),
|
||||
const_mul(x, 253),
|
||||
const_mul(x, 254),
|
||||
const_mul(x, 255),
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Octet {
|
||||
value: u8
|
||||
value: u8,
|
||||
}
|
||||
|
||||
impl Octet {
|
||||
pub fn new(value: u8) -> Octet {
|
||||
Octet {
|
||||
value
|
||||
}
|
||||
Octet { value }
|
||||
}
|
||||
|
||||
pub fn zero() -> Octet {
|
||||
Octet {
|
||||
value: 0
|
||||
}
|
||||
Octet { value: 0 }
|
||||
}
|
||||
|
||||
pub fn one() -> Octet {
|
||||
Octet {
|
||||
value: 1
|
||||
}
|
||||
Octet { value: 1 }
|
||||
}
|
||||
|
||||
pub fn alpha(i: u8) -> Octet {
|
||||
Octet {
|
||||
value: OCT_EXP[i as usize]
|
||||
value: OCT_EXP[i as usize],
|
||||
}
|
||||
}
|
||||
|
||||
@ -1361,7 +1241,7 @@ impl Add for Octet {
|
||||
fn add(self, other: Octet) -> Octet {
|
||||
Octet {
|
||||
// As defined in section 5.7.2, addition on octets is implemented as bitxor
|
||||
value: self.value ^ other.value
|
||||
value: self.value ^ other.value,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1372,7 +1252,7 @@ impl<'a, 'b> Add<&'b Octet> for &'a Octet {
|
||||
fn add(self, other: &'b Octet) -> Octet {
|
||||
Octet {
|
||||
// As defined in section 5.7.2, addition on octets is implemented as bitxor
|
||||
value: self.value ^ other.value
|
||||
value: self.value ^ other.value,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1395,7 +1275,7 @@ impl Sub for Octet {
|
||||
fn sub(self, rhs: Octet) -> Octet {
|
||||
Octet {
|
||||
// As defined in section 5.7.2, subtraction on octets is implemented as bitxor
|
||||
value: self.value ^ rhs.value
|
||||
value: self.value ^ rhs.value,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1414,18 +1294,15 @@ impl<'a, 'b> Mul<&'b Octet> for &'a Octet {
|
||||
fn mul(self, other: &'b Octet) -> Octet {
|
||||
// As defined in section 5.7.2, multiplication is implemented via the tables above
|
||||
if self.value == 0 || other.value == 0 {
|
||||
Octet {
|
||||
value: 0
|
||||
}
|
||||
}
|
||||
else {
|
||||
Octet { value: 0 }
|
||||
} else {
|
||||
unsafe {
|
||||
// This is safe because value is a u8, and OCT_LOG is 256 elements long
|
||||
let log_u = *OCT_LOG.get_unchecked(self.value as usize) as usize;
|
||||
let log_v = *OCT_LOG.get_unchecked(other.value as usize) as usize;
|
||||
// This is safe because the sum of two values in OCT_LOG cannot exceed 509
|
||||
Octet {
|
||||
value: *OCT_EXP.get_unchecked(log_u + log_v)
|
||||
value: *OCT_EXP.get_unchecked(log_u + log_v),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1447,15 +1324,12 @@ impl<'a, 'b> Div<&'b Octet> for &'a Octet {
|
||||
assert_ne!(0, rhs.value);
|
||||
// As defined in section 5.7.2, division is implemented via the tables above
|
||||
if self.value == 0 {
|
||||
Octet {
|
||||
value: 0
|
||||
}
|
||||
}
|
||||
else {
|
||||
Octet { value: 0 }
|
||||
} else {
|
||||
let log_u = OCT_LOG[self.value as usize] as usize;
|
||||
let log_v = OCT_LOG[rhs.value as usize] as usize;
|
||||
Octet {
|
||||
value: OCT_EXP[255 + log_u - log_v]
|
||||
value: OCT_EXP[255 + log_u - log_v],
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1466,10 +1340,10 @@ mod tests {
|
||||
use rand::Rng;
|
||||
|
||||
use crate::octet::Octet;
|
||||
use crate::octet::OCT_LOG;
|
||||
use crate::octet::OCT_EXP;
|
||||
use crate::octet::OCTET_MUL_LOW_BITS;
|
||||
use crate::octet::OCTET_MUL_HI_BITS;
|
||||
use crate::octet::OCTET_MUL_LOW_BITS;
|
||||
use crate::octet::OCT_EXP;
|
||||
use crate::octet::OCT_LOG;
|
||||
|
||||
#[test]
|
||||
fn multiplication_tables() {
|
||||
@ -1486,7 +1360,7 @@ mod tests {
|
||||
#[test]
|
||||
fn addition() {
|
||||
let octet = Octet {
|
||||
value: rand::thread_rng().gen()
|
||||
value: rand::thread_rng().gen(),
|
||||
};
|
||||
// See section 5.7.2. u is its own additive inverse
|
||||
assert_eq!(Octet::zero(), &octet + &octet);
|
||||
@ -1495,7 +1369,7 @@ mod tests {
|
||||
#[test]
|
||||
fn multiplication_identity() {
|
||||
let octet = Octet {
|
||||
value: rand::thread_rng().gen()
|
||||
value: rand::thread_rng().gen(),
|
||||
};
|
||||
assert_eq!(octet, &octet * &Octet::one());
|
||||
}
|
||||
@ -1503,7 +1377,7 @@ mod tests {
|
||||
#[test]
|
||||
fn multiplicative_inverse() {
|
||||
let octet = Octet {
|
||||
value: rand::thread_rng().gen_range(1, 255)
|
||||
value: rand::thread_rng().gen_range(1, 255),
|
||||
};
|
||||
let one = Octet::one();
|
||||
assert_eq!(one, &octet * &(&one / &octet));
|
||||
@ -1512,7 +1386,7 @@ mod tests {
|
||||
#[test]
|
||||
fn division() {
|
||||
let octet = Octet {
|
||||
value: rand::thread_rng().gen_range(1, 255)
|
||||
value: rand::thread_rng().gen_range(1, 255),
|
||||
};
|
||||
assert_eq!(Octet::one(), &octet / &octet);
|
||||
}
|
||||
@ -1520,7 +1394,7 @@ mod tests {
|
||||
#[test]
|
||||
fn unsafe_mul_gaurantees() {
|
||||
let max_value = *OCT_LOG.iter().max().unwrap() as usize;
|
||||
assert!(2*max_value < OCT_EXP.len());
|
||||
assert!(2 * max_value < OCT_EXP.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1,15 +1,17 @@
|
||||
use crate::octet::Octet;
|
||||
use crate::octet::OCTET_MUL;
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
use crate::octet::OCTET_MUL_LOW_BITS;
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
use crate::octet::OCTET_MUL_HI_BITS;
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
use crate::octet::OCTET_MUL_LOW_BITS;
|
||||
|
||||
fn mulassign_scalar_fallback(octets: &mut [u8], scalar: &Octet) {
|
||||
let scalar_index = scalar.byte() as usize;
|
||||
for i in 0..octets.len() {
|
||||
unsafe {
|
||||
*octets.get_unchecked_mut(i) = *OCTET_MUL.get_unchecked(scalar_index).get_unchecked(*octets.get_unchecked(i) as usize);
|
||||
*octets.get_unchecked_mut(i) = *OCTET_MUL
|
||||
.get_unchecked(scalar_index)
|
||||
.get_unchecked(*octets.get_unchecked(i) as usize);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -22,11 +24,13 @@ unsafe fn mulassign_scalar_avx2(octets: &mut [u8], scalar: &Octet) {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use std::arch::x86_64::*;
|
||||
|
||||
let low_mask =_mm256_set1_epi8(0x0F);
|
||||
let low_mask = _mm256_set1_epi8(0x0F);
|
||||
let hi_mask = _mm256_set1_epi8(0xF0 as u8 as i8);
|
||||
let self_avx_ptr = octets.as_mut_ptr() as *mut __m256i;
|
||||
let low_table =_mm256_loadu_si256(OCTET_MUL_LOW_BITS[scalar.byte() as usize].as_ptr() as *const __m256i);
|
||||
let hi_table =_mm256_loadu_si256(OCTET_MUL_HI_BITS[scalar.byte() as usize].as_ptr() as *const __m256i);
|
||||
let low_table =
|
||||
_mm256_loadu_si256(OCTET_MUL_LOW_BITS[scalar.byte() as usize].as_ptr() as *const __m256i);
|
||||
let hi_table =
|
||||
_mm256_loadu_si256(OCTET_MUL_HI_BITS[scalar.byte() as usize].as_ptr() as *const __m256i);
|
||||
|
||||
for i in 0..(octets.len() / 32) {
|
||||
let self_vec = _mm256_loadu_si256(self_avx_ptr.add(i));
|
||||
@ -42,7 +46,9 @@ unsafe fn mulassign_scalar_avx2(octets: &mut [u8], scalar: &Octet) {
|
||||
let remainder = octets.len() % 32;
|
||||
let scalar_index = scalar.byte() as usize;
|
||||
for i in (octets.len() - remainder)..octets.len() {
|
||||
*octets.get_unchecked_mut(i) = *OCTET_MUL.get_unchecked(scalar_index).get_unchecked(*octets.get_unchecked(i) as usize);
|
||||
*octets.get_unchecked_mut(i) = *OCTET_MUL
|
||||
.get_unchecked(scalar_index)
|
||||
.get_unchecked(*octets.get_unchecked(i) as usize);
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,8 +68,10 @@ pub fn mulassign_scalar(octets: &mut [u8], scalar: &Octet) {
|
||||
fn fused_addassign_mul_scalar_fallback(octets: &mut [u8], other: &[u8], scalar: &Octet) {
|
||||
let scalar_index = scalar.byte() as usize;
|
||||
for i in 0..octets.len() {
|
||||
unsafe {
|
||||
*octets.get_unchecked_mut(i) ^= *OCTET_MUL.get_unchecked(scalar_index).get_unchecked(*other.get_unchecked(i) as usize);
|
||||
unsafe {
|
||||
*octets.get_unchecked_mut(i) ^= *OCTET_MUL
|
||||
.get_unchecked(scalar_index)
|
||||
.get_unchecked(*other.get_unchecked(i) as usize);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -76,12 +84,14 @@ unsafe fn fused_addassign_mul_scalar_avx2(octets: &mut [u8], other: &[u8], scala
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use std::arch::x86_64::*;
|
||||
|
||||
let low_mask =_mm256_set1_epi8(0x0F);
|
||||
let low_mask = _mm256_set1_epi8(0x0F);
|
||||
let hi_mask = _mm256_set1_epi8(0xF0 as u8 as i8);
|
||||
let self_avx_ptr = octets.as_mut_ptr() as *mut __m256i;
|
||||
let other_avx_ptr = other.as_ptr() as *const __m256i;
|
||||
let low_table =_mm256_loadu_si256(OCTET_MUL_LOW_BITS[scalar.byte() as usize].as_ptr() as *const __m256i);
|
||||
let hi_table =_mm256_loadu_si256(OCTET_MUL_HI_BITS[scalar.byte() as usize].as_ptr() as *const __m256i);
|
||||
let low_table =
|
||||
_mm256_loadu_si256(OCTET_MUL_LOW_BITS[scalar.byte() as usize].as_ptr() as *const __m256i);
|
||||
let hi_table =
|
||||
_mm256_loadu_si256(OCTET_MUL_HI_BITS[scalar.byte() as usize].as_ptr() as *const __m256i);
|
||||
|
||||
for i in 0..(octets.len() / 32) {
|
||||
// Multiply by scalar
|
||||
@ -102,13 +112,23 @@ unsafe fn fused_addassign_mul_scalar_avx2(octets: &mut [u8], other: &[u8], scala
|
||||
let remainder = octets.len() % 32;
|
||||
let scalar_index = scalar.byte() as usize;
|
||||
for i in (octets.len() - remainder)..octets.len() {
|
||||
*octets.get_unchecked_mut(i) ^= *OCTET_MUL.get_unchecked(scalar_index).get_unchecked(*other.get_unchecked(i) as usize);
|
||||
*octets.get_unchecked_mut(i) ^= *OCTET_MUL
|
||||
.get_unchecked(scalar_index)
|
||||
.get_unchecked(*other.get_unchecked(i) as usize);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fused_addassign_mul_scalar(octets: &mut [u8], other: &[u8], scalar: &Octet) {
|
||||
debug_assert_ne!(*scalar, Octet::one(), "Don't call this with one. Use += instead");
|
||||
debug_assert_ne!(*scalar, Octet::zero(), "Don't call with zero. It's very inefficient");
|
||||
debug_assert_ne!(
|
||||
*scalar,
|
||||
Octet::one(),
|
||||
"Don't call this with one. Use += instead"
|
||||
);
|
||||
debug_assert_ne!(
|
||||
*scalar,
|
||||
Octet::zero(),
|
||||
"Don't call with zero. It's very inefficient"
|
||||
);
|
||||
|
||||
assert_eq!(octets.len(), other.len());
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
@ -191,7 +211,7 @@ unsafe fn count_ones_and_nonzeros_avx2(octets: &[u8]) -> (usize, usize) {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use std::arch::x86_64::*;
|
||||
|
||||
let avx_ones =_mm256_set1_epi8(1);
|
||||
let avx_ones = _mm256_set1_epi8(1);
|
||||
let avx_zeros = _mm256_set1_epi8(0);
|
||||
let avx_ptr = octets.as_ptr() as *const __m256i;
|
||||
|
||||
@ -216,7 +236,7 @@ unsafe fn count_ones_and_nonzeros_avx2(octets: &[u8]) -> (usize, usize) {
|
||||
let mut remainder = octets.len() % 32;
|
||||
if remainder >= 16 {
|
||||
remainder -= 16;
|
||||
let avx_ones =_mm_set1_epi8(1);
|
||||
let avx_ones = _mm_set1_epi8(1);
|
||||
let avx_zeros = _mm_set1_epi8(0);
|
||||
let avx_ptr = octets.as_ptr().add((octets.len() / 32) * 32) as *const __m128i;
|
||||
|
||||
|
184
src/pi_solver.rs
184
src/pi_solver.rs
@ -1,5 +1,5 @@
|
||||
use crate::arraymap::{ArrayMap, BoolArrayMap};
|
||||
use crate::arraymap::UsizeArrayMap;
|
||||
use crate::arraymap::{ArrayMap, BoolArrayMap};
|
||||
use crate::matrix::OctetMatrix;
|
||||
use crate::octet::Octet;
|
||||
use crate::octets::count_ones_and_nonzeros;
|
||||
@ -19,13 +19,17 @@ struct FirstPhaseRowSelectionStats {
|
||||
hdpc_rows: Vec<bool>,
|
||||
start_col: usize,
|
||||
end_col: usize,
|
||||
start_row: usize
|
||||
start_row: usize,
|
||||
}
|
||||
|
||||
impl FirstPhaseRowSelectionStats {
|
||||
#[inline(never)]
|
||||
#[allow(non_snake_case)]
|
||||
pub fn new(matrix: &OctetMatrix, end_col: usize, num_source_symbols: u32) -> FirstPhaseRowSelectionStats {
|
||||
pub fn new(
|
||||
matrix: &OctetMatrix,
|
||||
end_col: usize,
|
||||
num_source_symbols: u32,
|
||||
) -> FirstPhaseRowSelectionStats {
|
||||
let S = num_ldpc_symbols(num_source_symbols);
|
||||
let H = num_hdpc_symbols(num_source_symbols);
|
||||
|
||||
@ -43,7 +47,7 @@ impl FirstPhaseRowSelectionStats {
|
||||
hdpc_rows,
|
||||
start_col: 0,
|
||||
end_col,
|
||||
start_row: 0
|
||||
start_row: 0,
|
||||
};
|
||||
|
||||
for row in 0..matrix.height() {
|
||||
@ -67,8 +71,10 @@ impl FirstPhaseRowSelectionStats {
|
||||
|
||||
// Recompute all stored statistics for the given row
|
||||
pub fn recompute_row(&mut self, row: usize, matrix: &OctetMatrix) {
|
||||
let (ones, non_zero) = count_ones_and_nonzeros(&matrix.get_row(row)[self.start_col..self.end_col]);
|
||||
self.non_zeros_histogram.decrement(self.non_zeros_per_row.get(row));
|
||||
let (ones, non_zero) =
|
||||
count_ones_and_nonzeros(&matrix.get_row(row)[self.start_col..self.end_col]);
|
||||
self.non_zeros_histogram
|
||||
.decrement(self.non_zeros_per_row.get(row));
|
||||
self.non_zeros_histogram.increment(non_zero);
|
||||
self.non_zeros_per_row.insert(row, non_zero);
|
||||
self.ones_per_row.insert(row, ones);
|
||||
@ -87,13 +93,21 @@ impl FirstPhaseRowSelectionStats {
|
||||
|
||||
// Set the valid columns, and recalculate statistics
|
||||
#[inline(never)]
|
||||
pub fn resize(&mut self, start_row: usize, end_row: usize, start_col: usize, end_col: usize, matrix: &OctetMatrix) {
|
||||
pub fn resize(
|
||||
&mut self,
|
||||
start_row: usize,
|
||||
end_row: usize,
|
||||
start_col: usize,
|
||||
end_col: usize,
|
||||
matrix: &OctetMatrix,
|
||||
) {
|
||||
// Only shrinking is supported
|
||||
assert!(start_col > self.start_col);
|
||||
assert!(end_col <= self.end_col);
|
||||
assert_eq!(self.start_row, start_row - 1);
|
||||
|
||||
self.non_zeros_histogram.decrement(self.non_zeros_per_row.get(self.start_row));
|
||||
self.non_zeros_histogram
|
||||
.decrement(self.non_zeros_per_row.get(self.start_row));
|
||||
|
||||
for row in start_row..end_row {
|
||||
for col in self.start_col..start_col {
|
||||
@ -127,7 +141,11 @@ impl FirstPhaseRowSelectionStats {
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn first_phase_graph_substep_build_adjacency(&self, rows_with_two_ones: &Vec<usize>, matrix: &OctetMatrix) -> ArrayMap<Vec<(usize, usize)>> {
|
||||
fn first_phase_graph_substep_build_adjacency(
|
||||
&self,
|
||||
rows_with_two_ones: &Vec<usize>,
|
||||
matrix: &OctetMatrix,
|
||||
) -> ArrayMap<Vec<(usize, usize)>> {
|
||||
let mut adjacent_nodes = ArrayMap::new(self.start_col, self.end_col);
|
||||
|
||||
for row in rows_with_two_ones.iter() {
|
||||
@ -157,8 +175,7 @@ impl FirstPhaseRowSelectionStats {
|
||||
let mut new_nodes = Vec::with_capacity(10);
|
||||
new_nodes.push((ones[1], *row));
|
||||
adjacent_nodes.insert(ones[0], new_nodes);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
first.unwrap().push((ones[1], *row));
|
||||
}
|
||||
let second = adjacent_nodes.get_mut(ones[1]);
|
||||
@ -166,8 +183,7 @@ impl FirstPhaseRowSelectionStats {
|
||||
let mut new_nodes = Vec::with_capacity(10);
|
||||
new_nodes.push((ones[0], *row));
|
||||
adjacent_nodes.insert(ones[1], new_nodes);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
second.unwrap().push((ones[0], *row));
|
||||
}
|
||||
}
|
||||
@ -176,8 +192,15 @@ impl FirstPhaseRowSelectionStats {
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn first_phase_graph_substep(&self, start_row: usize, end_row: usize, rows_with_two_ones: &Vec<usize>, matrix: &OctetMatrix) -> usize {
|
||||
let adjacent_nodes = self.first_phase_graph_substep_build_adjacency(rows_with_two_ones, matrix);
|
||||
fn first_phase_graph_substep(
|
||||
&self,
|
||||
start_row: usize,
|
||||
end_row: usize,
|
||||
rows_with_two_ones: &Vec<usize>,
|
||||
matrix: &OctetMatrix,
|
||||
) -> usize {
|
||||
let adjacent_nodes =
|
||||
self.first_phase_graph_substep_build_adjacency(rows_with_two_ones, matrix);
|
||||
let mut visited = BoolArrayMap::new(start_row, end_row);
|
||||
|
||||
let mut examplar_largest_component_row = None;
|
||||
@ -214,7 +237,12 @@ impl FirstPhaseRowSelectionStats {
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn first_phase_original_degree_substep(&self, start_row: usize, end_row: usize, r: usize) -> usize {
|
||||
fn first_phase_original_degree_substep(
|
||||
&self,
|
||||
start_row: usize,
|
||||
end_row: usize,
|
||||
r: usize,
|
||||
) -> usize {
|
||||
let mut chosen_hdpc = None;
|
||||
let mut chosen_hdpc_original_degree = std::usize::MAX;
|
||||
let mut chosen_non_hdpc = None;
|
||||
@ -228,8 +256,7 @@ impl FirstPhaseRowSelectionStats {
|
||||
chosen_hdpc = Some(row);
|
||||
chosen_hdpc_original_degree = row_original_degree;
|
||||
}
|
||||
}
|
||||
else if row_original_degree < chosen_non_hdpc_original_degree {
|
||||
} else if row_original_degree < chosen_non_hdpc_original_degree {
|
||||
chosen_non_hdpc = Some(row);
|
||||
chosen_non_hdpc_original_degree = row_original_degree;
|
||||
}
|
||||
@ -237,8 +264,7 @@ impl FirstPhaseRowSelectionStats {
|
||||
}
|
||||
if chosen_non_hdpc != None {
|
||||
return chosen_non_hdpc.unwrap();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return chosen_hdpc.unwrap();
|
||||
}
|
||||
}
|
||||
@ -246,7 +272,12 @@ impl FirstPhaseRowSelectionStats {
|
||||
// Verify there there are no non-HPDC rows with exactly two non-zero entries, greater than one
|
||||
#[inline(never)]
|
||||
#[cfg(debug_assertions)]
|
||||
fn first_phase_graph_substep_verify(&self, start_row: usize, end_row: usize, rows_with_two_ones: &Vec<usize>) {
|
||||
fn first_phase_graph_substep_verify(
|
||||
&self,
|
||||
start_row: usize,
|
||||
end_row: usize,
|
||||
rows_with_two_ones: &Vec<usize>,
|
||||
) {
|
||||
for row in start_row..end_row {
|
||||
if self.non_zeros_per_row.get(row) == 2 {
|
||||
assert!(rows_with_two_ones.contains(&row) || self.hdpc_rows[row]);
|
||||
@ -257,7 +288,12 @@ impl FirstPhaseRowSelectionStats {
|
||||
// Helper method for decoder phase 1
|
||||
// selects from [start_row, end_row) reading [start_col, end_col)
|
||||
// Returns (the chosen row, and "r" number of non-zero values the row has)
|
||||
pub fn first_phase_selection(&self, start_row: usize, end_row: usize, matrix: &OctetMatrix) -> (Option<usize>, Option<usize>) {
|
||||
pub fn first_phase_selection(
|
||||
&self,
|
||||
start_row: usize,
|
||||
end_row: usize,
|
||||
matrix: &OctetMatrix,
|
||||
) -> (Option<usize>, Option<usize>) {
|
||||
let mut r = None;
|
||||
for i in 1..(self.end_col - self.start_col + 1) {
|
||||
if self.non_zeros_histogram.get(i) > 0 {
|
||||
@ -288,15 +324,24 @@ impl FirstPhaseRowSelectionStats {
|
||||
if rows_with_two_ones.len() > 0 {
|
||||
#[cfg(debug_assertions)]
|
||||
self.first_phase_graph_substep_verify(start_row, end_row, &rows_with_two_ones);
|
||||
return (Some(self.first_phase_graph_substep(start_row, end_row, &rows_with_two_ones, matrix)), r);
|
||||
}
|
||||
else {
|
||||
return (
|
||||
Some(self.first_phase_graph_substep(
|
||||
start_row,
|
||||
end_row,
|
||||
&rows_with_two_ones,
|
||||
matrix,
|
||||
)),
|
||||
r,
|
||||
);
|
||||
} else {
|
||||
// See paragraph starting "If r = 2 and there is no row with exactly 2 ones in V"
|
||||
return (row_with_two_greater_than_one, r);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return (Some(self.first_phase_original_degree_substep(start_row, end_row, r.unwrap())), r);
|
||||
} else {
|
||||
return (
|
||||
Some(self.first_phase_original_degree_substep(start_row, end_row, r.unwrap())),
|
||||
r,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -316,11 +361,15 @@ pub struct IntermediateSymbolDecoder {
|
||||
debug_symbol_mul_ops: u32,
|
||||
debug_symbol_add_ops: u32,
|
||||
debug_symbol_mul_ops_by_phase: Vec<u32>,
|
||||
debug_symbol_add_ops_by_phase: Vec<u32>
|
||||
debug_symbol_add_ops_by_phase: Vec<u32>,
|
||||
}
|
||||
|
||||
impl IntermediateSymbolDecoder {
|
||||
pub fn new(matrix: OctetMatrix, symbols: Vec<Symbol>, num_source_symbols: u32) -> IntermediateSymbolDecoder {
|
||||
pub fn new(
|
||||
matrix: OctetMatrix,
|
||||
symbols: Vec<Symbol>,
|
||||
num_source_symbols: u32,
|
||||
) -> IntermediateSymbolDecoder {
|
||||
assert!(matrix.width() <= symbols.len());
|
||||
assert_eq!(matrix.height(), symbols.len());
|
||||
let mut c = Vec::with_capacity(matrix.width());
|
||||
@ -345,14 +394,20 @@ impl IntermediateSymbolDecoder {
|
||||
debug_symbol_mul_ops: 0,
|
||||
debug_symbol_add_ops: 0,
|
||||
debug_symbol_mul_ops_by_phase: vec![0; 5],
|
||||
debug_symbol_add_ops_by_phase: vec![0; 5]
|
||||
debug_symbol_add_ops_by_phase: vec![0; 5],
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true iff all elements in A between [start_row, end_row)
|
||||
// and [start_column, end_column) are zero
|
||||
#[cfg(debug_assertions)]
|
||||
fn all_zeroes(&self, start_row: usize, end_row: usize, start_column: usize, end_column: usize) -> bool {
|
||||
fn all_zeroes(
|
||||
&self,
|
||||
start_row: usize,
|
||||
end_row: usize,
|
||||
start_column: usize,
|
||||
end_column: usize,
|
||||
) -> bool {
|
||||
for row in start_row..end_row {
|
||||
for column in start_column..end_column {
|
||||
if self.A.get(row, column) != Octet::zero() {
|
||||
@ -372,8 +427,7 @@ impl IntermediateSymbolDecoder {
|
||||
let dest;
|
||||
if swapped_columns == 0 {
|
||||
dest = self.i;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
dest = self.A.width() - self.u - swapped_columns;
|
||||
}
|
||||
// No need to swap the first i rows, as they are all zero (see submatrix above V)
|
||||
@ -408,13 +462,18 @@ impl IntermediateSymbolDecoder {
|
||||
// +-----------+-----------------+---------+
|
||||
// Figure 6: Submatrices of A in the First Phase
|
||||
|
||||
let mut selection_helper = FirstPhaseRowSelectionStats::new(&self.A, self.A.width() - self.u, self.num_source_symbols);
|
||||
let mut selection_helper = FirstPhaseRowSelectionStats::new(
|
||||
&self.A,
|
||||
self.A.width() - self.u,
|
||||
self.num_source_symbols,
|
||||
);
|
||||
|
||||
while self.i + self.u < self.L {
|
||||
// Calculate r
|
||||
// "Let r be the minimum integer such that at least one row of A has
|
||||
// exactly r nonzeros in V."
|
||||
let (chosen_row, r) = selection_helper.first_phase_selection(self.i, self.A.height(), &self.A);
|
||||
let (chosen_row, r) =
|
||||
selection_helper.first_phase_selection(self.i, self.A.height(), &self.A);
|
||||
|
||||
if r == None {
|
||||
return false;
|
||||
@ -442,8 +501,7 @@ impl IntermediateSymbolDecoder {
|
||||
// Hot path for r == 1, since it's very common due to maximum connected
|
||||
// component selection, and recompute_row() is expensive
|
||||
selection_helper.eliminate_leading_value(row, &leading_value);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
selection_helper.recompute_row(row, &self.A);
|
||||
}
|
||||
}
|
||||
@ -451,7 +509,13 @@ impl IntermediateSymbolDecoder {
|
||||
|
||||
self.i += 1;
|
||||
self.u += r - 1;
|
||||
selection_helper.resize(self.i, self.A.height(), self.i, self.A.width() - self.u, &self.A);
|
||||
selection_helper.resize(
|
||||
self.i,
|
||||
self.A.height(),
|
||||
self.i,
|
||||
self.A.width() - self.u,
|
||||
&self.A,
|
||||
);
|
||||
#[cfg(debug_assertions)]
|
||||
self.first_phase_verify();
|
||||
}
|
||||
@ -468,8 +532,7 @@ impl IntermediateSymbolDecoder {
|
||||
for col in 0..self.i {
|
||||
if row == col {
|
||||
assert_eq!(Octet::one(), self.A.get(row, col));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_eq!(Octet::zero(), self.A.get(row, col));
|
||||
}
|
||||
}
|
||||
@ -540,8 +603,7 @@ impl IntermediateSymbolDecoder {
|
||||
self.debug_symbol_add_ops += 1;
|
||||
let (dest, temp) = get_both_indices(&mut self.D, self.d[row], self.d[col]);
|
||||
*dest += temp;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
self.debug_symbol_mul_ops += 1;
|
||||
self.debug_symbol_add_ops += 1;
|
||||
let (dest, temp) = get_both_indices(&mut self.D, self.d[row], self.d[col]);
|
||||
@ -568,8 +630,7 @@ impl IntermediateSymbolDecoder {
|
||||
// The rest of A should be identity matrix
|
||||
if row == col {
|
||||
assert_eq!(Octet::one(), self.A.get(row, col));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_eq!(Octet::zero(), self.A.get(row, col));
|
||||
}
|
||||
}
|
||||
@ -629,8 +690,7 @@ impl IntermediateSymbolDecoder {
|
||||
for col in (self.A.width() - self.u)..self.A.width() {
|
||||
if row == col {
|
||||
assert_eq!(Octet::one(), self.A.get(row, col));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_eq!(Octet::zero(), self.A.get(row, col));
|
||||
}
|
||||
}
|
||||
@ -673,8 +733,7 @@ impl IntermediateSymbolDecoder {
|
||||
for col in 0..self.A.width() {
|
||||
if row == col {
|
||||
assert_eq!(Octet::one(), self.A.get(row, col));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
assert_eq!(Octet::zero(), self.A.get(row, col));
|
||||
}
|
||||
}
|
||||
@ -774,8 +833,7 @@ impl IntermediateSymbolDecoder {
|
||||
self.debug_symbol_add_ops += 1;
|
||||
let (dest, temp) = get_both_indices(&mut self.D, self.d[iprime], self.d[i]);
|
||||
*dest += temp;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
self.debug_symbol_add_ops += 1;
|
||||
self.debug_symbol_mul_ops += 1;
|
||||
let (dest, temp) = get_both_indices(&mut self.D, self.d[iprime], self.d[i]);
|
||||
@ -797,7 +855,7 @@ impl IntermediateSymbolDecoder {
|
||||
#[inline(never)]
|
||||
pub fn execute(&mut self) -> Option<Vec<Symbol>> {
|
||||
if !self.first_phase() {
|
||||
return None
|
||||
return None;
|
||||
}
|
||||
|
||||
if !self.second_phase() {
|
||||
@ -824,7 +882,11 @@ impl IntermediateSymbolDecoder {
|
||||
|
||||
// Fused implementation for self.inverse().mul_symbols(symbols)
|
||||
// See section 5.4.2.1
|
||||
pub fn fused_inverse_mul_symbols(matrix: OctetMatrix, symbols: Vec<Symbol>, num_source_symbols: u32) -> Option<Vec<Symbol>> {
|
||||
pub fn fused_inverse_mul_symbols(
|
||||
matrix: OctetMatrix,
|
||||
symbols: Vec<Symbol>,
|
||||
num_source_symbols: u32,
|
||||
) -> Option<Vec<Symbol>> {
|
||||
IntermediateSymbolDecoder::new(matrix, symbols, num_source_symbols).execute()
|
||||
}
|
||||
|
||||
@ -837,15 +899,25 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn operations_per_symbol() {
|
||||
for &(elements, expected_mul_ops, expected_add_ops) in [(10, 35.0, 50.0), (100, 16.0, 35.0)].iter() {
|
||||
for &(elements, expected_mul_ops, expected_add_ops) in
|
||||
[(10, 35.0, 50.0), (100, 16.0, 35.0)].iter()
|
||||
{
|
||||
let num_symbols = extended_source_block_symbols(elements);
|
||||
let indices: Vec<u32> = (0..num_symbols).collect();
|
||||
let a = generate_constraint_matrix(num_symbols, &indices);
|
||||
let symbols = vec![Symbol::zero(1); a.width()];
|
||||
let mut decoder = IntermediateSymbolDecoder::new(a, symbols, num_symbols);
|
||||
decoder.execute();
|
||||
assert!((decoder.get_symbol_mul_ops() as f64 / num_symbols as f64) < expected_mul_ops, "mul ops per symbol = {}", (decoder.get_symbol_mul_ops() as f64 / num_symbols as f64));
|
||||
assert!((decoder.get_symbol_add_ops() as f64 / num_symbols as f64) < expected_add_ops, "add ops per symbol = {}", (decoder.get_symbol_add_ops() as f64 / num_symbols as f64));
|
||||
assert!(
|
||||
(decoder.get_symbol_mul_ops() as f64 / num_symbols as f64) < expected_mul_ops,
|
||||
"mul ops per symbol = {}",
|
||||
(decoder.get_symbol_mul_ops() as f64 / num_symbols as f64)
|
||||
);
|
||||
assert!(
|
||||
(decoder.get_symbol_add_ops() as f64 / num_symbols as f64) < expected_add_ops,
|
||||
"add ops per symbol = {}",
|
||||
(decoder.get_symbol_add_ops() as f64 / num_symbols as f64)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,22 @@
|
||||
use std::ops::AddAssign;
|
||||
use crate::octet::Octet;
|
||||
use crate::octets::mulassign_scalar;
|
||||
use crate::octets::fused_addassign_mul_scalar;
|
||||
use crate::octets::add_assign;
|
||||
use crate::octets::fused_addassign_mul_scalar;
|
||||
use crate::octets::mulassign_scalar;
|
||||
use std::ops::AddAssign;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Symbol {
|
||||
value: Vec<u8>
|
||||
value: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Symbol {
|
||||
pub fn new(value: Vec<u8>) -> Symbol {
|
||||
Symbol {
|
||||
value
|
||||
}
|
||||
Symbol { value }
|
||||
}
|
||||
|
||||
pub fn zero(size: usize) -> Symbol {
|
||||
Symbol {
|
||||
value: vec![0; size]
|
||||
value: vec![0; size],
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -479,7 +479,8 @@ pub const SYSTEMATIC_INDICES_AND_PARAMETERS: [(u32, u32, u32, u32, u32); 477] =
|
||||
(54735, 233, 877, 16, 55259),
|
||||
(55289, 362, 883, 16, 55817),
|
||||
(55843, 963, 907, 16, 56393),
|
||||
(56403, 471, 907, 16, 56951)];
|
||||
(56403, 471, 907, 16, 56951),
|
||||
];
|
||||
|
||||
const P1_TABLE: [(u32, u32); 477] = [
|
||||
(10, 11),
|
||||
@ -958,7 +959,8 @@ const P1_TABLE: [(u32, u32); 477] = [
|
||||
(54735, 373),
|
||||
(55289, 373),
|
||||
(55843, 373),
|
||||
(56403, 379)];
|
||||
(56403, 379),
|
||||
];
|
||||
|
||||
// Calculates, K', the extended source block size, in symbols, for a given source block size
|
||||
// See section 5.3.1
|
||||
@ -1023,9 +1025,9 @@ pub fn num_lt_symbols(source_block_symbols: u32) -> u32 {
|
||||
// Calculates, L, the number of intermediate symbols, for a given number of source block symbols
|
||||
// See section 5.3.3.3
|
||||
pub fn num_intermediate_symbols(source_block_symbols: u32) -> u32 {
|
||||
extended_source_block_symbols(source_block_symbols) +
|
||||
num_ldpc_symbols(source_block_symbols) +
|
||||
num_hdpc_symbols(source_block_symbols)
|
||||
extended_source_block_symbols(source_block_symbols)
|
||||
+ num_ldpc_symbols(source_block_symbols)
|
||||
+ num_hdpc_symbols(source_block_symbols)
|
||||
}
|
||||
|
||||
// Calculates, P, the number of PI symbols, for a given number of source block symbols
|
||||
@ -1047,9 +1049,9 @@ pub fn calculate_p1(source_block_symbols: u32) -> u32 {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::systematic_constants::{MAX_SOURCE_SYMBOLS_PER_BLOCK, num_pi_symbols, calculate_p1};
|
||||
use crate::systematic_constants::num_ldpc_symbols;
|
||||
use crate::systematic_constants::num_lt_symbols;
|
||||
use crate::systematic_constants::{calculate_p1, num_pi_symbols, MAX_SOURCE_SYMBOLS_PER_BLOCK};
|
||||
|
||||
#[test]
|
||||
fn all_prime() {
|
||||
@ -1067,8 +1069,7 @@ mod tests {
|
||||
while !primal::is_prime(p1 as u64) {
|
||||
if p1 % 2 == 0 {
|
||||
p1 += 1;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
p1 += 2;
|
||||
}
|
||||
}
|
||||
|
@ -4,10 +4,9 @@ pub fn get_both_indices<T>(vector: &mut Vec<T>, i: usize, j: usize) -> (&mut T,
|
||||
debug_assert!(j < vector.len());
|
||||
if i < j {
|
||||
let (first, last) = vector.split_at_mut(j);
|
||||
return (&mut first[i], &mut last[0])
|
||||
}
|
||||
else {
|
||||
return (&mut first[i], &mut last[0]);
|
||||
} else {
|
||||
let (first, last) = vector.split_at_mut(i);
|
||||
return (&mut last[0], &mut first[j])
|
||||
return (&mut last[0], &mut first[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
#[cfg(test)]
|
||||
mod codec_tests {
|
||||
use rand::Rng;
|
||||
use rand::seq::SliceRandom;
|
||||
use raptorq::SourceBlockEncoder;
|
||||
use raptorq::SourceBlockDecoder;
|
||||
use raptorq::Encoder;
|
||||
use rand::Rng;
|
||||
use raptorq::Decoder;
|
||||
use raptorq::Encoder;
|
||||
use raptorq::SourceBlockDecoder;
|
||||
use raptorq::SourceBlockEncoder;
|
||||
|
||||
#[test]
|
||||
fn random_erasure() {
|
||||
|
Loading…
Reference in New Issue
Block a user