Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ asyncband = { version = "0.7.1", features = ["barrier", "semaphore", "watch"] }
cargo_metadata = { version = "0.23.1" }
clap = { version = "4.6.5", features = ["derive"] }
crc-fast = { version = "1.10.0", default-features = false, features = ["std"] }
hashcrew = { version = "0.2.0", features = ["std", "xxhash"] }
hashcrew = { version = "0.3.0", features = ["std", "crc", "xxhash"] }
io-uring = { version = "0.7.14" }
libc = { version = "0.2.189" }
log = { version = "0.4.31", features = ["kv"] }
Expand Down
2 changes: 1 addition & 1 deletion cache2/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ rustdoc-args = ["--cfg", "docsrs"]

[dependencies]
asyncband = { workspace = true }
crc-fast = { workspace = true }
hashcrew = { workspace = true }
log = { workspace = true }
tokio = { workspace = true }

[dev-dependencies]
crc-fast = { workspace = true }
quickcheck = { workspace = true }
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }

Expand Down
43 changes: 37 additions & 6 deletions cache2/src/checksum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@
//! retains a portable software fallback. This wrapper keeps the cache's codec
//! API and checksum values independent of that implementation detail.

use crc_fast::CrcAlgorithm;
use crc_fast::Digest;
use crc_fast::crc32_iscsi;
use hashcrew::crc::Crc32Iscsi;
use hashcrew::crc::crc32_iscsi;

/// Computes the standard CRC32C checksum of `bytes`.
pub fn crc32c(bytes: &[u8]) -> u32 {
Expand All @@ -30,13 +29,13 @@ pub fn crc32c(bytes: &[u8]) -> u32 {
/// Incremental CRC32C state, useful for checksum a key and value without first joining them in a
/// temporary allocation.
pub struct Crc32c {
digest: Digest,
digest: Crc32Iscsi,
}

impl Crc32c {
pub fn new() -> Self {
Self {
digest: Digest::new(CrcAlgorithm::Crc32Iscsi),
digest: Crc32Iscsi::new(),
}
}

Expand All @@ -45,7 +44,7 @@ impl Crc32c {
}

pub fn finish(self) -> u32 {
self.digest.finalize() as u32
self.digest.digest()
}
}

Expand All @@ -57,11 +56,43 @@ impl Default for Crc32c {

#[cfg(test)]
mod tests {
use crate::checksum::Crc32c;
use crate::checksum::crc32c;

#[test]
fn matches_the_crc32c_check_value() {
assert_eq!(crc32c(b"123456789"), 0xe306_9283);
assert_eq!(crc32c(b""), 0);
}

#[test]
fn fragmented_checksums_match_the_previous_implementation() {
let bytes: Vec<_> = (0..65_544).map(|index| (index * 37) as u8).collect();
for offset in [0, 1, 7] {
for len in [0, 1, 44, 48, 4092, 4096, 65_537] {
let input = &bytes[offset..offset + len];
let expected = crc_fast::crc32_iscsi(input);
assert_eq!(crc32c(input), expected);
for split in [0, len.min(44), len.min(56), len / 2, len] {
let mut checksum = Crc32c::new();
checksum.update(&input[..split]);
checksum.update(&[]);
checksum.update(&input[split..]);
assert_eq!(checksum.finish(), expected, "len={len}, split={split}");
}
}
}

// Record headers, index pages, and recovery pages zero their checksum
// field without concatenating the surrounding slices.
for (len, checksum_offset) in [(48, 44), (4096, 56), (4096, 4092)] {
let mut page = bytes[..len].to_vec();
page[checksum_offset..checksum_offset + 4].fill(0);
let mut checksum = Crc32c::new();
checksum.update(&page[..checksum_offset]);
checksum.update(&[0; 4]);
checksum.update(&page[checksum_offset + 4..]);
assert_eq!(checksum.finish(), crc_fast::crc32_iscsi(&page));
}
}
Comment on lines +68 to +97

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once rolling updates finished, we can drop this case and remove the dev-dependencies.

}