increase #[const_eval_limit] to avoid compilation errors for larger byte slices

This commit is contained in:
Jonathan Strong 2022-10-05 14:58:35 -04:00
parent 5dbfa46a34
commit 7324963d2b
3 changed files with 44 additions and 8 deletions

View File

@ -1,6 +1,6 @@
[package] [package]
name = "const-crc32" name = "const-crc32"
version = "1.0.1" version = "1.1.0"
edition = "2021" edition = "2021"
authors = ["Jonathan Strong <jstrong@shipyard.rs>"] authors = ["Jonathan Strong <jstrong@shipyard.rs>"]
license = "MIT" license = "MIT"

View File

@ -15,3 +15,10 @@ assert_eq!(CKSUM, 0x414fa339_u32);
This is a naive implementation that should be expected to have poor performance This is a naive implementation that should be expected to have poor performance
if used on dynamic data at runtime. Usage should generally be restricted to declaring if used on dynamic data at runtime. Usage should generally be restricted to declaring
`const` variables based on `static` or `const` data available at build time. `const` variables based on `static` or `const` data available at build time.
## `#[const_eval_limit]`
This crate sets `#[const_eval_limit]` to 1,000,000,000 to avoid hitting the limit when
executing the `const fn`, which requires `#![feature(const_eval_limit)]`.
Compile time for `const` data around 100k is less than 1s.

View File

@ -8,7 +8,11 @@
//! assert_eq!(CKSUM, 0x414fa339_u32); //! assert_eq!(CKSUM, 0x414fa339_u32);
//! ``` //! ```
/// typically crc32 implementations set up a [u32; 256] lookup table. this computes #![feature(const_eval_limit)]
#![const_eval_limit = "1000000000"]
/// used to generate up a [u32; 256] lookup table in `crc32`. this computes
/// the table on demand for a given "index" `i` /// the table on demand for a given "index" `i`
const fn table_fn(i: u32) -> u32 { const fn table_fn(i: u32) -> u32 {
let mut out = i; let mut out = i;
@ -25,6 +29,20 @@ const fn table_fn(i: u32) -> u32 {
out out
} }
const fn get_table() -> [u32; 256] {
let mut table: [u32; 256] = [0u32; 256];
let mut i = 0;
while i < 256 {
table[i] = table_fn(i as u32);
i += 1;
}
table
}
const TABLE: [u32; 256] = get_table();
/// A `const fn` crc32 checksum implementation. /// A `const fn` crc32 checksum implementation.
/// ///
/// Note: this is a naive implementation that should be expected to have poor performance /// Note: this is a naive implementation that should be expected to have poor performance
@ -32,12 +50,9 @@ const fn table_fn(i: u32) -> u32 {
/// `const` variables based on `static` or `const` data available at build time. /// `const` variables based on `static` or `const` data available at build time.
pub const fn crc32(buf: &[u8]) -> u32 { pub const fn crc32(buf: &[u8]) -> u32 {
let mut out = !0u32; let mut out = !0u32;
let mut i = 0; let mut i = 0usize;
loop { while i < buf.len() {
if i >= buf.len() { break } out = (out >> 8) ^ TABLE[((out & 0xff) ^ (buf[i] as u32)) as usize];
out = (out >> 8) ^ table_fn((out & 0xff) ^ (buf[i] as u32));
i += 1; i += 1;
} }
!out !out
@ -91,4 +106,18 @@ mod tests {
assert_eq!(crc32(&buf[..]), crc32fast::hash(&buf[..])); assert_eq!(crc32(&buf[..]), crc32fast::hash(&buf[..]));
} }
} }
#[test]
fn check_const_eval_limit_not_reached_on_100k_data() {
const BYTES: &[u8] = &[42u8; 1024 * 100];
const CKSUM: u32 = crc32(BYTES);
assert_eq!(CKSUM, crc32fast::hash(&BYTES[..]));
}
// #[test]
// fn check_const_eval_limit_not_reached_on_1mb_data() {
// const BYTES: &[u8] = &[42u8; 1024 * 1024];
// const CKSUM: u32 = crc32(BYTES);
// assert_eq!(CKSUM, crc32fast::hash(&BYTES[..]));
// }
} }