diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-05-10 07:03:10 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-05-10 07:03:10 +0000 |
commit | fd4a7f8b57c257a71dd853fb67985e83da4a3e9e (patch) | |
tree | 041d4dd236452f377fef6d1e896c542939286833 | |
parent | 8807a59a90cf6b23f30330e43d5ee26dded503a9 (diff) | |
parent | 41fbe6f14e90b7d4815bbf98ab6f73c62ef0c169 (diff) | |
download | crc32fast-fd4a7f8b57c257a71dd853fb67985e83da4a3e9e.tar.gz |
Snap for 8564071 from 41fbe6f14e90b7d4815bbf98ab6f73c62ef0c169 to mainline-tethering-releaseaml_tet_331910040aml_tet_331820050aml_tet_331711040aml_tet_331511160aml_tet_331511000aml_tet_331412030aml_tet_331312080aml_tet_331117000aml_tet_331012080aml_tet_330911010aml_tet_330812150android13-mainline-tethering-release
Change-Id: I9b835d91192742e7dafae49f5e34c34eedce20b6
-rw-r--r-- | .cargo_vcs_info.json | 7 | ||||
-rw-r--r-- | .travis.yml | 3 | ||||
-rw-r--r-- | Android.bp | 42 | ||||
-rw-r--r-- | Cargo.toml | 15 | ||||
-rw-r--r-- | Cargo.toml.orig | 6 | ||||
-rw-r--r-- | METADATA | 10 | ||||
-rw-r--r-- | README.md | 42 | ||||
-rw-r--r-- | TEST_MAPPING | 43 | ||||
-rw-r--r-- | benches/bench.rs | 12 | ||||
-rw-r--r-- | cargo2android.json | 10 | ||||
-rw-r--r-- | src/lib.rs | 71 | ||||
-rw-r--r-- | src/specialized/aarch64.rs | 2 | ||||
-rw-r--r-- | src/specialized/mod.rs | 1 | ||||
-rw-r--r-- | src/specialized/pclmulqdq.rs | 2 | ||||
-rw-r--r-- | src/table.rs | 5 |
15 files changed, 214 insertions, 57 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 3a72e82..492a5e3 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,5 +1,6 @@ { "git": { - "sha1": "c6a423b4da80da8e80f757f94d2e718187302e40" - } -} + "sha1": "e9c65bdb6d982cb7a8593408dca81cca2932bdc6" + }, + "path_in_vcs": "" +}
\ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 27b486a..d97e86f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ cache: matrix: include: - - rust: 1.34.0 + - rust: 1.46.0 # MSRV - rust: stable - rust: beta - rust: nightly @@ -37,7 +37,6 @@ script: then rustup target add $CROSS_CHECK cargo check --target $CROSS_CHECK - cargo check --tests --target $CROSS_CHECK cargo check --target $CROSS_CHECK --no-default-features elif [[ "$CROSS_TEST" ]] then @@ -1,4 +1,5 @@ -// This file is generated by cargo2android.py --run --device --dependencies. +// This file is generated by cargo2android.py --config cargo2android.json. +// Do not modify this file as changes will be overridden on upgrade. package { default_applicable_licenses: ["external_rust_crates_crc32fast_license"], @@ -36,23 +37,50 @@ license { ], } +rust_test { + name: "crc32fast_test_src_lib", + host_supported: true, + crate_name: "crc32fast", + cargo_env_compat: true, + cargo_pkg_version: "1.3.2", + srcs: ["src/lib.rs"], + test_suites: ["general-tests"], + auto_gen_config: true, + test_options: { + unit_test: true, + }, + edition: "2015", + features: [ + "default", + "std", + ], + cfgs: ["crc32fast_stdarchx86"], + rustlibs: [ + "libbencher", + "libcfg_if", + "libquickcheck", + "librand", + ], +} + rust_library { name: "libcrc32fast", host_supported: true, crate_name: "crc32fast", + cargo_env_compat: true, + cargo_pkg_version: "1.3.2", srcs: ["src/lib.rs"], edition: "2015", features: [ "default", "std", ], - flags: [ - "--cfg crc32fast_stdarchx86", - ], + cfgs: ["crc32fast_stdarchx86"], rustlibs: [ "libcfg_if", ], + apex_available: [ + "//apex_available:platform", + "com.android.virt", + ], } - -// dependent_library ["feature_list"] -// cfg-if-1.0.0 @@ -3,16 +3,15 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies +# to registry (e.g., crates.io) dependencies. # -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. [package] name = "crc32fast" -version = "1.2.1" +version = "1.3.2" authors = ["Sam Rijs <srijs@airpost.net>", "Alex Crichton <alex@alexcrichton.com>"] description = "Fast, SIMD-accelerated CRC32 (IEEE) checksum computation" readme = "README.md" @@ -29,11 +28,11 @@ version = "1.0" version = "0.1" [dev-dependencies.quickcheck] -version = "0.9" +version = "1.0" default-features = false [dev-dependencies.rand] -version = "0.7" +version = "0.8" [features] default = ["std"] diff --git a/Cargo.toml.orig b/Cargo.toml.orig index 6da29ea..83804b3 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,6 +1,6 @@ [package] name = "crc32fast" -version = "1.2.1" +version = "1.3.2" license = "MIT OR Apache-2.0" authors = [ "Sam Rijs <srijs@airpost.net>", @@ -16,8 +16,8 @@ cfg-if = "1.0" [dev-dependencies] bencher = "0.1" -quickcheck = { version = "0.9", default-features = false } -rand = "0.7" +quickcheck = { version = "1.0", default-features = false } +rand = "0.8" [features] default = ["std"] @@ -7,13 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/crc32fast/crc32fast-1.2.1.crate" + value: "https://static.crates.io/crates/crc32fast/crc32fast-1.3.2.crate" } - version: "1.2.1" + version: "1.3.2" license_type: NOTICE last_upgrade_date { - year: 2021 - month: 2 - day: 6 + year: 2022 + month: 3 + day: 1 } } @@ -1,19 +1,31 @@ # crc32fast [![Build Status][travis-img]][travis] [![Crates.io][crates-img]][crates] [![Documentation][docs-img]][docs] -[travis-img]: https://travis-ci.com/srijs/rust-crc32fast.svg?branch=master -[travis]: https://travis-ci.com/srijs/rust-crc32fast -[crates-img]: https://img.shields.io/crates/v/crc32fast.svg -[crates]: https://crates.io/crates/crc32fast -[docs-img]: https://docs.rs/crc32fast/badge.svg -[docs]: https://docs.rs/crc32fast +[travis-img]: https://travis-ci.com/srijs/rust-crc32fast.svg?branch=master +[travis]: https://travis-ci.com/srijs/rust-crc32fast +[crates-img]: https://img.shields.io/crates/v/crc32fast.svg +[crates]: https://crates.io/crates/crc32fast +[docs-img]: https://docs.rs/crc32fast/badge.svg +[docs]: https://docs.rs/crc32fast _Fast, SIMD-accelerated CRC32 (IEEE) checksum computation_ ## Usage +### Simple usage + +For simple use-cases, you can call the `hash` convenience function to +directly compute the CRC32 checksum for a given byte slice: + ```rust -extern crate crc32fast; +let checksum = crc32fast::hash(b"foo bar baz"); +``` +### Advanced usage + +For use-cases that require more flexibility or performance, for example when +processing large amounts of data, you can create and manipulate a `Hasher`: + +```rust use crc32fast::Hasher; let mut hasher = Hasher::new(); @@ -33,10 +45,10 @@ Calling the `Hasher::new` constructor at runtime will perform a feature detectio optimal implementation for the current CPU feature set. | crate | version | variant | ns/iter | MB/s | -|-------------------------------------|---------|-----------|---------|------| -| [crc](https://crates.io/crates/crc) | 1.8.1 | n/a | 4,926 | 207 | -| crc32fast (this crate) | 1.0.0 | baseline | 683 | 1499 | -| crc32fast (this crate) | 1.0.0 | pclmulqdq | 140 | 7314 | +| ----------------------------------- | ------- | --------- | ------- | ---- | +| [crc](https://crates.io/crates/crc) | 1.8.1 | n/a | 4,926 | 207 | +| crc32fast (this crate) | 1.0.0 | baseline | 683 | 1499 | +| crc32fast (this crate) | 1.0.0 | pclmulqdq | 140 | 7314 | ## Memory Safety @@ -67,10 +79,10 @@ Currently, enabling this feature flag will make the optimized `aarch64` implemen This project is licensed under either of - * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or - http://www.apache.org/licenses/LICENSE-2.0) - * MIT license ([LICENSE-MIT](LICENSE-MIT) or - http://opensource.org/licenses/MIT) +- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or + http://www.apache.org/licenses/LICENSE-2.0) +- MIT license ([LICENSE-MIT](LICENSE-MIT) or + http://opensource.org/licenses/MIT) at your option. diff --git a/TEST_MAPPING b/TEST_MAPPING new file mode 100644 index 0000000..a46d45f --- /dev/null +++ b/TEST_MAPPING @@ -0,0 +1,43 @@ +// Generated by update_crate_tests.py for tests that depend on this crate. +{ + "presubmit": [ + { + "name": "ZipFuseTest" + }, + { + "name": "crc32fast_test_src_lib" + }, + { + "name": "libapkverify.integration_test" + }, + { + "name": "libapkverify.test" + }, + { + "name": "microdroid_manager_test" + }, + { + "name": "virtualizationservice_device_test" + } + ], + "presubmit-rust": [ + { + "name": "ZipFuseTest" + }, + { + "name": "crc32fast_test_src_lib" + }, + { + "name": "libapkverify.integration_test" + }, + { + "name": "libapkverify.test" + }, + { + "name": "microdroid_manager_test" + }, + { + "name": "virtualizationservice_device_test" + } + ] +} diff --git a/benches/bench.rs b/benches/bench.rs index d702df0..53b3d83 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -21,19 +21,23 @@ fn bench(b: &mut Bencher, size: usize, hasher_init: Hasher) { } fn bench_kilobyte_baseline(b: &mut Bencher) { - bench(b, 1024, Hasher::internal_new_baseline(0)) + bench(b, 1024, Hasher::internal_new_baseline(0, 0)) } fn bench_kilobyte_specialized(b: &mut Bencher) { - bench(b, 1024, Hasher::internal_new_specialized(0).unwrap()) + bench(b, 1024, Hasher::internal_new_specialized(0, 0).unwrap()) } fn bench_megabyte_baseline(b: &mut Bencher) { - bench(b, 1024 * 1024, Hasher::internal_new_baseline(0)) + bench(b, 1024 * 1024, Hasher::internal_new_baseline(0, 0)) } fn bench_megabyte_specialized(b: &mut Bencher) { - bench(b, 1024 * 1024, Hasher::internal_new_specialized(0).unwrap()) + bench( + b, + 1024 * 1024, + Hasher::internal_new_specialized(0, 0).unwrap(), + ) } benchmark_group!( diff --git a/cargo2android.json b/cargo2android.json new file mode 100644 index 0000000..ac56e26 --- /dev/null +++ b/cargo2android.json @@ -0,0 +1,10 @@ +{ + "apex-available": [ + "//apex_available:platform", + "com.android.virt" + ], + "dependencies": true, + "device": true, + "run": true, + "tests": true +}
\ No newline at end of file @@ -1,4 +1,20 @@ -//! ## Example +//! Fast, SIMD-accelerated CRC32 (IEEE) checksum computation. +//! +//! ## Usage +//! +//! ### Simple usage +//! +//! For simple use-cases, you can call the [`hash()`] convenience function to +//! directly compute the CRC32 checksum for a given byte slice: +//! +//! ```rust +//! let checksum = crc32fast::hash(b"foo bar baz"); +//! ``` +//! +//! ### Advanced usage +//! +//! For use-cases that require more flexibility or performance, for example when +//! processing large amounts of data, you can create and manipulate a [`Hasher`]: //! //! ```rust //! use crc32fast::Hasher; @@ -15,7 +31,7 @@ //! - A fast baseline implementation which processes up to 16 bytes per iteration //! - An optimized implementation for modern `x86` using `sse` and `pclmulqdq` instructions //! -//! Calling the `Hasher::new` constructor at runtime will perform a feature detection to select the most +//! Calling the [`Hasher::new`] constructor at runtime will perform a feature detection to select the most //! optimal implementation for the current CPU feature set. #![cfg_attr(not(feature = "std"), no_std)] @@ -43,6 +59,15 @@ mod combine; mod specialized; mod table; +/// Computes the CRC32 hash of a byte slice. +/// +/// Check out [`Hasher`] for more advanced use-cases. +pub fn hash(buf: &[u8]) -> u32 { + let mut h = Hasher::new(); + h.update(buf); + h.finalize() +} + #[derive(Clone)] enum State { Baseline(baseline::State), @@ -72,25 +97,35 @@ impl Hasher { /// This works just like `Hasher::new`, except that it allows for an initial /// CRC32 state to be passed in. pub fn new_with_initial(init: u32) -> Self { - Self::internal_new_specialized(init).unwrap_or_else(|| Self::internal_new_baseline(init)) + Self::new_with_initial_len(init, 0) + } + + /// Create a new `Hasher` with an initial CRC32 state. + /// + /// As `new_with_initial`, but also accepts a length (in bytes). The + /// resulting object can then be used with `combine` to compute `crc(a || + /// b)` from `crc(a)`, `crc(b)`, and `len(b)`. + pub fn new_with_initial_len(init: u32, amount: u64) -> Self { + Self::internal_new_specialized(init, amount) + .unwrap_or_else(|| Self::internal_new_baseline(init, amount)) } #[doc(hidden)] // Internal-only API. Don't use. - pub fn internal_new_baseline(init: u32) -> Self { + pub fn internal_new_baseline(init: u32, amount: u64) -> Self { Hasher { - amount: 0, + amount, state: State::Baseline(baseline::State::new(init)), } } #[doc(hidden)] // Internal-only API. Don't use. - pub fn internal_new_specialized(init: u32) -> Option<Self> { + pub fn internal_new_specialized(init: u32, amount: u64) -> Option<Self> { { if let Some(state) = specialized::State::new(init) { return Some(Hasher { - amount: 0, + amount, state: State::Specialized(state), }); } @@ -174,5 +209,27 @@ mod test { hash_a.finalize() == hash_c.finalize() } + + fn combine_from_len(bytes_1: Vec<u8>, bytes_2: Vec<u8>) -> bool { + let mut hash_a = Hasher::new(); + hash_a.update(&bytes_1); + let a = hash_a.finalize(); + + let mut hash_b = Hasher::new(); + hash_b.update(&bytes_2); + let b = hash_b.finalize(); + + let mut hash_ab = Hasher::new(); + hash_ab.update(&bytes_1); + hash_ab.update(&bytes_2); + let ab = hash_ab.finalize(); + + let mut reconstructed = Hasher::new_with_initial_len(a, bytes_1.len() as u64); + let hash_b_reconstructed = Hasher::new_with_initial_len(b, bytes_2.len() as u64); + + reconstructed.combine(&hash_b_reconstructed); + + reconstructed.finalize() == ab + } } } diff --git a/src/specialized/aarch64.rs b/src/specialized/aarch64.rs index ce05261..49de6b0 100644 --- a/src/specialized/aarch64.rs +++ b/src/specialized/aarch64.rs @@ -7,7 +7,7 @@ pub struct State { impl State { pub fn new(state: u32) -> Option<Self> { - if is_aarch64_feature_detected!("crc") { + if std::arch::is_aarch64_feature_detected!("crc") { // SAFETY: The conditions above ensure that all // required instructions are supported by the CPU. Some(Self { state }) diff --git a/src/specialized/mod.rs b/src/specialized/mod.rs index d4b0b8d..525a42c 100644 --- a/src/specialized/mod.rs +++ b/src/specialized/mod.rs @@ -1,6 +1,7 @@ cfg_if! { if #[cfg(all( crc32fast_stdarchx86, + target_feature = "sse2", any(target_arch = "x86", target_arch = "x86_64") ))] { mod pclmulqdq; diff --git a/src/specialized/pclmulqdq.rs b/src/specialized/pclmulqdq.rs index 6abb08b..84a60ca 100644 --- a/src/specialized/pclmulqdq.rs +++ b/src/specialized/pclmulqdq.rs @@ -89,7 +89,7 @@ unsafe fn debug(_s: &str, a: arch::__m128i) -> arch::__m128i { } #[target_feature(enable = "pclmulqdq", enable = "sse2", enable = "sse4.1")] -pub unsafe fn calculate(crc: u32, mut data: &[u8]) -> u32 { +unsafe fn calculate(crc: u32, mut data: &[u8]) -> u32 { // In theory we can accelerate smaller chunks too, but for now just rely on // the fallback implementation as it's too much hassle and doesn't seem too // beneficial. diff --git a/src/table.rs b/src/table.rs index 9354601..78b89c3 100644 --- a/src/table.rs +++ b/src/table.rs @@ -1,4 +1,7 @@ -pub const CRC32_TABLE: [[u32; 256]; 16] = [ +// NOTE: This is static instead of const to ensure that indexing into this table +// doesn't result in large memmoves when in debug mode, which can significantly +// impact performance. +pub static CRC32_TABLE: [[u32; 256]; 16] = [ [ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, |