mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-27 15:37:02 +00:00
fix(checksum): align multipart CRC64NVME with full object (#2286)
This commit is contained in:
@@ -981,17 +981,17 @@ const CRC64_NVME_POLYNOMIAL: u64 = 0xad93d23594c93659;
|
||||
/// GF(2) matrix multiplication
|
||||
fn gf2_matrix_times(mat: &[u64], mut vec: u64) -> u64 {
|
||||
let mut sum = 0u64;
|
||||
let mut mat_iter = mat.iter();
|
||||
for &m in mat {
|
||||
if vec == 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
while vec != 0 {
|
||||
if vec & 1 != 0
|
||||
&& let Some(&m) = mat_iter.next()
|
||||
{
|
||||
if vec & 1 != 0 {
|
||||
sum ^= m;
|
||||
}
|
||||
vec >>= 1;
|
||||
mat_iter.next();
|
||||
}
|
||||
|
||||
sum
|
||||
}
|
||||
|
||||
@@ -1128,3 +1128,62 @@ fn crc64_combine(poly: u64, crc1: u64, crc2: u64, len2: i64) -> u64 {
|
||||
// Return combined crc
|
||||
crc1n ^ crc2
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{Checksum, ChecksumType};
|
||||
|
||||
#[test]
|
||||
fn crc64_nvme_add_part_matches_full_object_checksum() {
|
||||
let data = (0..200_000).map(|i| (i % 251) as u8).collect::<Vec<_>>();
|
||||
let split_at = 73_421;
|
||||
let (first, second) = data.split_at(split_at);
|
||||
|
||||
let expected = Checksum::new_from_data(ChecksumType::CRC64_NVME, &data).expect("full checksum");
|
||||
let first_checksum = Checksum::new_from_data(ChecksumType::CRC64_NVME, first).expect("first checksum");
|
||||
let second_checksum = Checksum::new_from_data(ChecksumType::CRC64_NVME, second).expect("second checksum");
|
||||
|
||||
let mut combined = Checksum {
|
||||
checksum_type: ChecksumType::CRC64_NVME,
|
||||
..Default::default()
|
||||
};
|
||||
combined
|
||||
.add_part(&first_checksum, first.len() as i64)
|
||||
.expect("add first part");
|
||||
combined
|
||||
.add_part(&second_checksum, second.len() as i64)
|
||||
.expect("add second part");
|
||||
|
||||
assert_eq!(combined.encoded, expected.encoded);
|
||||
assert_eq!(combined.raw, expected.raw);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn crc32c_add_part_matches_full_object_checksum() {
|
||||
let data = (0..32_768).map(|i| (255 - (i % 251)) as u8).collect::<Vec<_>>();
|
||||
let (first, rest) = data.split_at(7_777);
|
||||
let (second, third) = rest.split_at(13_333);
|
||||
|
||||
let expected = Checksum::new_from_data(ChecksumType::CRC32C, &data).expect("full checksum");
|
||||
let first_checksum = Checksum::new_from_data(ChecksumType::CRC32C, first).expect("first checksum");
|
||||
let second_checksum = Checksum::new_from_data(ChecksumType::CRC32C, second).expect("second checksum");
|
||||
let third_checksum = Checksum::new_from_data(ChecksumType::CRC32C, third).expect("third checksum");
|
||||
|
||||
let mut combined = Checksum {
|
||||
checksum_type: ChecksumType::CRC32C,
|
||||
..Default::default()
|
||||
};
|
||||
combined
|
||||
.add_part(&first_checksum, first.len() as i64)
|
||||
.expect("add first part");
|
||||
combined
|
||||
.add_part(&second_checksum, second.len() as i64)
|
||||
.expect("add second part");
|
||||
combined
|
||||
.add_part(&third_checksum, third.len() as i64)
|
||||
.expect("add third part");
|
||||
|
||||
assert_eq!(combined.encoded, expected.encoded);
|
||||
assert_eq!(combined.raw, expected.raw);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user