Skip to content

Commit 3adb117

Browse files
committed
cksum: Use crc_fast::Digest on the fly to improve performances
1 parent b3d71e3 commit 3adb117

File tree

2 files changed

+27
-30
lines changed

2 files changed

+27
-30
lines changed

src/uucore/src/lib/features/checksum.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1155,7 +1155,7 @@ where
11551155

11561156
pub fn digest_reader<T: Read>(
11571157
digest: &mut Box<dyn Digest>,
1158-
reader: &mut BufReader<T>,
1158+
reader: &mut T,
11591159
binary: bool,
11601160
output_bits: usize,
11611161
) -> io::Result<(String, usize)> {

src/uucore/src/lib/features/sum.rs

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -138,51 +138,48 @@ impl Digest for Sm3 {
138138
}
139139
}
140140

141-
pub struct Crc {
142-
state: u32,
143-
size: usize,
144-
// Store data for SIMD processing
145-
data_buffer: Vec<u8>,
141+
pub struct Crc(crc_fast::Digest);
142+
143+
impl Crc {
144+
/// POSIX cksum SIMD configuration for crc-fast
145+
/// This uses SIMD instructions (PCLMULQDQ) for fast CRC computation
146+
fn get_posix_cksum_params() -> crc_fast::CrcParams {
147+
crc_fast::CrcParams::new(
148+
"CRC-32/CKSUM", // Name
149+
32, // Width
150+
0x04c11db7, // Polynomial
151+
0x00000000, // Initial CRC value: 0 (not 0xffffffff)
152+
false, // No input reflection (refin)
153+
0xffffffff, // XOR output with 0xffffffff (xorout)
154+
0, // Check value (not used)
155+
)
156+
}
146157
}
147158

148159
impl Digest for Crc {
149160
fn new() -> Self {
150-
Self {
151-
state: 0,
152-
size: 0,
153-
data_buffer: Vec::with_capacity(8192),
154-
}
161+
Self(crc_fast::Digest::new_with_params(
162+
Self::get_posix_cksum_params(),
163+
))
155164
}
156165

157166
fn hash_update(&mut self, input: &[u8]) {
158-
self.size += input.len();
159-
// Store data for SIMD processing
160-
self.data_buffer.extend_from_slice(input);
167+
self.0.update(input);
161168
}
162169

163170
fn hash_finalize(&mut self, out: &mut [u8]) {
164-
// Add the size bytes to the data buffer
165-
let mut sz = self.size;
166-
while sz != 0 {
167-
self.data_buffer.push(sz as u8);
168-
sz >>= 8;
169-
}
170-
171-
// Use SIMD-accelerated CRC computation
172-
self.state = checksum_with_params(get_posix_cksum_params(), &self.data_buffer) as u32;
173-
out.copy_from_slice(&self.state.to_ne_bytes());
171+
let xout = self.0.finalize();
172+
out.copy_from_slice(&xout.to_ne_bytes());
174173
}
175174

176175
fn result_str(&mut self) -> String {
177-
let mut _out: Vec<u8> = vec![0; 4];
178-
self.hash_finalize(&mut _out);
179-
format!("{}", self.state)
176+
let mut out: [u8; 8] = [0; 8];
177+
self.hash_finalize(&mut out);
178+
u64::from_ne_bytes(out).to_string()
180179
}
181180

182181
fn reset(&mut self) {
183-
self.state = 0;
184-
self.size = 0;
185-
self.data_buffer.clear();
182+
self.0.reset();
186183
}
187184

188185
fn output_bits(&self) -> usize {

0 commit comments

Comments
 (0)