From 027f720cbcef0dfe2bf4f6bdc63c0110d784a235 Mon Sep 17 00:00:00 2001 From: tison Date: Wed, 2 Sep 2026 17:49:47 +0800 Subject: [PATCH 1/6] refactor: publish the crate as hashcrew Hashcrew will debut as a new 0.1.0 crate rather than continue rache's release line. Rename the package, source tree, imports, documentation, CI, benchmarks, tests, and release tooling together so every checked surface agrees on the public crate identity. Keep the existing fast/rache repository URLs until that repository itself is renamed, avoiding links to a location that does not exist yet. --- .github/workflows/ci.yml | 10 +- AGENTS.md | 2 +- ARCHITECTURE.md | 4 +- CHANGELOG.md | 30 +---- Cargo.lock | 14 +-- Cargo.toml | 4 +- HISTORY.md | 10 +- README.md | 66 +++++------ RELEASE.md | 14 +-- THIRD_PARTY_NOTICES.md | 6 +- benchmarks/Cargo.toml | 2 +- benchmarks/README.md | 4 +- benchmarks/benches/streaming.rs | 60 +++++----- benchmarks/benches/throughput.rs | 110 +++++++++--------- examples/Cargo.toml | 2 +- examples/src/hash_file.rs | 2 +- {rache => hashcrew}/Cargo.toml | 6 +- {rache => hashcrew}/LICENSE | 0 {rache => hashcrew}/THIRD_PARTY_NOTICES.md | 6 +- {rache => hashcrew}/src/cityhash/mod.rs | 4 +- {rache => hashcrew}/src/fnv/mod.rs | 10 +- {rache => hashcrew}/src/lib.rs | 18 +-- {rache => hashcrew}/src/murmur/mod.rs | 10 +- {rache => hashcrew}/src/xxhash/kernel/mod.rs | 2 +- {rache => hashcrew}/src/xxhash/kernel/neon.rs | 0 .../src/xxhash/kernel/scalar.rs | 0 {rache => hashcrew}/src/xxhash/kernel/x86.rs | 0 {rache => hashcrew}/src/xxhash/mod.rs | 10 +- {rache => hashcrew}/src/xxhash/xxh3.rs | 0 {rache => hashcrew}/src/xxhash/xxh32.rs | 0 {rache => hashcrew}/src/xxhash/xxh64.rs | 0 tests-integration/Cargo.toml | 2 +- tests-integration/tests/cityhash.rs | 14 +-- tests-integration/tests/io.rs | 26 ++--- tests-integration/tests/murmur_fnv.rs | 32 ++--- tests-integration/tests/xxhash.rs | 54 ++++----- typos.toml | 2 +- xtask/src/main.rs | 4 +- 38 files changed, 262 insertions(+), 278 deletions(-) rename {rache => hashcrew}/Cargo.toml (93%) rename {rache => hashcrew}/LICENSE (100%) rename {rache => hashcrew}/THIRD_PARTY_NOTICES.md (91%) rename {rache => hashcrew}/src/cityhash/mod.rs (99%) rename {rache => hashcrew}/src/fnv/mod.rs (98%) rename {rache => hashcrew}/src/lib.rs (96%) rename {rache => hashcrew}/src/murmur/mod.rs (98%) rename {rache => hashcrew}/src/xxhash/kernel/mod.rs (98%) rename {rache => hashcrew}/src/xxhash/kernel/neon.rs (100%) rename {rache => hashcrew}/src/xxhash/kernel/scalar.rs (100%) rename {rache => hashcrew}/src/xxhash/kernel/x86.rs (100%) rename {rache => hashcrew}/src/xxhash/mod.rs (93%) rename {rache => hashcrew}/src/xxhash/xxh3.rs (100%) rename {rache => hashcrew}/src/xxhash/xxh32.rs (100%) rename {rache => hashcrew}/src/xxhash/xxh64.rs (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index be693a7..d3beb5b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -120,7 +120,7 @@ jobs: - name: Run release-profile library tests under Miri # Release mode disables debug assertions that could otherwise mask an # unsafe precondition violation before Miri observes it. - run: cargo miri test --package rache --lib --no-default-features --release + run: cargo miri test --package hashcrew --lib --no-default-features --release target: name: Target (${{ matrix.name }}) @@ -166,7 +166,7 @@ jobs: key: ${{ matrix.target }} - name: Check target - run: cargo check --package rache --target "${{ matrix.target }}" --locked ${{ matrix.features }} + run: cargo check --package hashcrew --target "${{ matrix.target }}" --locked ${{ matrix.features }} package: name: Package @@ -189,7 +189,7 @@ jobs: - name: Validate package contents shell: bash run: | - package_files="$(cargo package --package rache --locked --list)" + package_files="$(cargo package --package hashcrew --locked --list)" for required in Cargo.lock Cargo.toml README.md LICENSE THIRD_PARTY_NOTICES.md src/lib.rs; do grep -Fxq "$required" <<< "$package_files" || { echo "missing required package file: $required" >&2 @@ -202,12 +202,12 @@ jobs: fi - name: Build package - run: cargo package --package rache --locked + run: cargo package --package hashcrew --locked - name: Test package shell: bash run: | - package_dir="$(find target/package -mindepth 1 -maxdepth 1 -type d -name 'rache-*' -print -quit)" + package_dir="$(find target/package -mindepth 1 -maxdepth 1 -type d -name 'hashcrew-*' -print -quit)" test -n "$package_dir" cargo test --manifest-path "$package_dir/Cargo.toml" --all-features --locked cargo test --manifest-path "$package_dir/Cargo.toml" --no-default-features --locked diff --git a/AGENTS.md b/AGENTS.md index 895ebb6..e10df53 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,7 +6,7 @@ Use `cargo x` as the source of truth for repository workflows. Read `cargo x --h ## Rust Style -Keep the publishable `rache` crate dependency-free, `no_std` compatible, and allocation-free. Isolate architecture-specific unsafe code in the XXH3 kernel layer and preserve a scalar implementation for every accelerated path. +Keep the publishable `hashcrew` crate dependency-free, `no_std` compatible, and allocation-free. Isolate architecture-specific unsafe code in the XXH3 kernel layer and preserve a scalar implementation for every accelerated path. ## Documentation diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index ad1a22a..bb1413b 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -1,6 +1,6 @@ # Architecture -`rache` separates its public API, portable algorithm cores, and optional hardware kernels: +`hashcrew` separates its public API, portable algorithm cores, and optional hardware kernels: ```text public API @@ -19,7 +19,7 @@ Configuration follows the source algorithm rather than a synthetic common interf CityHash remains a one-shot family. The reference algorithm incorporates the complete input length and reads its tail relative to the end of the message; bounded-memory state cannot derive the final digest from independently hashed chunks. `CityHash128` values store the reference high word in the most significant half and the low word in the least significant half. -The individual xxHash variants and hardware kernel are nested under `rache::xxhash`; no compatibility modules are re-exported at the crate root. +The individual xxHash variants and hardware kernel are nested under `hashcrew::xxhash`; no compatibility modules are re-exported at the crate root. ## Streaming state diff --git a/CHANGELOG.md b/CHANGELOG.md index 26434ad..5fb1832 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,29 +1,9 @@ # Changelog -## 0.2.0 - -- Remove duplicate crate-root, `raw`, and nested xxHash variant paths so each public API has one family-qualified home. Import functions, states, builders, constants, and kernels from `rache::{cityhash, fnv, murmur, xxhash}`; for example, replace `rache::Xxh3` or `rache::xxhash::xxh3::Xxh3` with `rache::xxhash::Xxh3_64`, `rache::raw::xxh3_64` with `rache::xxhash::xxh3_64`, and `rache::kernel` with `rache::xxhash::kernel`. -- Remove redundant alternate entry points so each operation has one public name. Use the module-level functions for complete input, replace `murmur3_128` and `Murmur3_128` with the architecture-qualified `murmur3_x64_128` and `Murmur3X64_128`, and replace the 128-bit states' `finish_128` methods with `digest`. -- Complete the original MurmurHash3 family with allocation-free one-shot and streaming APIs named after the reference variants: `murmur3_x86_32` and `Murmur3X86_32`, `murmur3_x86_128` and `Murmur3X86_128`, and `murmur3_x64_128` and `Murmur3X64_128`. -- Allow custom-secret XXH3 streaming states and builders to own caller-provided storage while preserving borrowed-secret construction and allocation-free hashing. Code that explicitly named `Xxh3_64SecretBuilder<'a>` must use the storage type `Xxh3_64SecretBuilder<&'a [u8]>`; constructor calls with inferred types continue to work. -- Implement `std::io::Write` for every streaming hash state when the default `std` feature is enabled, allowing file and network hashing through `std::io::copy`, `Write::write`, or `Write::write_all`. The inherent 128-bit state `write` aliases have been removed so they do not shadow the trait method; use `update` for direct incremental input. -- Cache the derived secret in seeded `Xxh3_64Builder` values so hash collections do not repeat 192-byte seed expansion for every key. -- Improve one-shot XXH3-64 and XXH3-128 throughput for 17-to-128-byte inputs by ensuring the specialized medium-length paths are inlined. - ## 0.1.0 -- Add compatible XXH32, XXH64, XXH3-64, and XXH3-128 implementations. -- Add CityHash32, CityHash64, CityHash128, seeded variants, and the public 128-to-64 reducer as allocation-free one-shot APIs. -- Add MurmurHash3 x86_32 and x64_128 one-shot and streaming implementations. -- Add FNV-1a 32 and FNV-1a 64 one-shot and streaming implementations. -- Add reference-compatible XXH3 custom-secret and seed+secret raw, streaming, and `BuildHasher` APIs without allocation. -- Add FNV-1a custom offset-basis raw, streaming, and `BuildHasher` APIs. -- Add allocation-free raw and streaming APIs plus standard hashing adapters. -- Add scalar, little-endian AArch64 NEON, x86-64 SSE2, and x86-64 AVX2 XXH3 kernels. -- Optimize NEON stripe accumulation and instruction scheduling, plus buffered streaming writes that do not yet require kernel work. -- Add `no_std` support, randomized cross-implementation and per-backend tests, specification vectors, and one-shot/streaming comparison benchmarks. -- Add exhaustive short-input and two-way streaming partition tests, optimized CI coverage for MSRV and representative targets, and a reproducible package release gate. -- Harden XXH streaming state across 64-bit length-counter wraparound and avoid secret-size arithmetic overflow in XXH3 long-input one-shot hashing. -- Clarify that cross-platform digest stability applies to identical raw byte streams rather than Rust's native typed `Hash` encoding. -- Adopt the Apache License 2.0 and enforce source headers and Conventional Commit pull-request titles in CI. -- Group implementations by algorithm family while preserving crate-root xxHash module paths. +- Provide dependency-free, allocation-free, and `no_std`-compatible implementations of CityHash32, CityHash64, CityHash128, XXH32, XXH64, XXH3-64, XXH3-128, all three reference MurmurHash3 variants, and FNV-1a 32 and 64. +- Group each algorithm family under `hashcrew::{cityhash, xxhash, murmur, fnv}` with one-shot functions for complete byte slices, bounded-memory streaming states where the algorithm permits them, and matching `Hasher` and `BuildHasher` adapters for 32-bit and 64-bit states. +- Support seeded and custom-secret XXH3, seeded CityHash, seeded MurmurHash3, custom FNV offset bases, and caller-owned or borrowed XXH3 secret storage without allocation. +- Accelerate long-input XXH3 with scalar, little-endian AArch64 NEON, x86-64 SSE2, and x86-64 AVX2 kernels selected from target features and cached runtime detection where available. +- Integrate streaming states with `std::io::Write` under the default `std` feature while keeping direct `update` and `digest` APIs available in every build. diff --git a/Cargo.lock b/Cargo.lock index 9571036..1b09882 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -60,8 +60,8 @@ dependencies = [ "cityhasher", "divan", "fnv", + "hashcrew", "murmur3", - "rache", "twox-hash", "xxhash-rust", ] @@ -182,7 +182,7 @@ dependencies = [ name = "examples" version = "0.0.0" dependencies = [ - "rache", + "hashcrew", ] [[package]] @@ -191,6 +191,10 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "hashcrew" +version = "0.1.0" + [[package]] name = "heck" version = "0.5.0" @@ -245,10 +249,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rache" -version = "0.2.0" - [[package]] name = "regex-lite" version = "0.1.9" @@ -313,8 +313,8 @@ dependencies = [ "cityhash-rs", "cityhasher", "fnv", + "hashcrew", "murmur3", - "rache", "twox-hash", "xxhash-rust", ] diff --git a/Cargo.toml b/Cargo.toml index 6df2d8f..92fbd06 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ # limitations under the License. [workspace] -members = ["benchmarks", "examples", "rache", "tests-integration", "xtask"] +members = ["benchmarks", "examples", "hashcrew", "tests-integration", "xtask"] resolver = "3" [workspace.package] @@ -24,7 +24,7 @@ rust-version = "1.85" [workspace.dependencies] # Workspace dependencies -rache = { path = "rache" } +hashcrew = { path = "hashcrew" } # Crates.io dependencies cityhash-rs = { version = "1.0.1" } diff --git a/HISTORY.md b/HISTORY.md index 548554f..a4f0186 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,11 +1,11 @@ # Implementation history -The first `rache` release establishes the xxHash family as the library's initial compatibility surface. XXH32 and XXH64 use direct portable cores. XXH3 keeps short-input routing separate from a long-input kernel so hardware backends can change without changing public APIs or digest output. +Hashcrew starts with four algorithm families behind a consistent family-qualified API. One-shot functions handle complete byte slices, bounded-memory state types handle incremental input where the algorithm permits it, and explicit adapters integrate 32-bit and 64-bit states with Rust's standard hashing traits. -The naming and API split draw on lessons from `twox-hash`: one-shot functions for complete byte slices, stateful types for streaming input, and explicit adapters for Rust's standard hashing traits. Unlike implementations whose streaming XXH3 state allocates its secret, the initial `rache` state owns fixed buffers so the same API works under `no_std`. +XXH32 and XXH64 use direct portable cores. XXH3 keeps short-input routing separate from a long-input kernel so scalar and hardware-accelerated backends can change without changing public APIs or digest output. Its streaming state owns fixed buffers and accepts borrowed or caller-owned secret storage, preserving allocation-free `no_std` operation. -The repository separates the publishable crate from examples, benchmarks, and cross-implementation tests, following the workspace organization used by Apache Asyncband. Within the library, source files are grouped by algorithm family; the XXH3 hardware kernels live beside the xxHash implementations while crate-root re-exports keep the public API compact. +MurmurHash3 implements the reference `x86_32`, `x86_128`, and `x64_128` variants. Their architecture labels identify distinct algorithms rather than target restrictions. FNV-1a 32 and 64 use a portable byte-at-a-time core shared by one-shot functions, streaming states, and standard hash adapters. -MurmurHash3 x86_32 and x64_128 extend the same raw/streaming split with small fixed-size tail buffers. FNV-1a 32 and 64 use a single portable byte-at-a-time core shared by their one-shot functions, streaming states, and standard hash adapters. Reference crates remain isolated in the integration-test and benchmark workspace members. +CityHash32, CityHash64, and CityHash128 remain one-shot-oriented. Their construction depends on the complete input length and tail, so a streaming facade would need to retain the entire message instead of providing bounded-memory incremental hashing. -CityHash32, CityHash64, and CityHash128 add a second one-shot-oriented family, including the reference seeded forms and 128-to-64 reducer. CityHash does not expose incremental state: its length- and tail-dependent construction cannot be resumed with bounded memory, so such an API would have to buffer the entire message. The implementation stays portable, safe, allocation-free, and compatible with `no_std`. +The repository keeps the dependency-free publishable crate separate from examples, benchmarks, and cross-implementation tests. Reference implementations are development-only dependencies and never enter the published package. diff --git a/README.md b/README.md index aa3c1b5..1a5f1fa 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# rache +# hashcrew [![Crates.io][crates-badge]][crates-url] [![Documentation][docs-badge]][docs-url] @@ -6,19 +6,19 @@ [![Apache 2.0 licensed][license-badge]][license-url] [![Build Status][actions-badge]][actions-url] -[crates-badge]: https://img.shields.io/crates/v/rache.svg -[crates-url]: https://crates.io/crates/rache -[docs-badge]: https://docs.rs/rache/badge.svg -[docs-url]: https://docs.rs/rache +[crates-badge]: https://img.shields.io/crates/v/hashcrew.svg +[crates-url]: https://crates.io/crates/hashcrew +[docs-badge]: https://docs.rs/hashcrew/badge.svg +[docs-url]: https://docs.rs/hashcrew [msrv-badge]: https://img.shields.io/badge/MSRV-1.85-green?logo=rust -[license-badge]: https://img.shields.io/crates/l/rache +[license-badge]: https://img.shields.io/crates/l/hashcrew [license-url]: LICENSE [actions-badge]: https://github.com/fast/rache/actions/workflows/ci.yml/badge.svg [actions-url]: https://github.com/fast/rache/actions/workflows/ci.yml ## Overview -Rache is a zero-dependency Rust library for fast, deterministic, non-cryptographic hashing. It provides allocation-free one-shot APIs, incremental state where the algorithm supports it, stable cross-platform digests for identical raw byte streams, and hardware-accelerated XXH3 kernels. +Hashcrew is a zero-dependency Rust library for fast, deterministic, non-cryptographic hashing. It provides allocation-free one-shot APIs, incremental state where the algorithm supports it, stable cross-platform digests for identical raw byte streams, and hardware-accelerated XXH3 kernels. Every implementation supports `no_std`. XXH3 inputs longer than 240 bytes use a dedicated kernel layer with scalar, little-endian AArch64 NEON, x86-64 SSE2, and x86-64 AVX2 backends; the other algorithms use compact portable Rust cores. @@ -29,22 +29,22 @@ Every implementation supports `no_std`. XXH3 inputs longer than 240 bytes use a ## Getting started ```shell -cargo add rache +cargo add hashcrew ``` Disable the default `std` feature for bare-metal and other `no_std` targets: ```toml [dependencies] -rache = { version = "0.2", default-features = false } +hashcrew = { version = "0.1", default-features = false } ``` Import the algorithm family when the complete input is already in memory: ```rust -use rache::{cityhash, fnv, murmur, xxhash}; +use hashcrew::{cityhash, fnv, murmur, xxhash}; -let data = b"rache"; +let data = b"hashcrew"; let city = cityhash::cityhash64(data); let xxh3 = xxhash::xxh3_64(data); let murmur = murmur::murmur3_x64_128(data, 42); @@ -59,35 +59,35 @@ assert_ne!(fnv, 0); Use a state type when data arrives incrementally: ```rust -use rache::murmur::Murmur3X64_128; -use rache::murmur::murmur3_x64_128; +use hashcrew::murmur::Murmur3X64_128; +use hashcrew::murmur::murmur3_x64_128; let mut hash = Murmur3X64_128::with_seed(42); -hash.update(b"ra"); -hash.update(b"che"); +hash.update(b"hash"); +hash.update(b"crew"); -assert_eq!(hash.digest(), murmur3_x64_128(b"rache", 42)); +assert_eq!(hash.digest(), murmur3_x64_128(b"hashcrew", 42)); ``` Custom XXH3 secrets can be borrowed or moved into the streaming state. Owning the storage is useful when a factory or component needs to return a self-contained hasher: ```rust -use rache::xxhash::Xxh3_64; -use rache::xxhash::xxh3_64_with_secret; +use hashcrew::xxhash::Xxh3_64; +use hashcrew::xxhash::xxh3_64_with_secret; let secret = [0xa5; 192]; -let expected = xxh3_64_with_secret(b"rache", &secret).unwrap(); +let expected = xxh3_64_with_secret(b"hashcrew", &secret).unwrap(); let mut hash = Xxh3_64::with_secret(secret).unwrap(); -hash.update(b"rache"); +hash.update(b"hashcrew"); assert_eq!(hash.digest(), expected); ``` -All public APIs are grouped under the [`cityhash`](https://docs.rs/rache/*/rache/cityhash/), [`xxhash`](https://docs.rs/rache/*/rache/xxhash/), [`murmur`](https://docs.rs/rache/*/rache/murmur/), and [`fnv`](https://docs.rs/rache/*/rache/fnv/) modules. Each module keeps its one-shot functions, streaming states, builders, and configuration together. +All public APIs are grouped under the [`cityhash`](https://docs.rs/hashcrew/*/hashcrew/cityhash/), [`xxhash`](https://docs.rs/hashcrew/*/hashcrew/xxhash/), [`murmur`](https://docs.rs/hashcrew/*/hashcrew/murmur/), and [`fnv`](https://docs.rs/hashcrew/*/hashcrew/fnv/) modules. Each module keeps its one-shot functions, streaming states, builders, and configuration together. ## API model -Rache exposes the same algorithm at different integration boundaries. Pick the narrowest interface that matches where the bytes come from: +Hashcrew exposes the same algorithm at different integration boundaries. Pick the narrowest interface that matches where the bytes come from: | Input or caller | Interface | What it does | |------------------------------------------------------|---------------------------------------------------------------------------|----------------------------------------------------------------------------------------------| @@ -117,7 +117,7 @@ The table names the canonical module-level function for complete input. A traili | FNV-1a 32 | `fnv1a_32*` | `Fnv1a32` | `u32` | `Fnv1a32` / `Fnv1a32Builder` | | FNV-1a 64 | `fnv1a_64*` | `Fnv1a64` | `u64` | `Fnv1a64` / `Fnv1a64Builder` | -Rache implements all three variants from the original MurmurHash3 family under their reference-qualified `x86_32`, `x86_128`, and `x64_128` names. These architecture labels distinguish algorithms and do not restrict which target can run them. `cityhash128_to_64` reduces an existing 128-bit CityHash value; it does not hash a new byte slice. +Hashcrew implements all three variants from the original MurmurHash3 family under their reference-qualified `x86_32`, `x86_128`, and `x64_128` names. These architecture labels distinguish algorithms and do not restrict which target can run them. `cityhash128_to_64` reduces an existing 128-bit CityHash value; it does not hash a new byte slice. ## Choosing an algorithm @@ -131,14 +131,14 @@ The adapter treats every written byte as hash input; it accepts the complete buf ```rust use std::io::{self, Cursor}; -use rache::xxhash::Xxh3_64; -use rache::xxhash::xxh3_64; +use hashcrew::xxhash::Xxh3_64; +use hashcrew::xxhash::xxh3_64; -let mut source = Cursor::new(b"rache"); +let mut source = Cursor::new(b"hashcrew"); let mut hash = Xxh3_64::new(); io::copy(&mut source, &mut hash).unwrap(); -assert_eq!(hash.digest(), xxh3_64(b"rache")); +assert_eq!(hash.digest(), xxh3_64(b"hashcrew")); ``` This adapter is only needed for `std` interoperability. The direct `update` API is available in both `std` and `no_std` builds. @@ -149,12 +149,12 @@ The 32-bit and 64-bit streaming states implement `core::hash::Hasher`, with matc ```rust use std::collections::HashMap; -use rache::xxhash::Xxh3_64Builder; +use hashcrew::xxhash::Xxh3_64Builder; let mut counts = HashMap::with_hasher(Xxh3_64Builder::with_seed(7)); -counts.insert("rache", 1); +counts.insert("hashcrew", 1); -assert_eq!(counts["rache"], 1); +assert_eq!(counts["hashcrew"], 1); ``` CityHash is intentionally one-shot. Its digest depends on the complete input length and tail, so a streaming facade would have to retain the entire message and would not provide bounded-memory incremental hashing. @@ -165,7 +165,7 @@ XXH3 accepts custom secrets of at least 136 bytes and returns an error for short Raw and streaming digests are stable across platforms for identical byte streams. Rust's `Hash` and `BuildHasher` adapters use native typed encodings, including platform endianness and `usize` width, and are not a portable serialization format. -Target-guaranteed CPU features are selected at compile time. Other `std` builds cache runtime feature detection; `no_std` builds use compile-time features only and otherwise fall back to the scalar kernel. [`rache::xxhash::kernel::selected_backend()`](https://docs.rs/rache/*/rache/xxhash/kernel/fn.selected_backend.html) reports the selected XXH3 backend. +Target-guaranteed CPU features are selected at compile time. Other `std` builds cache runtime feature detection; `no_std` builds use compile-time features only and otherwise fall back to the scalar kernel. [`hashcrew::xxhash::kernel::selected_backend()`](https://docs.rs/hashcrew/*/hashcrew/xxhash/kernel/fn.selected_backend.html) reports the selected XXH3 backend. ## Examples and benchmarks @@ -184,8 +184,8 @@ Integration tests compare CityHash, xxHash, and MurmurHash3 with independent imp ## Minimum Supported Rust Version (MSRV) -Rache's minimum supported rustc version is 1.85.0. The MSRV may be increased in a minor release. +Hashcrew's minimum supported rustc version is 1.85.0. The MSRV may be increased in a minor release. ## License and acknowledgements -This project is licensed under [Apache License, Version 2.0](LICENSE). See [`THIRD_PARTY_NOTICES.md`](THIRD_PARTY_NOTICES.md) for the specifications, implementations, and development-only comparison dependencies that informed Rache. +This project is licensed under [Apache License, Version 2.0](LICENSE). See [`THIRD_PARTY_NOTICES.md`](THIRD_PARTY_NOTICES.md) for the specifications, implementations, and development-only comparison dependencies that informed Hashcrew. diff --git a/RELEASE.md b/RELEASE.md index 03ac36f..52e285a 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,6 +1,6 @@ -# Releasing `rache` +# Releasing `hashcrew` -Only the `rache` workspace package is published. Benchmarks, examples, and integration-test packages must remain development-only. +Only the `hashcrew` workspace package is published. Benchmarks, examples, and integration-test packages must remain development-only. ## Preflight @@ -17,19 +17,19 @@ cargo x check cargo x test RUSTUP_TOOLCHAIN=1.85.0 cargo x test cargo x bench --no-run -release_version=0.2.0 -cargo release "$release_version" --package rache +release_version=0.1.0 +cargo release "$release_version" --package hashcrew ``` -The `cargo release` command is a dry run unless `--execute` is present. Inspect `cargo +stable package -p rache --locked --list` before publishing. The archive must contain the license, README, third-party notices, manifest, lockfile, and library sources, without workspace benchmarks or integration-test fixtures. +The `cargo release` command is a dry run unless `--execute` is present. Inspect `cargo +stable package -p hashcrew --locked --list` before publishing. The archive must contain the license, README, third-party notices, manifest, lockfile, and library sources, without workspace benchmarks or integration-test fixtures. ## Publish Confirm the crate name, version, repository URL, and crates.io account before the irreversible step: ```shell -release_version=0.2.0 -cargo release "$release_version" --package rache --execute +release_version=0.1.0 +cargo release "$release_version" --package hashcrew --execute ``` This publishes the crate, creates the configured signed `v` tag, and pushes the branch and tag. Do not create a second tag manually. After crates.io confirms the release, create the matching GitHub Release and verify the crate page and docs.rs build. diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md index 838c8c3..0d175c4 100644 --- a/THIRD_PARTY_NOTICES.md +++ b/THIRD_PARTY_NOTICES.md @@ -25,16 +25,16 @@ The workspace organization was informed by Apache Asyncband, distributed under t - -`xxhash-rust` is a development-only conformance and benchmark dependency. It is not linked into the published `rache` crate: +`xxhash-rust` is a development-only conformance and benchmark dependency. It is not linked into the published `hashcrew` crate: - -`murmur3` and `fnv` are development-only conformance and benchmark dependencies. They are not linked into the published `rache` crate: +`murmur3` and `fnv` are development-only conformance and benchmark dependencies. They are not linked into the published `hashcrew` crate: - - -`cityhasher` and `cityhash-rs` are development-only conformance and benchmark dependencies. They are not linked into the published `rache` crate: +`cityhasher` and `cityhash-rs` are development-only conformance and benchmark dependencies. They are not linked into the published `hashcrew` crate: - - diff --git a/benchmarks/Cargo.toml b/benchmarks/Cargo.toml index 54da9ce..46f6bdb 100644 --- a/benchmarks/Cargo.toml +++ b/benchmarks/Cargo.toml @@ -24,8 +24,8 @@ cityhash-rs = { workspace = true } cityhasher = { workspace = true } divan = { workspace = true } fnv = { workspace = true } +hashcrew = { workspace = true } murmur3 = { workspace = true } -rache = { workspace = true } twox-hash = { workspace = true } xxhash-rust = { workspace = true } diff --git a/benchmarks/README.md b/benchmarks/README.md index a1aaa7c..a66cf02 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -1,6 +1,6 @@ # Benchmarks -The benchmark package uses Divan to measure public `rache` APIs alongside `cityhasher`, `cityhash-rs`, `twox-hash`, `xxhash-rust`, `murmur3`, and `fnv`. These comparison crates are development-only dependencies and are not linked into the published library. +The benchmark package uses Divan to measure public `hashcrew` APIs alongside `cityhasher`, `cityhash-rs`, `twox-hash`, `xxhash-rust`, `murmur3`, and `fnv`. These comparison crates are development-only dependencies and are not linked into the published library. | Target | Coverage | |--------------|------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -34,5 +34,5 @@ cargo bench -p benchmarks --bench throughput -- cityhash cargo bench -p benchmarks --bench throughput -- murmur3 cargo bench -p benchmarks --bench throughput -- fnv1a cargo bench -p benchmarks --bench streaming -- xxh64 -cargo bench -p benchmarks --bench streaming -- rache +cargo bench -p benchmarks --bench streaming -- hashcrew ``` diff --git a/benchmarks/benches/streaming.rs b/benchmarks/benches/streaming.rs index 126c0c3..4e90474 100644 --- a/benchmarks/benches/streaming.rs +++ b/benchmarks/benches/streaming.rs @@ -36,10 +36,10 @@ mod xxh32 { use super::*; #[divan::bench(args = CASES)] - fn rache(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { + fn hashcrew(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { let bytes = input(len); bencher.counter(BytesCount::new(len)).bench(|| { - let mut hasher = rache::xxhash::Xxh32::new(); + let mut hasher = hashcrew::xxhash::Xxh32::new(); for chunk in black_box(&bytes).chunks(chunk_size) { hasher.update(chunk); } @@ -76,10 +76,10 @@ mod xxh64 { use super::*; #[divan::bench(args = CASES)] - fn rache(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { + fn hashcrew(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { let bytes = input(len); bencher.counter(BytesCount::new(len)).bench(|| { - let mut hasher = rache::xxhash::Xxh64::new(); + let mut hasher = hashcrew::xxhash::Xxh64::new(); for chunk in black_box(&bytes).chunks(chunk_size) { hasher.update(chunk); } @@ -116,10 +116,10 @@ mod xxh3_64 { use super::*; #[divan::bench(args = CASES)] - fn rache(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { + fn hashcrew(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { let bytes = input(len); bencher.counter(BytesCount::new(len)).bench(|| { - let mut hasher = rache::xxhash::Xxh3_64::new(); + let mut hasher = hashcrew::xxhash::Xxh3_64::new(); for chunk in black_box(&bytes).chunks(chunk_size) { hasher.update(chunk); } @@ -128,11 +128,11 @@ mod xxh3_64 { } #[divan::bench(args = CASES)] - fn rache_secret(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { + fn hashcrew_secret(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { let bytes = input(len); - let secret = input(rache::xxhash::DEFAULT_SECRET_SIZE); + let secret = input(hashcrew::xxhash::DEFAULT_SECRET_SIZE); bencher.counter(BytesCount::new(len)).bench(|| { - let mut hasher = rache::xxhash::Xxh3_64::with_secret(black_box(&secret)).unwrap(); + let mut hasher = hashcrew::xxhash::Xxh3_64::with_secret(black_box(&secret)).unwrap(); for chunk in black_box(&bytes).chunks(chunk_size) { hasher.update(chunk); } @@ -141,11 +141,11 @@ mod xxh3_64 { } #[divan::bench(args = CASES)] - fn rache_seed_and_secret(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { + fn hashcrew_seed_and_secret(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { let bytes = input(len); - let secret = input(rache::xxhash::DEFAULT_SECRET_SIZE); + let secret = input(hashcrew::xxhash::DEFAULT_SECRET_SIZE); bencher.counter(BytesCount::new(len)).bench(|| { - let mut hasher = rache::xxhash::Xxh3_64::with_seed_and_secret( + let mut hasher = hashcrew::xxhash::Xxh3_64::with_seed_and_secret( 0x0123_4567_89ab_cdef, black_box(&secret), ) @@ -186,10 +186,10 @@ mod xxh3_128 { use super::*; #[divan::bench(args = CASES)] - fn rache(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { + fn hashcrew(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { let bytes = input(len); bencher.counter(BytesCount::new(len)).bench(|| { - let mut hasher = rache::xxhash::Xxh3_128::new(); + let mut hasher = hashcrew::xxhash::Xxh3_128::new(); for chunk in black_box(&bytes).chunks(chunk_size) { hasher.update(chunk); } @@ -198,11 +198,11 @@ mod xxh3_128 { } #[divan::bench(args = CASES)] - fn rache_secret(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { + fn hashcrew_secret(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { let bytes = input(len); - let secret = input(rache::xxhash::DEFAULT_SECRET_SIZE); + let secret = input(hashcrew::xxhash::DEFAULT_SECRET_SIZE); bencher.counter(BytesCount::new(len)).bench(|| { - let mut hasher = rache::xxhash::Xxh3_128::with_secret(black_box(&secret)).unwrap(); + let mut hasher = hashcrew::xxhash::Xxh3_128::with_secret(black_box(&secret)).unwrap(); for chunk in black_box(&bytes).chunks(chunk_size) { hasher.update(chunk); } @@ -211,11 +211,11 @@ mod xxh3_128 { } #[divan::bench(args = CASES)] - fn rache_seed_and_secret(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { + fn hashcrew_seed_and_secret(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { let bytes = input(len); - let secret = input(rache::xxhash::DEFAULT_SECRET_SIZE); + let secret = input(hashcrew::xxhash::DEFAULT_SECRET_SIZE); bencher.counter(BytesCount::new(len)).bench(|| { - let mut hasher = rache::xxhash::Xxh3_128::with_seed_and_secret( + let mut hasher = hashcrew::xxhash::Xxh3_128::with_seed_and_secret( 0x0123_4567_89ab_cdef, black_box(&secret), ) @@ -256,10 +256,10 @@ mod murmur3_x86_32 { use super::*; #[divan::bench(args = CASES)] - fn rache(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { + fn hashcrew(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { let bytes = input(len); bencher.counter(BytesCount::new(len)).bench(|| { - let mut hasher = rache::murmur::Murmur3X86_32::new(); + let mut hasher = hashcrew::murmur::Murmur3X86_32::new(); for chunk in black_box(&bytes).chunks(chunk_size) { hasher.update(chunk); } @@ -272,10 +272,10 @@ mod murmur3_x86_128 { use super::*; #[divan::bench(args = CASES)] - fn rache(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { + fn hashcrew(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { let bytes = input(len); bencher.counter(BytesCount::new(len)).bench(|| { - let mut hasher = rache::murmur::Murmur3X86_128::new(); + let mut hasher = hashcrew::murmur::Murmur3X86_128::new(); for chunk in black_box(&bytes).chunks(chunk_size) { hasher.update(chunk); } @@ -288,10 +288,10 @@ mod murmur3_x64_128 { use super::*; #[divan::bench(args = CASES)] - fn rache(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { + fn hashcrew(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { let bytes = input(len); bencher.counter(BytesCount::new(len)).bench(|| { - let mut hasher = rache::murmur::Murmur3X64_128::new(); + let mut hasher = hashcrew::murmur::Murmur3X64_128::new(); for chunk in black_box(&bytes).chunks(chunk_size) { hasher.update(chunk); } @@ -304,10 +304,10 @@ mod fnv1a_32 { use super::*; #[divan::bench(args = CASES)] - fn rache(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { + fn hashcrew(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { let bytes = input(len); bencher.counter(BytesCount::new(len)).bench(|| { - let mut hasher = rache::fnv::Fnv1a32::new(); + let mut hasher = hashcrew::fnv::Fnv1a32::new(); for chunk in black_box(&bytes).chunks(chunk_size) { hasher.update(chunk); } @@ -320,10 +320,10 @@ mod fnv1a_64 { use super::*; #[divan::bench(args = CASES)] - fn rache(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { + fn hashcrew(bencher: Bencher<'_, '_>, (len, chunk_size): (usize, usize)) { let bytes = input(len); bencher.counter(BytesCount::new(len)).bench(|| { - let mut hasher = rache::fnv::Fnv1a64::new(); + let mut hasher = hashcrew::fnv::Fnv1a64::new(); for chunk in black_box(&bytes).chunks(chunk_size) { hasher.update(chunk); } diff --git a/benchmarks/benches/throughput.rs b/benchmarks/benches/throughput.rs index 5e8086a..4ee710a 100644 --- a/benchmarks/benches/throughput.rs +++ b/benchmarks/benches/throughput.rs @@ -52,11 +52,11 @@ mod cityhash32 { use super::*; #[divan::bench(args = SIZES)] - fn rache(bencher: Bencher<'_, '_>, len: usize) { + fn hashcrew(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); bencher .counter(BytesCount::new(len)) - .bench(|| rache::cityhash::cityhash32(black_box(&bytes))); + .bench(|| hashcrew::cityhash::cityhash32(black_box(&bytes))); } #[divan::bench(args = SIZES)] @@ -72,11 +72,11 @@ mod cityhash64 { use super::*; #[divan::bench(args = SIZES)] - fn rache(bencher: Bencher<'_, '_>, len: usize) { + fn hashcrew(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); bencher .counter(BytesCount::new(len)) - .bench(|| rache::cityhash::cityhash64(black_box(&bytes))); + .bench(|| hashcrew::cityhash::cityhash64(black_box(&bytes))); } #[divan::bench(args = SIZES)] @@ -92,19 +92,19 @@ mod cityhash64_seeded { use super::*; #[divan::bench(args = SIZES)] - fn rache_one_seed(bencher: Bencher<'_, '_>, len: usize) { + fn hashcrew_one_seed(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); bencher .counter(BytesCount::new(len)) - .bench(|| rache::cityhash::cityhash64_with_seed(black_box(&bytes), SEED)); + .bench(|| hashcrew::cityhash::cityhash64_with_seed(black_box(&bytes), SEED)); } #[divan::bench(args = SIZES)] - fn rache_two_seeds(bencher: Bencher<'_, '_>, len: usize) { + fn hashcrew_two_seeds(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); bencher .counter(BytesCount::new(len)) - .bench(|| rache::cityhash::cityhash64_with_seeds(black_box(&bytes), SEED, !SEED)); + .bench(|| hashcrew::cityhash::cityhash64_with_seeds(black_box(&bytes), SEED, !SEED)); } #[divan::bench(args = SIZES)] @@ -120,11 +120,11 @@ mod cityhash128 { use super::*; #[divan::bench(args = SIZES)] - fn rache(bencher: Bencher<'_, '_>, len: usize) { + fn hashcrew(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); bencher .counter(BytesCount::new(len)) - .bench(|| rache::cityhash::cityhash128(black_box(&bytes))); + .bench(|| hashcrew::cityhash::cityhash128(black_box(&bytes))); } #[divan::bench(args = SIZES)] @@ -140,12 +140,12 @@ mod cityhash128_seeded { use super::*; #[divan::bench(args = SIZES)] - fn rache(bencher: Bencher<'_, '_>, len: usize) { + fn hashcrew(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); let seed = (u128::from(!SEED) << 64) | u128::from(SEED); bencher .counter(BytesCount::new(len)) - .bench(|| rache::cityhash::cityhash128_with_seed(black_box(&bytes), seed)); + .bench(|| hashcrew::cityhash::cityhash128_with_seed(black_box(&bytes), seed)); } } @@ -153,11 +153,11 @@ mod xxh32 { use super::*; #[divan::bench(args = SIZES)] - fn rache(bencher: Bencher<'_, '_>, len: usize) { + fn hashcrew(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); bencher .counter(BytesCount::new(len)) - .bench(|| rache::xxhash::xxh32(black_box(&bytes), 0)); + .bench(|| hashcrew::xxhash::xxh32(black_box(&bytes), 0)); } #[divan::bench(args = SIZES)] @@ -181,11 +181,11 @@ mod xxh64 { use super::*; #[divan::bench(args = SIZES)] - fn rache(bencher: Bencher<'_, '_>, len: usize) { + fn hashcrew(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); bencher .counter(BytesCount::new(len)) - .bench(|| rache::xxhash::xxh64(black_box(&bytes), 0)); + .bench(|| hashcrew::xxhash::xxh64(black_box(&bytes), 0)); } #[divan::bench(args = SIZES)] @@ -209,11 +209,11 @@ mod xxh3_64 { use super::*; #[divan::bench(args = SIZES)] - fn rache(bencher: Bencher<'_, '_>, len: usize) { + fn hashcrew(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); bencher .counter(BytesCount::new(len)) - .bench(|| rache::xxhash::xxh3_64(black_box(&bytes))); + .bench(|| hashcrew::xxhash::xxh3_64(black_box(&bytes))); } #[divan::bench(args = SIZES)] @@ -237,11 +237,11 @@ mod xxh3_128 { use super::*; #[divan::bench(args = SIZES)] - fn rache(bencher: Bencher<'_, '_>, len: usize) { + fn hashcrew(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); bencher .counter(BytesCount::new(len)) - .bench(|| rache::xxhash::xxh3_128(black_box(&bytes))); + .bench(|| hashcrew::xxhash::xxh3_128(black_box(&bytes))); } #[divan::bench(args = SIZES)] @@ -265,11 +265,11 @@ mod xxh3_64_seeded { use super::*; #[divan::bench(args = SIZES)] - fn rache(bencher: Bencher<'_, '_>, len: usize) { + fn hashcrew(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); bencher .counter(BytesCount::new(len)) - .bench(|| rache::xxhash::xxh3_64_with_seed(black_box(&bytes), SEED)); + .bench(|| hashcrew::xxhash::xxh3_64_with_seed(black_box(&bytes), SEED)); } #[divan::bench(args = SIZES)] @@ -293,11 +293,11 @@ mod xxh3_128_seeded { use super::*; #[divan::bench(args = SIZES)] - fn rache(bencher: Bencher<'_, '_>, len: usize) { + fn hashcrew(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); bencher .counter(BytesCount::new(len)) - .bench(|| rache::xxhash::xxh3_128_with_seed(black_box(&bytes), SEED)); + .bench(|| hashcrew::xxhash::xxh3_128_with_seed(black_box(&bytes), SEED)); } #[divan::bench(args = SIZES)] @@ -321,18 +321,18 @@ mod xxh3_64_secret { use super::*; #[divan::bench(args = SIZES)] - fn rache(bencher: Bencher<'_, '_>, len: usize) { + fn hashcrew(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); - let secret = input(rache::xxhash::DEFAULT_SECRET_SIZE); + let secret = input(hashcrew::xxhash::DEFAULT_SECRET_SIZE); bencher.counter(BytesCount::new(len)).bench(|| { - rache::xxhash::xxh3_64_with_secret(black_box(&bytes), black_box(&secret)).unwrap() + hashcrew::xxhash::xxh3_64_with_secret(black_box(&bytes), black_box(&secret)).unwrap() }); } #[divan::bench(args = SIZES)] fn xxhash_rust(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); - let secret = input(rache::xxhash::DEFAULT_SECRET_SIZE); + let secret = input(hashcrew::xxhash::DEFAULT_SECRET_SIZE); bencher.counter(BytesCount::new(len)).bench(|| { xxhash_rust::xxh3::xxh3_64_with_secret(black_box(&bytes), black_box(&secret)) }); @@ -341,7 +341,7 @@ mod xxh3_64_secret { #[divan::bench(args = SIZES)] fn twox_hash(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); - let secret = input(rache::xxhash::DEFAULT_SECRET_SIZE); + let secret = input(hashcrew::xxhash::DEFAULT_SECRET_SIZE); bencher.counter(BytesCount::new(len)).bench(|| { twox_hash::xxhash3_64::Hasher::oneshot_with_secret( black_box(&secret), @@ -356,18 +356,18 @@ mod xxh3_128_secret { use super::*; #[divan::bench(args = SIZES)] - fn rache(bencher: Bencher<'_, '_>, len: usize) { + fn hashcrew(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); - let secret = input(rache::xxhash::DEFAULT_SECRET_SIZE); + let secret = input(hashcrew::xxhash::DEFAULT_SECRET_SIZE); bencher.counter(BytesCount::new(len)).bench(|| { - rache::xxhash::xxh3_128_with_secret(black_box(&bytes), black_box(&secret)).unwrap() + hashcrew::xxhash::xxh3_128_with_secret(black_box(&bytes), black_box(&secret)).unwrap() }); } #[divan::bench(args = SIZES)] fn xxhash_rust(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); - let secret = input(rache::xxhash::DEFAULT_SECRET_SIZE); + let secret = input(hashcrew::xxhash::DEFAULT_SECRET_SIZE); bencher.counter(BytesCount::new(len)).bench(|| { xxhash_rust::xxh3::xxh3_128_with_secret(black_box(&bytes), black_box(&secret)) }); @@ -376,7 +376,7 @@ mod xxh3_128_secret { #[divan::bench(args = SIZES)] fn twox_hash(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); - let secret = input(rache::xxhash::DEFAULT_SECRET_SIZE); + let secret = input(hashcrew::xxhash::DEFAULT_SECRET_SIZE); bencher.counter(BytesCount::new(len)).bench(|| { twox_hash::xxhash3_128::Hasher::oneshot_with_secret( black_box(&secret), @@ -391,19 +391,23 @@ mod xxh3_64_seed_and_secret { use super::*; #[divan::bench(args = SIZES)] - fn rache(bencher: Bencher<'_, '_>, len: usize) { + fn hashcrew(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); - let secret = input(rache::xxhash::DEFAULT_SECRET_SIZE); + let secret = input(hashcrew::xxhash::DEFAULT_SECRET_SIZE); bencher.counter(BytesCount::new(len)).bench(|| { - rache::xxhash::xxh3_64_with_seed_and_secret(black_box(&bytes), SEED, black_box(&secret)) - .unwrap() + hashcrew::xxhash::xxh3_64_with_seed_and_secret( + black_box(&bytes), + SEED, + black_box(&secret), + ) + .unwrap() }); } #[divan::bench(args = SIZES)] fn twox_hash(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); - let secret = input(rache::xxhash::DEFAULT_SECRET_SIZE); + let secret = input(hashcrew::xxhash::DEFAULT_SECRET_SIZE); bencher.counter(BytesCount::new(len)).bench(|| { twox_hash::xxhash3_64::Hasher::oneshot_with_seed_and_secret( SEED, @@ -419,11 +423,11 @@ mod xxh3_128_seed_and_secret { use super::*; #[divan::bench(args = SIZES)] - fn rache(bencher: Bencher<'_, '_>, len: usize) { + fn hashcrew(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); - let secret = input(rache::xxhash::DEFAULT_SECRET_SIZE); + let secret = input(hashcrew::xxhash::DEFAULT_SECRET_SIZE); bencher.counter(BytesCount::new(len)).bench(|| { - rache::xxhash::xxh3_128_with_seed_and_secret( + hashcrew::xxhash::xxh3_128_with_seed_and_secret( black_box(&bytes), SEED, black_box(&secret), @@ -435,7 +439,7 @@ mod xxh3_128_seed_and_secret { #[divan::bench(args = SIZES)] fn twox_hash(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); - let secret = input(rache::xxhash::DEFAULT_SECRET_SIZE); + let secret = input(hashcrew::xxhash::DEFAULT_SECRET_SIZE); bencher.counter(BytesCount::new(len)).bench(|| { twox_hash::xxhash3_128::Hasher::oneshot_with_seed_and_secret( SEED, @@ -451,11 +455,11 @@ mod murmur3_x86_32 { use super::*; #[divan::bench(args = SIZES)] - fn rache(bencher: Bencher<'_, '_>, len: usize) { + fn hashcrew(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); bencher .counter(BytesCount::new(len)) - .bench(|| rache::murmur::murmur3_x86_32(black_box(&bytes), 0)); + .bench(|| hashcrew::murmur::murmur3_x86_32(black_box(&bytes), 0)); } #[divan::bench(args = SIZES)] @@ -471,11 +475,11 @@ mod murmur3_x86_128 { use super::*; #[divan::bench(args = SIZES)] - fn rache(bencher: Bencher<'_, '_>, len: usize) { + fn hashcrew(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); bencher .counter(BytesCount::new(len)) - .bench(|| rache::murmur::murmur3_x86_128(black_box(&bytes), 0)); + .bench(|| hashcrew::murmur::murmur3_x86_128(black_box(&bytes), 0)); } #[divan::bench(args = SIZES)] @@ -491,11 +495,11 @@ mod murmur3_x64_128 { use super::*; #[divan::bench(args = SIZES)] - fn rache(bencher: Bencher<'_, '_>, len: usize) { + fn hashcrew(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); bencher .counter(BytesCount::new(len)) - .bench(|| rache::murmur::murmur3_x64_128(black_box(&bytes), 0)); + .bench(|| hashcrew::murmur::murmur3_x64_128(black_box(&bytes), 0)); } #[divan::bench(args = SIZES)] @@ -511,11 +515,11 @@ mod fnv1a_32 { use super::*; #[divan::bench(args = SIZES)] - fn rache(bencher: Bencher<'_, '_>, len: usize) { + fn hashcrew(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); bencher .counter(BytesCount::new(len)) - .bench(|| rache::fnv::fnv1a_32(black_box(&bytes))); + .bench(|| hashcrew::fnv::fnv1a_32(black_box(&bytes))); } } @@ -523,11 +527,11 @@ mod fnv1a_64 { use super::*; #[divan::bench(args = SIZES)] - fn rache(bencher: Bencher<'_, '_>, len: usize) { + fn hashcrew(bencher: Bencher<'_, '_>, len: usize) { let bytes = input(len); bencher .counter(BytesCount::new(len)) - .bench(|| rache::fnv::fnv1a_64(black_box(&bytes))); + .bench(|| hashcrew::fnv::fnv1a_64(black_box(&bytes))); } #[divan::bench(args = SIZES)] diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 328f020..5a53216 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -20,7 +20,7 @@ edition.workspace = true rust-version.workspace = true [dependencies] -rache = { workspace = true } +hashcrew = { workspace = true } [[bin]] name = "hash-file" diff --git a/examples/src/hash_file.rs b/examples/src/hash_file.rs index 6ddd261..4c05d39 100644 --- a/examples/src/hash_file.rs +++ b/examples/src/hash_file.rs @@ -16,7 +16,7 @@ use std::env; use std::fs::File; use std::io; -use rache::xxhash::Xxh3_64; +use hashcrew::xxhash::Xxh3_64; fn main() -> io::Result<()> { let path = env::args_os() diff --git a/rache/Cargo.toml b/hashcrew/Cargo.toml similarity index 93% rename from rache/Cargo.toml rename to hashcrew/Cargo.toml index 963cebf..5659012 100644 --- a/rache/Cargo.toml +++ b/hashcrew/Cargo.toml @@ -15,12 +15,12 @@ [package] categories = ["algorithms", "no-std"] description = "Fast, portable non-cryptographic hashes for Rust" -documentation = "https://docs.rs/rache" +documentation = "https://docs.rs/hashcrew" homepage = "https://github.com/fast/rache" keywords = ["hash", "xxhash", "cityhash", "murmurhash", "fnv"] -name = "rache" +name = "hashcrew" repository = "https://github.com/fast/rache" -version = "0.2.0" +version = "0.1.0" edition.workspace = true license.workspace = true diff --git a/rache/LICENSE b/hashcrew/LICENSE similarity index 100% rename from rache/LICENSE rename to hashcrew/LICENSE diff --git a/rache/THIRD_PARTY_NOTICES.md b/hashcrew/THIRD_PARTY_NOTICES.md similarity index 91% rename from rache/THIRD_PARTY_NOTICES.md rename to hashcrew/THIRD_PARTY_NOTICES.md index 838c8c3..0d175c4 100644 --- a/rache/THIRD_PARTY_NOTICES.md +++ b/hashcrew/THIRD_PARTY_NOTICES.md @@ -25,16 +25,16 @@ The workspace organization was informed by Apache Asyncband, distributed under t - -`xxhash-rust` is a development-only conformance and benchmark dependency. It is not linked into the published `rache` crate: +`xxhash-rust` is a development-only conformance and benchmark dependency. It is not linked into the published `hashcrew` crate: - -`murmur3` and `fnv` are development-only conformance and benchmark dependencies. They are not linked into the published `rache` crate: +`murmur3` and `fnv` are development-only conformance and benchmark dependencies. They are not linked into the published `hashcrew` crate: - - -`cityhasher` and `cityhash-rs` are development-only conformance and benchmark dependencies. They are not linked into the published `rache` crate: +`cityhasher` and `cityhash-rs` are development-only conformance and benchmark dependencies. They are not linked into the published `hashcrew` crate: - - diff --git a/rache/src/cityhash/mod.rs b/hashcrew/src/cityhash/mod.rs similarity index 99% rename from rache/src/cityhash/mod.rs rename to hashcrew/src/cityhash/mod.rs index b852ead..60ad0e2 100644 --- a/rache/src/cityhash/mod.rs +++ b/hashcrew/src/cityhash/mod.rs @@ -25,9 +25,9 @@ //! new byte slice. //! //! ``` -//! use rache::cityhash::cityhash64_with_seed; +//! use hashcrew::cityhash::cityhash64_with_seed; //! -//! let digest = cityhash64_with_seed(b"rache", 42); +//! let digest = cityhash64_with_seed(b"hashcrew", 42); //! assert_ne!(digest, 0); //! ``` diff --git a/rache/src/fnv/mod.rs b/hashcrew/src/fnv/mod.rs similarity index 98% rename from rache/src/fnv/mod.rs rename to hashcrew/src/fnv/mod.rs index 7fe3ca9..e04e0dd 100644 --- a/rache/src/fnv/mod.rs +++ b/hashcrew/src/fnv/mod.rs @@ -24,13 +24,13 @@ //! is not a security key and does not make FNV resistant to hash flooding. //! //! ``` -//! use rache::fnv::Fnv1a64; -//! use rache::fnv::fnv1a_64; +//! use hashcrew::fnv::Fnv1a64; +//! use hashcrew::fnv::fnv1a_64; //! //! let mut state = Fnv1a64::new(); -//! state.update(b"ra"); -//! state.update(b"che"); -//! assert_eq!(state.digest(), fnv1a_64(b"rache")); +//! state.update(b"hash"); +//! state.update(b"crew"); +//! assert_eq!(state.digest(), fnv1a_64(b"hashcrew")); //! ``` use core::hash::BuildHasher; diff --git a/rache/src/lib.rs b/hashcrew/src/lib.rs similarity index 96% rename from rache/src/lib.rs rename to hashcrew/src/lib.rs index 4afed88..c1fe61b 100644 --- a/rache/src/lib.rs +++ b/hashcrew/src/lib.rs @@ -84,7 +84,7 @@ //! //! ```toml //! [dependencies] -//! rache = { version = "0.2", default-features = false } +//! hashcrew = { version = "0.1", default-features = false } //! ``` //! //! # Streaming input @@ -101,10 +101,10 @@ //! # { //! use std::io; //! -//! use rache::xxhash::Xxh3_64; -//! use rache::xxhash::xxh3_64; +//! use hashcrew::xxhash::Xxh3_64; +//! use hashcrew::xxhash::xxh3_64; //! -//! let input = b"rache"; +//! let input = b"hashcrew"; //! let mut state = Xxh3_64::new(); //! io::copy(&mut input.as_slice(), &mut state).unwrap(); //! @@ -118,13 +118,13 @@ //! a reusable state: //! //! ``` -//! use rache::xxhash::Xxh64; -//! use rache::xxhash::xxh64; +//! use hashcrew::xxhash::Xxh64; +//! use hashcrew::xxhash::xxh64; //! -//! let expected = xxh64(b"rache", 42); +//! let expected = xxh64(b"hashcrew", 42); //! let mut state = Xxh64::with_seed(42); -//! state.update(b"ra"); -//! state.update(b"che"); +//! state.update(b"hash"); +//! state.update(b"crew"); //! //! assert_eq!(state.digest(), expected); //! ``` diff --git a/rache/src/murmur/mod.rs b/hashcrew/src/murmur/mod.rs similarity index 98% rename from rache/src/murmur/mod.rs rename to hashcrew/src/murmur/mod.rs index cb14c29..bd0be34 100644 --- a/rache/src/murmur/mod.rs +++ b/hashcrew/src/murmur/mod.rs @@ -26,13 +26,13 @@ //! [`Hasher::finish`] can return only `u64`. //! //! ``` -//! use rache::murmur::Murmur3X64_128; -//! use rache::murmur::murmur3_x64_128; +//! use hashcrew::murmur::Murmur3X64_128; +//! use hashcrew::murmur::murmur3_x64_128; //! //! let mut state = Murmur3X64_128::with_seed(42); -//! state.update(b"ra"); -//! state.update(b"che"); -//! assert_eq!(state.digest(), murmur3_x64_128(b"rache", 42)); +//! state.update(b"hash"); +//! state.update(b"crew"); +//! assert_eq!(state.digest(), murmur3_x64_128(b"hashcrew", 42)); //! ``` use core::hash::BuildHasher; diff --git a/rache/src/xxhash/kernel/mod.rs b/hashcrew/src/xxhash/kernel/mod.rs similarity index 98% rename from rache/src/xxhash/kernel/mod.rs rename to hashcrew/src/xxhash/kernel/mod.rs index eec03d6..59e8060 100644 --- a/rache/src/xxhash/kernel/mod.rs +++ b/hashcrew/src/xxhash/kernel/mod.rs @@ -15,7 +15,7 @@ //! XXH3 execution backends. //! //! Short XXH3 inputs use their dedicated scalar algorithms. For inputs larger -//! than 240 bytes, `rache` directly selects features guaranteed by the target. +//! than 240 bytes, `hashcrew` directly selects features guaranteed by the target. //! Otherwise, a `std` build caches runtime feature detection and a `no_std` //! build falls back to the portable scalar kernel. diff --git a/rache/src/xxhash/kernel/neon.rs b/hashcrew/src/xxhash/kernel/neon.rs similarity index 100% rename from rache/src/xxhash/kernel/neon.rs rename to hashcrew/src/xxhash/kernel/neon.rs diff --git a/rache/src/xxhash/kernel/scalar.rs b/hashcrew/src/xxhash/kernel/scalar.rs similarity index 100% rename from rache/src/xxhash/kernel/scalar.rs rename to hashcrew/src/xxhash/kernel/scalar.rs diff --git a/rache/src/xxhash/kernel/x86.rs b/hashcrew/src/xxhash/kernel/x86.rs similarity index 100% rename from rache/src/xxhash/kernel/x86.rs rename to hashcrew/src/xxhash/kernel/x86.rs diff --git a/rache/src/xxhash/mod.rs b/hashcrew/src/xxhash/mod.rs similarity index 93% rename from rache/src/xxhash/mod.rs rename to hashcrew/src/xxhash/mod.rs index 34d2f44..69e2248 100644 --- a/rache/src/xxhash/mod.rs +++ b/hashcrew/src/xxhash/mod.rs @@ -31,13 +31,13 @@ //! scalar or hardware XXH3 backend; ordinary callers do not need to choose one. //! //! ``` -//! use rache::xxhash::Xxh3_64; -//! use rache::xxhash::xxh3_64; +//! use hashcrew::xxhash::Xxh3_64; +//! use hashcrew::xxhash::xxh3_64; //! //! let mut state = Xxh3_64::new(); -//! state.update(b"ra"); -//! state.update(b"che"); -//! assert_eq!(state.digest(), xxh3_64(b"rache")); +//! state.update(b"hash"); +//! state.update(b"crew"); +//! assert_eq!(state.digest(), xxh3_64(b"hashcrew")); //! ``` mod xxh3; diff --git a/rache/src/xxhash/xxh3.rs b/hashcrew/src/xxhash/xxh3.rs similarity index 100% rename from rache/src/xxhash/xxh3.rs rename to hashcrew/src/xxhash/xxh3.rs diff --git a/rache/src/xxhash/xxh32.rs b/hashcrew/src/xxhash/xxh32.rs similarity index 100% rename from rache/src/xxhash/xxh32.rs rename to hashcrew/src/xxhash/xxh32.rs diff --git a/rache/src/xxhash/xxh64.rs b/hashcrew/src/xxhash/xxh64.rs similarity index 100% rename from rache/src/xxhash/xxh64.rs rename to hashcrew/src/xxhash/xxh64.rs diff --git a/tests-integration/Cargo.toml b/tests-integration/Cargo.toml index 2e40f41..39e0ce1 100644 --- a/tests-integration/Cargo.toml +++ b/tests-integration/Cargo.toml @@ -23,8 +23,8 @@ rust-version.workspace = true cityhash-rs = { workspace = true } cityhasher = { workspace = true } fnv = { workspace = true } +hashcrew = { workspace = true } murmur3 = { workspace = true } -rache = { workspace = true } twox-hash = { workspace = true } xxhash-rust = { workspace = true } diff --git a/tests-integration/tests/cityhash.rs b/tests-integration/tests/cityhash.rs index 977b173..4b27559 100644 --- a/tests-integration/tests/cityhash.rs +++ b/tests-integration/tests/cityhash.rs @@ -12,13 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use rache::cityhash::cityhash32; -use rache::cityhash::cityhash64; -use rache::cityhash::cityhash64_with_seed; -use rache::cityhash::cityhash64_with_seeds; -use rache::cityhash::cityhash128; -use rache::cityhash::cityhash128_to_64; -use rache::cityhash::cityhash128_with_seed; +use hashcrew::cityhash::cityhash32; +use hashcrew::cityhash::cityhash64; +use hashcrew::cityhash::cityhash64_with_seed; +use hashcrew::cityhash::cityhash64_with_seeds; +use hashcrew::cityhash::cityhash128; +use hashcrew::cityhash::cityhash128_to_64; +use hashcrew::cityhash::cityhash128_with_seed; mod support; diff --git a/tests-integration/tests/io.rs b/tests-integration/tests/io.rs index d20e08d..a40f11d 100644 --- a/tests-integration/tests/io.rs +++ b/tests-integration/tests/io.rs @@ -15,19 +15,19 @@ use std::io::Cursor; use std::io::Write; -use rache::fnv::Fnv1a32; -use rache::fnv::Fnv1a64; -use rache::murmur::Murmur3X64_128; -use rache::murmur::Murmur3X86_32; -use rache::murmur::Murmur3X86_128; -use rache::murmur::murmur3_x64_128; -use rache::murmur::murmur3_x86_128; -use rache::xxhash::Xxh3_64; -use rache::xxhash::Xxh3_128; -use rache::xxhash::Xxh32; -use rache::xxhash::Xxh64; -use rache::xxhash::xxh3_64; -use rache::xxhash::xxh3_128; +use hashcrew::fnv::Fnv1a32; +use hashcrew::fnv::Fnv1a64; +use hashcrew::murmur::Murmur3X64_128; +use hashcrew::murmur::Murmur3X86_32; +use hashcrew::murmur::Murmur3X86_128; +use hashcrew::murmur::murmur3_x64_128; +use hashcrew::murmur::murmur3_x86_128; +use hashcrew::xxhash::Xxh3_64; +use hashcrew::xxhash::Xxh3_128; +use hashcrew::xxhash::Xxh32; +use hashcrew::xxhash::Xxh64; +use hashcrew::xxhash::xxh3_64; +use hashcrew::xxhash::xxh3_128; #[test] fn streaming_states_are_standard_io_writers() { diff --git a/tests-integration/tests/murmur_fnv.rs b/tests-integration/tests/murmur_fnv.rs index d599cea..ae79e76 100644 --- a/tests-integration/tests/murmur_fnv.rs +++ b/tests-integration/tests/murmur_fnv.rs @@ -16,21 +16,21 @@ use core::hash::BuildHasher; use core::hash::Hasher; use std::io::Cursor; -use rache::fnv::Fnv1a32; -use rache::fnv::Fnv1a32Builder; -use rache::fnv::Fnv1a64; -use rache::fnv::Fnv1a64Builder; -use rache::fnv::fnv1a_32; -use rache::fnv::fnv1a_32_with_offset_basis; -use rache::fnv::fnv1a_64; -use rache::fnv::fnv1a_64_with_offset_basis; -use rache::murmur::Murmur3X64_128; -use rache::murmur::Murmur3X86_32; -use rache::murmur::Murmur3X86_32Builder; -use rache::murmur::Murmur3X86_128; -use rache::murmur::murmur3_x64_128; -use rache::murmur::murmur3_x86_32; -use rache::murmur::murmur3_x86_128; +use hashcrew::fnv::Fnv1a32; +use hashcrew::fnv::Fnv1a32Builder; +use hashcrew::fnv::Fnv1a64; +use hashcrew::fnv::Fnv1a64Builder; +use hashcrew::fnv::fnv1a_32; +use hashcrew::fnv::fnv1a_32_with_offset_basis; +use hashcrew::fnv::fnv1a_64; +use hashcrew::fnv::fnv1a_64_with_offset_basis; +use hashcrew::murmur::Murmur3X64_128; +use hashcrew::murmur::Murmur3X86_32; +use hashcrew::murmur::Murmur3X86_32Builder; +use hashcrew::murmur::Murmur3X86_128; +use hashcrew::murmur::murmur3_x64_128; +use hashcrew::murmur::murmur3_x86_32; +use hashcrew::murmur::murmur3_x86_128; mod support; @@ -164,7 +164,7 @@ fn fnv_matches_specification_and_reference() { #[test] fn fnv_custom_offset_basis_matches_chaining_and_reference() { - let prefix = b"rache namespace"; + let prefix = b"hashcrew namespace"; let suffix = input(4_097); let mut joined = prefix.to_vec(); joined.extend_from_slice(&suffix); diff --git a/tests-integration/tests/xxhash.rs b/tests-integration/tests/xxhash.rs index e79d36f..dda339d 100644 --- a/tests-integration/tests/xxhash.rs +++ b/tests-integration/tests/xxhash.rs @@ -16,25 +16,25 @@ use core::hash::BuildHasher; use core::hash::Hasher; use std::collections::HashMap; -use rache::xxhash::SECRET_SIZE_MIN; -use rache::xxhash::Xxh3_64; -use rache::xxhash::Xxh3_64Builder; -use rache::xxhash::Xxh3_64SecretBuilder; -use rache::xxhash::Xxh3_128; -use rache::xxhash::Xxh32; -use rache::xxhash::Xxh32Builder; -use rache::xxhash::Xxh64; -use rache::xxhash::Xxh64Builder; -use rache::xxhash::xxh3_64; -use rache::xxhash::xxh3_64_with_secret; -use rache::xxhash::xxh3_64_with_seed; -use rache::xxhash::xxh3_64_with_seed_and_secret; -use rache::xxhash::xxh3_128; -use rache::xxhash::xxh3_128_with_secret; -use rache::xxhash::xxh3_128_with_seed; -use rache::xxhash::xxh3_128_with_seed_and_secret; -use rache::xxhash::xxh32; -use rache::xxhash::xxh64; +use hashcrew::xxhash::SECRET_SIZE_MIN; +use hashcrew::xxhash::Xxh3_64; +use hashcrew::xxhash::Xxh3_64Builder; +use hashcrew::xxhash::Xxh3_64SecretBuilder; +use hashcrew::xxhash::Xxh3_128; +use hashcrew::xxhash::Xxh32; +use hashcrew::xxhash::Xxh32Builder; +use hashcrew::xxhash::Xxh64; +use hashcrew::xxhash::Xxh64Builder; +use hashcrew::xxhash::xxh3_64; +use hashcrew::xxhash::xxh3_64_with_secret; +use hashcrew::xxhash::xxh3_64_with_seed; +use hashcrew::xxhash::xxh3_64_with_seed_and_secret; +use hashcrew::xxhash::xxh3_128; +use hashcrew::xxhash::xxh3_128_with_secret; +use hashcrew::xxhash::xxh3_128_with_seed; +use hashcrew::xxhash::xxh3_128_with_seed_and_secret; +use hashcrew::xxhash::xxh32; +use hashcrew::xxhash::xxh64; use xxhash_rust::xxh3; use xxhash_rust::xxh32 as reference32; use xxhash_rust::xxh64 as reference64; @@ -177,10 +177,10 @@ fn seed_and_secret_oneshot_matches_reference_contract() { #[test] fn custom_secret_length_is_validated() { let short = secret(SECRET_SIZE_MIN - 1); - let error = xxh3_64_with_secret(b"rache", &short).unwrap_err(); + let error = xxh3_64_with_secret(b"hashcrew", &short).unwrap_err(); assert_eq!(error.actual_len(), SECRET_SIZE_MIN - 1); assert_eq!( - rache::xxhash::Xxh3SecretTooShort::minimum_len(), + hashcrew::xxhash::Xxh3SecretTooShort::minimum_len(), SECRET_SIZE_MIN ); assert_eq!( @@ -188,9 +188,9 @@ fn custom_secret_length_is_validated() { "XXH3 secret is 135 bytes; at least 136 bytes are required" ); - assert!(xxh3_128_with_secret(b"rache", &short).is_err()); - assert!(xxh3_64_with_seed_and_secret(b"rache", 7, &short).is_err()); - assert!(xxh3_128_with_seed_and_secret(b"rache", 7, &short).is_err()); + assert!(xxh3_128_with_secret(b"hashcrew", &short).is_err()); + assert!(xxh3_64_with_seed_and_secret(b"hashcrew", 7, &short).is_err()); + assert!(xxh3_128_with_seed_and_secret(b"hashcrew", 7, &short).is_err()); assert!(Xxh3_64::with_secret(&short).is_err()); assert!(Xxh3_64::with_seed_and_secret(7, &short).is_err()); assert!(Xxh3_128::with_secret(&short).is_err()); @@ -218,8 +218,8 @@ fn custom_secret_states_and_builders_can_own_their_storage() { let builder = Xxh3_64SecretBuilder::with_secret(secret).unwrap(); let mut map = HashMap::with_hasher(builder); - map.insert("rache", 2); - assert_eq!(map["rache"], 2); + map.insert("hashcrew", 2); + assert_eq!(map["hashcrew"], 2); } #[test] @@ -543,5 +543,5 @@ fn standard_hash_traits_use_the_raw_stream() { xxh3_64_with_seed_and_secret(&bytes, 17, &secret).unwrap() ); - assert!(rache::xxhash::kernel::selected_backend().is_available()); + assert!(hashcrew::xxhash::kernel::selected_backend().is_available()); } diff --git a/typos.toml b/typos.toml index fd804e7..b2a6b6b 100644 --- a/typos.toml +++ b/typos.toml @@ -14,7 +14,7 @@ [default.extend-words] Collet = "Collet" -rache = "rache" +hashcrew = "hashcrew" [files] extend-exclude = ["/target"] diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 2075bb6..4dd1475 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -18,7 +18,7 @@ use std::process::Command as StdCommand; use clap::Parser; use clap::Subcommand; -const PACKAGE_NAME: &str = "rache"; +const PACKAGE_NAME: &str = "hashcrew"; #[derive(Parser)] struct Command { @@ -44,7 +44,7 @@ enum SubCommand { Bench(CommandBench), #[command(about = "Compile workspace packages.")] Build(CommandBuild), - #[command(about = "Check rache under its feature configurations.")] + #[command(about = "Check hashcrew under its feature configurations.")] Check(CommandCheck), #[command(about = "Run workspace quality checks.")] Lint(CommandLint), From 091c5cec0c5fec51e1034a3520b088993466ec3a Mon Sep 17 00:00:00 2001 From: tison Date: Wed, 2 Sep 2026 17:56:08 +0800 Subject: [PATCH 2/6] test: remove the empty integration library target The integration-test package is driven entirely by its four tests/*.rs targets. Cargo discovers and runs those targets without a placeholder library, so keeping an empty src/lib.rs plus four target-disable flags adds configuration without changing coverage. --- tests-integration/Cargo.toml | 6 ------ tests-integration/src/lib.rs | 15 --------------- 2 files changed, 21 deletions(-) delete mode 100644 tests-integration/src/lib.rs diff --git a/tests-integration/Cargo.toml b/tests-integration/Cargo.toml index 39e0ce1..8155652 100644 --- a/tests-integration/Cargo.toml +++ b/tests-integration/Cargo.toml @@ -28,11 +28,5 @@ murmur3 = { workspace = true } twox-hash = { workspace = true } xxhash-rust = { workspace = true } -[lib] -bench = false -doc = false -doctest = false -test = false - [lints] workspace = true diff --git a/tests-integration/src/lib.rs b/tests-integration/src/lib.rs deleted file mode 100644 index ad1d3c1..0000000 --- a/tests-integration/src/lib.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2026 FastLabs Developers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Integration-test-only workspace member. From 8664b845f5eb1087a15175907f3078e8be4ea091 Mon Sep 17 00:00:00 2001 From: tison Date: Wed, 2 Sep 2026 17:57:24 +0800 Subject: [PATCH 3/6] docs: remove the duplicate implementation history HISTORY.md did not record releases or decisions and had no incoming documentation links. Its five paragraphs repeated the API, streaming, kernel, and verification boundaries already maintained in ARCHITECTURE.md, creating two competing summaries without adding user-facing information. --- HISTORY.md | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 HISTORY.md diff --git a/HISTORY.md b/HISTORY.md deleted file mode 100644 index a4f0186..0000000 --- a/HISTORY.md +++ /dev/null @@ -1,11 +0,0 @@ -# Implementation history - -Hashcrew starts with four algorithm families behind a consistent family-qualified API. One-shot functions handle complete byte slices, bounded-memory state types handle incremental input where the algorithm permits it, and explicit adapters integrate 32-bit and 64-bit states with Rust's standard hashing traits. - -XXH32 and XXH64 use direct portable cores. XXH3 keeps short-input routing separate from a long-input kernel so scalar and hardware-accelerated backends can change without changing public APIs or digest output. Its streaming state owns fixed buffers and accepts borrowed or caller-owned secret storage, preserving allocation-free `no_std` operation. - -MurmurHash3 implements the reference `x86_32`, `x86_128`, and `x64_128` variants. Their architecture labels identify distinct algorithms rather than target restrictions. FNV-1a 32 and 64 use a portable byte-at-a-time core shared by one-shot functions, streaming states, and standard hash adapters. - -CityHash32, CityHash64, and CityHash128 remain one-shot-oriented. Their construction depends on the complete input length and tail, so a streaming facade would need to retain the entire message instead of providing bounded-memory incremental hashing. - -The repository keeps the dependency-free publishable crate separate from examples, benchmarks, and cross-implementation tests. Reference implementations are development-only dependencies and never enter the published package. From 50ee3252b564f521c6f9e48fec894855aa73157d Mon Sep 17 00:00:00 2001 From: tison Date: Wed, 2 Sep 2026 17:59:48 +0800 Subject: [PATCH 4/6] refactor: keep one source for the XXH3 secret minimum SECRET_SIZE_MIN already exposes the algorithm's fixed lower bound. Xxh3SecretTooShort::minimum_len() returned that same constant without using an error value, giving callers two canonical-looking ways to obtain one fact. Retain actual_len() because it reports per-error input and is not recoverable from the module constant. --- hashcrew/src/xxhash/xxh3.rs | 6 ------ tests-integration/tests/xxhash.rs | 4 ---- 2 files changed, 10 deletions(-) diff --git a/hashcrew/src/xxhash/xxh3.rs b/hashcrew/src/xxhash/xxh3.rs index ae62def..622aa68 100644 --- a/hashcrew/src/xxhash/xxh3.rs +++ b/hashcrew/src/xxhash/xxh3.rs @@ -80,12 +80,6 @@ impl Xxh3SecretTooShort { pub const fn actual_len(self) -> usize { self.actual_len } - - /// Returns the minimum accepted secret length. - #[must_use] - pub const fn minimum_len() -> usize { - SECRET_SIZE_MIN - } } impl fmt::Display for Xxh3SecretTooShort { diff --git a/tests-integration/tests/xxhash.rs b/tests-integration/tests/xxhash.rs index dda339d..1907989 100644 --- a/tests-integration/tests/xxhash.rs +++ b/tests-integration/tests/xxhash.rs @@ -179,10 +179,6 @@ fn custom_secret_length_is_validated() { let short = secret(SECRET_SIZE_MIN - 1); let error = xxh3_64_with_secret(b"hashcrew", &short).unwrap_err(); assert_eq!(error.actual_len(), SECRET_SIZE_MIN - 1); - assert_eq!( - hashcrew::xxhash::Xxh3SecretTooShort::minimum_len(), - SECRET_SIZE_MIN - ); assert_eq!( error.to_string(), "XXH3 secret is 135 bytes; at least 136 bytes are required" From 12f3e732dac50b777107c74040de547ea841a6b1 Mon Sep 17 00:00:00 2001 From: tison Date: Wed, 2 Sep 2026 18:01:39 +0800 Subject: [PATCH 5/6] feat: make default XXH3 state construction const XXH3 secret derivation is already const and every other built-in streaming state supports const construction. Carry constness through the private StreamState constructors so Xxh3_64 and Xxh3_128 can be initialized consistently in static or const contexts. The complete change compiles on the declared Rust 1.85 MSRV. --- hashcrew/src/xxhash/xxh3.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hashcrew/src/xxhash/xxh3.rs b/hashcrew/src/xxhash/xxh3.rs index 622aa68..1f68091 100644 --- a/hashcrew/src/xxhash/xxh3.rs +++ b/hashcrew/src/xxhash/xxh3.rs @@ -682,11 +682,11 @@ struct StreamState { } impl StreamState<[u8; DEFAULT_SECRET_SIZE]> { - fn with_seed(seed: u64) -> Self { + const fn with_seed(seed: u64) -> Self { Self::with_derived_secret(seed, derive_secret(seed)) } - fn with_derived_secret(seed: u64, secret: [u8; DEFAULT_SECRET_SIZE]) -> Self { + const fn with_derived_secret(seed: u64, secret: [u8; DEFAULT_SECRET_SIZE]) -> Self { Self { seed, secret, @@ -921,13 +921,13 @@ pub struct Xxh3_64(StreamState); impl Xxh3_64<[u8; DEFAULT_SECRET_SIZE]> { /// Creates an unseeded XXH3-64 state. #[must_use] - pub fn new() -> Self { + pub const fn new() -> Self { Self::with_seed(0) } /// Creates an XXH3-64 state with `seed`. #[must_use] - pub fn with_seed(seed: u64) -> Self { + pub const fn with_seed(seed: u64) -> Self { Self(StreamState::with_seed(seed)) } } @@ -1036,13 +1036,13 @@ pub struct Xxh3_128(StreamState); impl Xxh3_128<[u8; DEFAULT_SECRET_SIZE]> { /// Creates an unseeded XXH3-128 state. #[must_use] - pub fn new() -> Self { + pub const fn new() -> Self { Self::with_seed(0) } /// Creates an XXH3-128 state with `seed`. #[must_use] - pub fn with_seed(seed: u64) -> Self { + pub const fn with_seed(seed: u64) -> Self { Self(StreamState::with_seed(seed)) } } From 2a12310f706d42b245a5ee3063b918bcdeddb8e7 Mon Sep 17 00:00:00 2001 From: tison Date: Wed, 2 Sep 2026 19:07:36 +0800 Subject: [PATCH 6/6] docs: follow the renamed hashcrew repository The GitHub repository now lives at fast/hashcrew, so the crate metadata, workflow badge, and semantic-status link should use the canonical location instead of relying on GitHub's fast/rache redirect. --- .github/semantic.yml | 2 +- README.md | 4 ++-- hashcrew/Cargo.toml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/semantic.yml b/.github/semantic.yml index 68daa13..4a2a28c 100644 --- a/.github/semantic.yml +++ b/.github/semantic.yml @@ -32,4 +32,4 @@ types: - chore - revert -targetUrl: https://github.com/fast/rache/blob/main/.github/semantic.yml +targetUrl: https://github.com/fast/hashcrew/blob/main/.github/semantic.yml diff --git a/README.md b/README.md index 1a5f1fa..65cc2f2 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,8 @@ [msrv-badge]: https://img.shields.io/badge/MSRV-1.85-green?logo=rust [license-badge]: https://img.shields.io/crates/l/hashcrew [license-url]: LICENSE -[actions-badge]: https://github.com/fast/rache/actions/workflows/ci.yml/badge.svg -[actions-url]: https://github.com/fast/rache/actions/workflows/ci.yml +[actions-badge]: https://github.com/fast/hashcrew/actions/workflows/ci.yml/badge.svg +[actions-url]: https://github.com/fast/hashcrew/actions/workflows/ci.yml ## Overview diff --git a/hashcrew/Cargo.toml b/hashcrew/Cargo.toml index 5659012..fd55291 100644 --- a/hashcrew/Cargo.toml +++ b/hashcrew/Cargo.toml @@ -16,10 +16,10 @@ categories = ["algorithms", "no-std"] description = "Fast, portable non-cryptographic hashes for Rust" documentation = "https://docs.rs/hashcrew" -homepage = "https://github.com/fast/rache" +homepage = "https://github.com/fast/hashcrew" keywords = ["hash", "xxhash", "cityhash", "murmurhash", "fnv"] name = "hashcrew" -repository = "https://github.com/fast/rache" +repository = "https://github.com/fast/hashcrew" version = "0.1.0" edition.workspace = true