diff --git a/src/algorithm.md b/src/algorithm.md index b8f36b5..9ca84b2 100644 --- a/src/algorithm.md +++ b/src/algorithm.md @@ -59,17 +59,17 @@ Encoding and decoding both have two variations: and use similar setup than [main benchmarks], except with maximum possible shard loss. -| original : recovery | Chunks | HighRateEncoder | LowRateEncoder | HighRateDecoder | LowRateDecoder | -| ------------------- | ------- | --------------- | -------------- | --------------- | -------------- | -| 1024 : 1024 | 1x 1024 | 175 MiB/s | 176 MiB/s | 76 MiB/s | 75 MiB/s | -| 1024 : 1025 (Low) | 2x 1024 | 140 | **153** | 47 | **59** | -| 1025 : 1024 (High) | 2x 1024 | **152** | 132 | **60** | 46 | -| 1024 : 2048 (Low) | 2x 1024 | 157 | **169** | 70 | 70 | -| 2048 : 1024 (High) | 2x 1024 | **167** | 151 | 69 | 68 | -| 1025 : 1025 | 1x 2048 | 125 | 126 | 44 | 43 | -| 1025 : 2048 (Low) | 1x 2048 | 144 | 144 | **65** **!!!** | 53 | -| 2048 : 1025 (High) | 1x 2048 | 144 | 145 | 53 | **62** **!!!** | -| 2048 : 2048 | 1x 2048 | 156 | 157 | 70 | 69 | +| original : recovery | Chunks | `HighRateEncoder` | `LowRateEncoder` | `HighRateDecoder` | `LowRateDecoder` | +| ------------------- | ------- | ----------------- | ---------------- | ----------------- | ---------------- | +| 1024 : 1024 | 1x 1024 | 175 MiB/s | 176 MiB/s | 76 MiB/s | 75 MiB/s | +| 1024 : 1025 (Low) | 2x 1024 | 140 | **153** | 47 | **59** | +| 1025 : 1024 (High) | 2x 1024 | **152** | 132 | **60** | 46 | +| 1024 : 2048 (Low) | 2x 1024 | 157 | **169** | 70 | 70 | +| 2048 : 1024 (High) | 2x 1024 | **167** | 151 | 69 | 68 | +| 1025 : 1025 | 1x 2048 | 125 | 126 | 44 | 43 | +| 1025 : 2048 (Low) | 1x 2048 | 144 | 144 | **65** **!!!** | 53 | +| 2048 : 1025 (High) | 1x 2048 | 144 | 145 | 53 | **62** **!!!** | +| 2048 : 2048 | 1x 2048 | 156 | 157 | 70 | 69 | [main benchmarks]: crate#benchmarks diff --git a/src/decoder_result.rs b/src/decoder_result.rs index cd2d470..452710f 100644 --- a/src/decoder_result.rs +++ b/src/decoder_result.rs @@ -74,7 +74,7 @@ impl<'a> Iterator for RestoredOriginal<'a> { self.next_index = index + 1; return Some((index, original)); } - index += 1 + index += 1; } self.ended = true; None diff --git a/src/engine.rs b/src/engine.rs index 5f6ab8d..a8d926a 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -21,7 +21,7 @@ //! - [`Ssse3`] //! - Optimized engine that takes advantage of the x86(-64) SSSE3 SIMD instructions. //! - [`Neon`] -//! - Optimized engine that takes advantage of the AArch64 Neon SIMD instructions. +//! - Optimized engine that takes advantage of the `AArch64` Neon SIMD instructions. //! - [`DefaultEngine`] //! - Default engine which is used when no specific engine is given. //! - Automatically selects best engine at runtime. @@ -156,7 +156,7 @@ pub trait Engine { where Self: Sized, { - utils::eval_poly(erasures, truncated_size) + utils::eval_poly(erasures, truncated_size); } } diff --git a/src/engine/engine_avx2.rs b/src/engine/engine_avx2.rs index e2b7830..4f3390a 100644 --- a/src/engine/engine_avx2.rs +++ b/src/engine/engine_avx2.rs @@ -109,30 +109,30 @@ impl From<&Multiply128lutT> for LutAvx2 { #[inline(always)] fn from(lut: &Multiply128lutT) -> Self { unsafe { - LutAvx2 { + Self { t0_lo: _mm256_broadcastsi128_si256(_mm_loadu_si128( - &lut.lo[0] as *const u128 as *const __m128i, + std::ptr::from_ref::(&lut.lo[0]).cast::<__m128i>(), )), t1_lo: _mm256_broadcastsi128_si256(_mm_loadu_si128( - &lut.lo[1] as *const u128 as *const __m128i, + std::ptr::from_ref::(&lut.lo[1]).cast::<__m128i>(), )), t2_lo: _mm256_broadcastsi128_si256(_mm_loadu_si128( - &lut.lo[2] as *const u128 as *const __m128i, + std::ptr::from_ref::(&lut.lo[2]).cast::<__m128i>(), )), t3_lo: _mm256_broadcastsi128_si256(_mm_loadu_si128( - &lut.lo[3] as *const u128 as *const __m128i, + std::ptr::from_ref::(&lut.lo[3]).cast::<__m128i>(), )), t0_hi: _mm256_broadcastsi128_si256(_mm_loadu_si128( - &lut.hi[0] as *const u128 as *const __m128i, + std::ptr::from_ref::(&lut.hi[0]).cast::<__m128i>(), )), t1_hi: _mm256_broadcastsi128_si256(_mm_loadu_si128( - &lut.hi[1] as *const u128 as *const __m128i, + std::ptr::from_ref::(&lut.hi[1]).cast::<__m128i>(), )), t2_hi: _mm256_broadcastsi128_si256(_mm_loadu_si128( - &lut.hi[2] as *const u128 as *const __m128i, + std::ptr::from_ref::(&lut.hi[2]).cast::<__m128i>(), )), t3_hi: _mm256_broadcastsi128_si256(_mm_loadu_si128( - &lut.hi[3] as *const u128 as *const __m128i, + std::ptr::from_ref::(&lut.hi[3]).cast::<__m128i>(), )), } } @@ -146,7 +146,7 @@ impl Avx2 { let lut_avx2 = LutAvx2::from(lut); for chunk in x.iter_mut() { - let x_ptr = chunk.as_mut_ptr() as *mut __m256i; + let x_ptr = chunk.as_mut_ptr().cast::<__m256i>(); unsafe { let x_lo = _mm256_loadu_si256(x_ptr); let x_hi = _mm256_loadu_si256(x_ptr.add(1)); @@ -211,9 +211,9 @@ impl Avx2 { impl Avx2 { // Implementation of LEO_FFTB_256 #[inline(always)] - fn fftb_256(&self, x: &mut [u8; 64], y: &mut [u8; 64], lut_avx2: LutAvx2) { - let x_ptr = x.as_mut_ptr() as *mut __m256i; - let y_ptr = y.as_mut_ptr() as *mut __m256i; + fn fftb_256(x: &mut [u8; 64], y: &mut [u8; 64], lut_avx2: LutAvx2) { + let x_ptr = x.as_mut_ptr().cast::<__m256i>(); + let y_ptr = y.as_mut_ptr().cast::<__m256i>(); unsafe { let mut x_lo = _mm256_loadu_si256(x_ptr); @@ -242,7 +242,7 @@ impl Avx2 { let lut_avx2 = LutAvx2::from(lut); for (x_chunk, y_chunk) in zip(x.iter_mut(), y.iter_mut()) { - self.fftb_256(x_chunk, y_chunk, lut_avx2); + Self::fftb_256(x_chunk, y_chunk, lut_avx2); } } @@ -319,7 +319,7 @@ impl Avx2 { let log_m23 = self.skew[base + dist * 2]; for i in r..r + dist { - self.fft_butterfly_two_layers(data, pos + i, dist, log_m01, log_m23, log_m02) + self.fft_butterfly_two_layers(data, pos + i, dist, log_m01, log_m23, log_m02); } r += dist4; @@ -340,7 +340,7 @@ impl Avx2 { if log_m == GF_MODULUS { utils::xor(y, x); } else { - self.fft_butterfly_partial(x, y, log_m) + self.fft_butterfly_partial(x, y, log_m); } r += 2; @@ -355,9 +355,9 @@ impl Avx2 { impl Avx2 { // Implementation of LEO_IFFTB_256 #[inline(always)] - fn ifftb_256(&self, x: &mut [u8; 64], y: &mut [u8; 64], lut_avx2: LutAvx2) { - let x_ptr = x.as_mut_ptr() as *mut __m256i; - let y_ptr = y.as_mut_ptr() as *mut __m256i; + fn ifftb_256(x: &mut [u8; 64], y: &mut [u8; 64], lut_avx2: LutAvx2) { + let x_ptr = x.as_mut_ptr().cast::<__m256i>(); + let y_ptr = y.as_mut_ptr().cast::<__m256i>(); unsafe { let mut x_lo = _mm256_loadu_si256(x_ptr); @@ -385,7 +385,7 @@ impl Avx2 { let lut_avx2 = LutAvx2::from(lut); for (x_chunk, y_chunk) in zip(x.iter_mut(), y.iter_mut()) { - self.ifftb_256(x_chunk, y_chunk, lut_avx2); + Self::ifftb_256(x_chunk, y_chunk, lut_avx2); } } @@ -436,7 +436,7 @@ impl Avx2 { skew_delta: usize, ) { // Drop unsafe privileges - self.ifft_private(data, pos, size, truncated_size, skew_delta) + self.ifft_private(data, pos, size, truncated_size, skew_delta); } #[inline(always)] @@ -462,7 +462,7 @@ impl Avx2 { let log_m23 = self.skew[base + dist * 2]; for i in r..r + dist { - self.ifft_butterfly_two_layers(data, pos + i, dist, log_m01, log_m23, log_m02) + self.ifft_butterfly_two_layers(data, pos + i, dist, log_m01, log_m23, log_m02); } r += dist4; @@ -497,7 +497,7 @@ impl Avx2 { impl Avx2 { #[target_feature(enable = "avx2")] unsafe fn eval_poly_avx2(erasures: &mut [GfElement; GF_ORDER], truncated_size: usize) { - utils::eval_poly(erasures, truncated_size) + utils::eval_poly(erasures, truncated_size); } } diff --git a/src/engine/engine_default.rs b/src/engine/engine_default.rs index 42b9374..7eea7a0 100644 --- a/src/engine/engine_default.rs +++ b/src/engine/engine_default.rs @@ -20,29 +20,29 @@ impl DefaultEngine { /// 2. [`Ssse3`] /// 3. [`NoSimd`] /// - /// On AArch64 the engine is chosen in the following order of preference: + /// On `AArch64` the engine is chosen in the following order of preference: /// 1. [`Neon`] /// 2. [`NoSimd`] pub fn new() -> Self { #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { if is_x86_feature_detected!("avx2") { - return DefaultEngine(Box::new(Avx2::new())); + return Self(Box::new(Avx2::new())); } if is_x86_feature_detected!("ssse3") { - return DefaultEngine(Box::new(Ssse3::new())); + return Self(Box::new(Ssse3::new())); } } #[cfg(target_arch = "aarch64")] { if std::arch::is_aarch64_feature_detected!("neon") { - return DefaultEngine(Box::new(Neon::new())); + return Self(Box::new(Neon::new())); } } - DefaultEngine(Box::new(NoSimd::new())) + Self(Box::new(NoSimd::new())) } } @@ -67,7 +67,7 @@ impl Engine for DefaultEngine { truncated_size: usize, skew_delta: usize, ) { - self.0.fft(data, pos, size, truncated_size, skew_delta) + self.0.fft(data, pos, size, truncated_size, skew_delta); } fn ifft( @@ -78,11 +78,11 @@ impl Engine for DefaultEngine { truncated_size: usize, skew_delta: usize, ) { - self.0.ifft(data, pos, size, truncated_size, skew_delta) + self.0.ifft(data, pos, size, truncated_size, skew_delta); } fn mul(&self, x: &mut [[u8; 64]], log_m: GfElement) { - self.0.mul(x, log_m) + self.0.mul(x, log_m); } fn eval_poly(erasures: &mut [GfElement; GF_ORDER], truncated_size: usize) { @@ -104,6 +104,6 @@ impl Engine for DefaultEngine { } } - NoSimd::eval_poly(erasures, truncated_size) + NoSimd::eval_poly(erasures, truncated_size); } } diff --git a/src/engine/engine_naive.rs b/src/engine/engine_naive.rs index a2f215a..20292c4 100644 --- a/src/engine/engine_naive.rs +++ b/src/engine/engine_naive.rs @@ -107,8 +107,8 @@ impl Engine for Naive { fn mul(&self, x: &mut [[u8; 64]], log_m: GfElement) { for chunk in x.iter_mut() { for i in 0..32 { - let lo = chunk[i] as GfElement; - let hi = chunk[i + 32] as GfElement; + let lo = GfElement::from(chunk[i]); + let hi = GfElement::from(chunk[i + 32]); let prod = tables::mul(lo | (hi << 8), log_m, self.exp, self.log); chunk[i] = prod as u8; chunk[i + 32] = (prod >> 8) as u8; @@ -136,8 +136,8 @@ impl Naive { for (x_chunk, y_chunk) in std::iter::zip(x.iter_mut(), y.iter()) { for i in 0..32 { - let lo = y_chunk[i] as GfElement; - let hi = y_chunk[i + 32] as GfElement; + let lo = GfElement::from(y_chunk[i]); + let hi = GfElement::from(y_chunk[i + 32]); let prod = tables::mul(lo | (hi << 8), log_m, self.exp, self.log); x_chunk[i] ^= prod as u8; x_chunk[i + 32] ^= (prod >> 8) as u8; diff --git a/src/engine/engine_neon.rs b/src/engine/engine_neon.rs index bcfd8c1..8e1ab84 100644 --- a/src/engine/engine_neon.rs +++ b/src/engine/engine_neon.rs @@ -123,15 +123,15 @@ impl Neon { let mut prod_hi: uint8x16_t; unsafe { - let t0_lo = vld1q_u8(&lut.lo[0] as *const u128 as *const u8); - let t1_lo = vld1q_u8(&lut.lo[1] as *const u128 as *const u8); - let t2_lo = vld1q_u8(&lut.lo[2] as *const u128 as *const u8); - let t3_lo = vld1q_u8(&lut.lo[3] as *const u128 as *const u8); + let t0_lo = vld1q_u8(std::ptr::from_ref::(&lut.lo[0]).cast::()); + let t1_lo = vld1q_u8(std::ptr::from_ref::(&lut.lo[1]).cast::()); + let t2_lo = vld1q_u8(std::ptr::from_ref::(&lut.lo[2]).cast::()); + let t3_lo = vld1q_u8(std::ptr::from_ref::(&lut.lo[3]).cast::()); - let t0_hi = vld1q_u8(&lut.hi[0] as *const u128 as *const u8); - let t1_hi = vld1q_u8(&lut.hi[1] as *const u128 as *const u8); - let t2_hi = vld1q_u8(&lut.hi[2] as *const u128 as *const u8); - let t3_hi = vld1q_u8(&lut.hi[3] as *const u128 as *const u8); + let t0_hi = vld1q_u8(std::ptr::from_ref::(&lut.hi[0]).cast::()); + let t1_hi = vld1q_u8(std::ptr::from_ref::(&lut.hi[1]).cast::()); + let t2_hi = vld1q_u8(std::ptr::from_ref::(&lut.hi[2]).cast::()); + let t3_hi = vld1q_u8(std::ptr::from_ref::(&lut.hi[3]).cast::()); let clr_mask = vdupq_n_u8(0x0f); @@ -296,7 +296,7 @@ impl Neon { let log_m23 = self.skew[base + dist * 2]; for i in r..r + dist { - self.fft_butterfly_two_layers(data, pos + i, dist, log_m01, log_m23, log_m02) + self.fft_butterfly_two_layers(data, pos + i, dist, log_m01, log_m23, log_m02); } r += dist4; @@ -317,7 +317,7 @@ impl Neon { if log_m == GF_MODULUS { utils::xor(y, x); } else { - self.fft_butterfly_partial(x, y, log_m) + self.fft_butterfly_partial(x, y, log_m); } r += 2; @@ -422,7 +422,7 @@ impl Neon { skew_delta: usize, ) { // Drop unsafe privileges - self.ifft_private(data, pos, size, truncated_size, skew_delta) + self.ifft_private(data, pos, size, truncated_size, skew_delta); } #[inline(always)] @@ -448,7 +448,7 @@ impl Neon { let log_m23 = self.skew[base + dist * 2]; for i in r..r + dist { - self.ifft_butterfly_two_layers(data, pos + i, dist, log_m01, log_m23, log_m02) + self.ifft_butterfly_two_layers(data, pos + i, dist, log_m01, log_m23, log_m02); } r += dist4; @@ -483,7 +483,7 @@ impl Neon { impl Neon { #[target_feature(enable = "neon")] unsafe fn eval_poly_neon(erasures: &mut [GfElement; GF_ORDER], truncated_size: usize) { - utils::eval_poly(erasures, truncated_size) + utils::eval_poly(erasures, truncated_size); } } diff --git a/src/engine/engine_nosimd.rs b/src/engine/engine_nosimd.rs index acaddb4..68ea8c6 100644 --- a/src/engine/engine_nosimd.rs +++ b/src/engine/engine_nosimd.rs @@ -182,7 +182,7 @@ impl NoSimd { let log_m23 = self.skew[base + dist * 2]; for i in r..r + dist { - self.fft_butterfly_two_layers(data, pos + i, dist, log_m01, log_m23, log_m02) + self.fft_butterfly_two_layers(data, pos + i, dist, log_m01, log_m23, log_m02); } r += dist4; @@ -203,7 +203,7 @@ impl NoSimd { if log_m == GF_MODULUS { utils::xor(y, x); } else { - self.fft_butterfly_partial(x, y, log_m) + self.fft_butterfly_partial(x, y, log_m); } r += 2; @@ -283,7 +283,7 @@ impl NoSimd { let log_m23 = self.skew[base + dist * 2]; for i in r..r + dist { - self.ifft_butterfly_two_layers(data, pos + i, dist, log_m01, log_m23, log_m02) + self.ifft_butterfly_two_layers(data, pos + i, dist, log_m01, log_m23, log_m02); } r += dist4; diff --git a/src/engine/engine_ssse3.rs b/src/engine/engine_ssse3.rs index b8fb265..c3083dc 100644 --- a/src/engine/engine_ssse3.rs +++ b/src/engine/engine_ssse3.rs @@ -99,7 +99,7 @@ impl Ssse3 { let lut = &self.mul128[log_m as usize]; for chunk in x.iter_mut() { - let x_ptr = chunk.as_mut_ptr() as *mut __m128i; + let x_ptr = chunk.as_mut_ptr().cast::<__m128i>(); unsafe { let x0_lo = _mm_loadu_si128(x_ptr); let x1_lo = _mm_loadu_si128(x_ptr.add(1)); @@ -122,15 +122,15 @@ impl Ssse3 { let mut prod_hi: __m128i; unsafe { - let t0_lo = _mm_loadu_si128(&lut.lo[0] as *const u128 as *const __m128i); - let t1_lo = _mm_loadu_si128(&lut.lo[1] as *const u128 as *const __m128i); - let t2_lo = _mm_loadu_si128(&lut.lo[2] as *const u128 as *const __m128i); - let t3_lo = _mm_loadu_si128(&lut.lo[3] as *const u128 as *const __m128i); + let t0_lo = _mm_loadu_si128(std::ptr::from_ref::(&lut.lo[0]).cast::<__m128i>()); + let t1_lo = _mm_loadu_si128(std::ptr::from_ref::(&lut.lo[1]).cast::<__m128i>()); + let t2_lo = _mm_loadu_si128(std::ptr::from_ref::(&lut.lo[2]).cast::<__m128i>()); + let t3_lo = _mm_loadu_si128(std::ptr::from_ref::(&lut.lo[3]).cast::<__m128i>()); - let t0_hi = _mm_loadu_si128(&lut.hi[0] as *const u128 as *const __m128i); - let t1_hi = _mm_loadu_si128(&lut.hi[1] as *const u128 as *const __m128i); - let t2_hi = _mm_loadu_si128(&lut.hi[2] as *const u128 as *const __m128i); - let t3_hi = _mm_loadu_si128(&lut.hi[3] as *const u128 as *const __m128i); + let t0_hi = _mm_loadu_si128(std::ptr::from_ref::(&lut.hi[0]).cast::<__m128i>()); + let t1_hi = _mm_loadu_si128(std::ptr::from_ref::(&lut.hi[1]).cast::<__m128i>()); + let t2_hi = _mm_loadu_si128(std::ptr::from_ref::(&lut.hi[2]).cast::<__m128i>()); + let t3_hi = _mm_loadu_si128(std::ptr::from_ref::(&lut.hi[3]).cast::<__m128i>()); let clr_mask = _mm_set1_epi8(0x0f); @@ -181,8 +181,8 @@ impl Ssse3 { #[inline(always)] fn fftb_128(&self, x: &mut [u8; 64], y: &mut [u8; 64], log_m: GfElement) { let lut = &self.mul128[log_m as usize]; - let x_ptr = x.as_mut_ptr() as *mut __m128i; - let y_ptr = y.as_mut_ptr() as *mut __m128i; + let x_ptr = x.as_mut_ptr().cast::<__m128i>(); + let y_ptr = y.as_mut_ptr().cast::<__m128i>(); unsafe { let mut x0_lo = _mm_loadu_si128(x_ptr); let mut x1_lo = _mm_loadu_si128(x_ptr.add(1)); @@ -295,7 +295,7 @@ impl Ssse3 { let log_m23 = self.skew[base + dist * 2]; for i in r..r + dist { - self.fft_butterfly_two_layers(data, pos + i, dist, log_m01, log_m23, log_m02) + self.fft_butterfly_two_layers(data, pos + i, dist, log_m01, log_m23, log_m02); } r += dist4; @@ -316,7 +316,7 @@ impl Ssse3 { if log_m == GF_MODULUS { utils::xor(y, x); } else { - self.fft_butterfly_partial(x, y, log_m) + self.fft_butterfly_partial(x, y, log_m); } r += 2; @@ -333,8 +333,8 @@ impl Ssse3 { #[inline(always)] fn ifftb_128(&self, x: &mut [u8; 64], y: &mut [u8; 64], log_m: GfElement) { let lut = &self.mul128[log_m as usize]; - let x_ptr = x.as_mut_ptr() as *mut __m128i; - let y_ptr = y.as_mut_ptr() as *mut __m128i; + let x_ptr = x.as_mut_ptr().cast::<__m128i>(); + let y_ptr = y.as_mut_ptr().cast::<__m128i>(); unsafe { let mut x0_lo = _mm_loadu_si128(x_ptr); @@ -421,7 +421,7 @@ impl Ssse3 { skew_delta: usize, ) { // Drop unsafe privileges - self.ifft_private(data, pos, size, truncated_size, skew_delta) + self.ifft_private(data, pos, size, truncated_size, skew_delta); } #[inline(always)] @@ -447,7 +447,7 @@ impl Ssse3 { let log_m23 = self.skew[base + dist * 2]; for i in r..r + dist { - self.ifft_butterfly_two_layers(data, pos + i, dist, log_m01, log_m23, log_m02) + self.ifft_butterfly_two_layers(data, pos + i, dist, log_m01, log_m23, log_m02); } r += dist4; @@ -482,7 +482,7 @@ impl Ssse3 { impl Ssse3 { #[target_feature(enable = "ssse3")] unsafe fn eval_poly_ssse3(erasures: &mut [GfElement; GF_ORDER], truncated_size: usize) { - utils::eval_poly(erasures, truncated_size) + utils::eval_poly(erasures, truncated_size); } } diff --git a/src/engine/tables.rs b/src/engine/tables.rs index 72078c3..2d3f1e8 100644 --- a/src/engine/tables.rs +++ b/src/engine/tables.rs @@ -51,9 +51,9 @@ pub type Mul128 = [Multiply128lutT; GF_ORDER]; /// Elements of the Mul128 table #[derive(Clone, Debug)] pub struct Multiply128lutT { - /// Lower half of GfElements + /// Lower half of `GfElements` pub lo: [u128; 4], - /// Upper half of GfElements + /// Upper half of `GfElements` pub hi: [u128; 4], } @@ -93,7 +93,7 @@ pub static EXP_LOG: LazyLock = LazyLock::new(initialize_exp_log); /// Lazily initialized logarithmic Walsh transform table. pub static LOG_WALSH: LazyLock> = LazyLock::new(initialize_log_walsh); -/// Lazily initialized multiplication table for the NoSimd engine. +/// Lazily initialized multiplication table for the `NoSimd` engine. pub static MUL16: LazyLock> = LazyLock::new(initialize_mul16); /// Lazily initialized multiplication table for SIMD engines. diff --git a/src/engine/utils.rs b/src/engine/utils.rs index e182f94..6d283ae 100644 --- a/src/engine/utils.rs +++ b/src/engine/utils.rs @@ -80,7 +80,7 @@ pub(crate) fn fft_skew_end( size: usize, truncated_size: usize, ) { - engine.fft(data, pos, size, truncated_size, pos + size) + engine.fft(data, pos, size, truncated_size, pos + size); } /// IFFT with `skew_delta = pos + size`. @@ -92,7 +92,7 @@ pub(crate) fn ifft_skew_end( size: usize, truncated_size: usize, ) { - engine.ifft(data, pos, size, truncated_size, pos + size) + engine.ifft(data, pos, size, truncated_size, pos + size); } // Formal derivative. diff --git a/src/lib.rs b/src/lib.rs index 9a0eaeb..ea844a1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,16 @@ #![doc = include_str!(concat!(env!("OUT_DIR"), "/README-rustdocified.md"))] #![deny(missing_docs)] +#![warn(clippy::pedantic, clippy::cargo)] +// Allow some lints from the pedantic category +#![allow( + clippy::must_use_candidate, + clippy::cast_ptr_alignment, + clippy::inline_always, + clippy::missing_errors_doc, + clippy::cast_possible_truncation, + clippy::large_stack_arrays, + clippy::wildcard_imports +)] use std::{collections::HashMap, fmt}; @@ -130,91 +141,83 @@ pub enum Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Error::DifferentShardSize { shard_bytes, got } => { + Self::DifferentShardSize { shard_bytes, got } => { write!( f, - "different shard size: expected {} bytes, got {} bytes", - shard_bytes, got + "different shard size: expected {shard_bytes} bytes, got {got} bytes" ) } - Error::DuplicateOriginalShardIndex { index } => { - write!(f, "duplicate original shard index: {}", index) + Self::DuplicateOriginalShardIndex { index } => { + write!(f, "duplicate original shard index: {index}") } - Error::DuplicateRecoveryShardIndex { index } => { - write!(f, "duplicate recovery shard index: {}", index) + Self::DuplicateRecoveryShardIndex { index } => { + write!(f, "duplicate recovery shard index: {index}") } - Error::InvalidOriginalShardIndex { + Self::InvalidOriginalShardIndex { original_count, index, } => { write!( f, - "invalid original shard index: {} >= original_count {}", - index, original_count, + "invalid original shard index: {index} >= original_count {original_count}", ) } - Error::InvalidRecoveryShardIndex { + Self::InvalidRecoveryShardIndex { recovery_count, index, } => { write!( f, - "invalid recovery shard index: {} >= recovery_count {}", - index, recovery_count, + "invalid recovery shard index: {index} >= recovery_count {recovery_count}", ) } - Error::InvalidShardSize { shard_bytes } => { + Self::InvalidShardSize { shard_bytes } => { write!( f, - "invalid shard size: {} bytes (must non-zero and multiple of 2)", - shard_bytes + "invalid shard size: {shard_bytes} bytes (must non-zero and multiple of 2)" ) } - Error::NotEnoughShards { + Self::NotEnoughShards { original_count, original_received_count, recovery_received_count, } => { write!( f, - "not enough shards: {} original + {} recovery < {} original_count", - original_received_count, recovery_received_count, original_count, + "not enough shards: {original_received_count} original + {recovery_received_count} recovery < {original_count} original_count", ) } - Error::TooFewOriginalShards { + Self::TooFewOriginalShards { original_count, original_received_count, } => { write!( f, - "too few original shards: got {} shards while original_count is {}", - original_received_count, original_count + "too few original shards: got {original_received_count} shards while original_count is {original_count}" ) } - Error::TooManyOriginalShards { original_count } => { + Self::TooManyOriginalShards { original_count } => { write!( f, - "too many original shards: got more than original_count ({}) shards", - original_count + "too many original shards: got more than original_count ({original_count}) shards" ) } - Error::UnsupportedShardCount { + Self::UnsupportedShardCount { original_count, recovery_count, } => { write!( f, - "unsupported shard count: {} original shards with {} recovery shards", - original_count, recovery_count + "unsupported shard count: {original_count} original shards with {recovery_count} recovery shards" ) } } @@ -275,7 +278,7 @@ where let result = encoder.encode()?; - Ok(result.recovery_iter().map(|s| s.to_vec()).collect()) + Ok(result.recovery_iter().map(<[u8]>::to_vec).collect()) } /// Decodes in one go using [`ReedSolomonDecoder`], @@ -315,13 +318,13 @@ where if original_received_count == original_count { // Nothing to do, original data is complete. return Ok(HashMap::new()); - } else { - return Err(Error::NotEnoughShards { - original_count, - original_received_count, - recovery_received_count: 0, - }); } + + return Err(Error::NotEnoughShards { + original_count, + original_received_count, + recovery_received_count: 0, + }); }; let mut decoder = ReedSolomonDecoder::new(original_count, recovery_count, shard_bytes)?; diff --git a/src/rate/encoder_work.rs b/src/rate/encoder_work.rs index 4da8de7..8596b15 100644 --- a/src/rate/encoder_work.rs +++ b/src/rate/encoder_work.rs @@ -72,17 +72,17 @@ impl EncoderWork { } pub(crate) fn encode_begin(&mut self) -> Result<(ShardsRefMut, usize, usize), Error> { - if self.original_received_count != self.original_count { - Err(Error::TooFewOriginalShards { - original_count: self.original_count, - original_received_count: self.original_received_count, - }) - } else { + if self.original_received_count == self.original_count { Ok(( self.shards.as_ref_mut(), self.original_count, self.recovery_count, )) + } else { + Err(Error::TooFewOriginalShards { + original_count: self.original_count, + original_received_count: self.original_received_count, + }) } } diff --git a/src/rate/rate_high.rs b/src/rate/rate_high.rs index a190def..bd177e7 100644 --- a/src/rate/rate_high.rs +++ b/src/rate/rate_high.rs @@ -99,7 +99,7 @@ impl RateEncoder for HighRateEncoder { ) -> Result { let mut work = work.unwrap_or_default(); Self::reset_work(original_count, recovery_count, shard_bytes, &mut work)?; - Ok(Self { work, engine }) + Ok(Self { engine, work }) } fn reset( @@ -170,13 +170,12 @@ impl RateDecoder for HighRateDecoder { } fn decode(&mut self) -> Result { - let (mut work, original_count, recovery_count, received) = - if let Some(stuff) = self.work.decode_begin()? { - stuff - } else { - // Nothing to do, original data is complete. - return Ok(DecoderResult::new(&mut self.work)); - }; + let Some((mut work, original_count, recovery_count, received)) = + self.work.decode_begin()? + else { + // Nothing to do, original data is complete. + return Ok(DecoderResult::new(&mut self.work)); + }; let chunk_size = recovery_count.next_power_of_two(); let original_end = chunk_size + original_count; @@ -267,7 +266,7 @@ impl RateDecoder for HighRateDecoder { ) -> Result { let mut work = work.unwrap_or_default(); Self::reset_work(original_count, recovery_count, shard_bytes, &mut work)?; - Ok(Self { work, engine }) + Ok(Self { engine, work }) } fn reset( diff --git a/src/rate/rate_low.rs b/src/rate/rate_low.rs index 99c4cd6..b644b9b 100644 --- a/src/rate/rate_low.rs +++ b/src/rate/rate_low.rs @@ -99,7 +99,7 @@ impl RateEncoder for LowRateEncoder { ) -> Result { let mut work = work.unwrap_or_default(); Self::reset_work(original_count, recovery_count, shard_bytes, &mut work)?; - Ok(Self { work, engine }) + Ok(Self { engine, work }) } fn reset( @@ -170,13 +170,12 @@ impl RateDecoder for LowRateDecoder { } fn decode(&mut self) -> Result { - let (mut work, original_count, recovery_count, received) = - if let Some(stuff) = self.work.decode_begin()? { - stuff - } else { - // Nothing to do, original data is complete. - return Ok(DecoderResult::new(&mut self.work)); - }; + let Some((mut work, original_count, recovery_count, received)) = + self.work.decode_begin()? + else { + // Nothing to do, original data is complete. + return Ok(DecoderResult::new(&mut self.work)); + }; let chunk_size = original_count.next_power_of_two(); let recovery_end = chunk_size + recovery_count; @@ -267,7 +266,7 @@ impl RateDecoder for LowRateDecoder { ) -> Result { let mut work = work.unwrap_or_default(); Self::reset_work(original_count, recovery_count, shard_bytes, &mut work)?; - Ok(Self { work, engine }) + Ok(Self { engine, work }) } fn reset(