diff --git a/Cargo.lock b/Cargo.lock index f9c8859..12983e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -90,7 +90,7 @@ dependencies = [ "rand", "serde", "serde_cbor", - "siphasher", + "twox-hash", ] [[package]] @@ -321,21 +321,18 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" -[[package]] -name = "siphasher" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" -dependencies = [ - "serde", -] - [[package]] name = "smallvec" version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "syn" version = "2.0.114" @@ -405,6 +402,17 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "twox-hash" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if", + "serde", + "static_assertions", +] + [[package]] name = "unicode-ident" version = "1.0.22" diff --git a/Cargo.toml b/Cargo.toml index d861d46..eaa18f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,14 +20,14 @@ default = ["std", "rand"] std = ["portable-atomic/std"] loom = ["dep:loom"] rand = ["std", "dep:rand"] -serde = ["dep:serde", "siphasher/serde_std", "portable-atomic/serde"] +serde = ["dep:serde", "twox-hash/serialize", "portable-atomic/serde"] [dependencies] foldhash = { version = "0.2.0", default-features = false } loom = { version = "0.7.2", optional = true } rand = { version = "0.9.0", optional = true } serde = { version = "1.0.203", features = ["derive"], optional = true } -siphasher = { version = "1.0.0", default-features = false } +twox-hash = { version = "1.6.3", default-features = false } libm = "0.2" portable-atomic = { version = "1.13.1", default-features = false, features = ["fallback"] } diff --git a/src/hasher.rs b/src/hasher.rs index 5d5cc98..5094fb0 100644 --- a/src/hasher.rs +++ b/src/hasher.rs @@ -1,5 +1,5 @@ use core::hash::{BuildHasher, Hasher}; -use siphasher::sip::SipHasher13; +use twox_hash::XxHash64; #[derive(Clone, Debug, Default, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -32,7 +32,7 @@ impl BuildHasher for CloneBuildHasher { pub type DefaultHasher = CloneBuildHasher; impl DefaultHasher { - pub fn seeded(seed: &[u8; 16]) -> Self { + pub fn seeded(seed: u64) -> Self { Self { hasher: RandomDefaultHasher::seeded(seed), } @@ -41,12 +41,12 @@ impl DefaultHasher { #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct RandomDefaultHasher(SipHasher13); +pub struct RandomDefaultHasher(XxHash64); impl RandomDefaultHasher { #[inline] - pub fn seeded(seed: &[u8; 16]) -> Self { - Self(SipHasher13::new_with_key(seed)) + pub fn seeded(seed: u64) -> Self { + Self(XxHash64::with_seed(seed)) } } @@ -56,18 +56,13 @@ impl Default for RandomDefaultHasher { #[cfg(not(feature = "rand"))] { use foldhash::fast::RandomState; - let state_a = RandomState::default(); - let state_b = RandomState::default(); - let lo = state_a.build_hasher().finish() as u128; - let hi = state_b.build_hasher().finish() as u128; - Self::seeded(&((hi << 64) | lo).to_ne_bytes()) + let seed = RandomState::default().build_hasher().finish(); + Self::seeded(seed) } #[cfg(feature = "rand")] { - let mut seed = [0u8; 16]; - use rand::RngCore; - rand::rng().fill_bytes(&mut seed); - Self::seeded(&seed) + use rand::Rng; + Self::seeded(rand::rng().random()) } } } @@ -135,7 +130,6 @@ impl Hasher for RandomDefaultHasher { mod test { use crate::hasher::RandomDefaultHasher; use core::hash::Hasher; - use siphasher::sip::SipHasher13; fn hash_all(mut x: impl Hasher) -> u64 { x.write(&[1; 16]); @@ -156,8 +150,8 @@ mod test { #[test] fn test_hasher() { - let h1 = RandomDefaultHasher::seeded(&[0; 16]); - let h2 = SipHasher13::new_with_key(&[0; 16]); + let h1 = RandomDefaultHasher::seeded(0); + let h2 = RandomDefaultHasher::seeded(0); assert_eq!(hash_all(h1), hash_all(h2),); } } diff --git a/src/lib.rs b/src/lib.rs index d05aace..65f3b94 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -139,8 +139,8 @@ macro_rules! impl_hll { /// Returns a new [`Self`] with `1 << precision` registers (1 byte each) /// using the default hasher seeded with `seed`. - pub fn seeded(precision: u8, seed: u128) -> $name { - $name::with_hasher(precision, DefaultHasher::seeded(&seed.to_be_bytes())) + pub fn seeded(precision: u8, seed: u64) -> $name { + $name::with_hasher(precision, DefaultHasher::seeded(seed)) } } diff --git a/src/sparse.rs b/src/sparse.rs index 95cfb78..931ac6b 100644 --- a/src/sparse.rs +++ b/src/sparse.rs @@ -296,8 +296,8 @@ impl HyperLogLogPlus { /// [`Self`] is initialized to use the compact and dynamically sized sparse /// representation, but later switches to the dense representation when /// it uses equal memory (`1 << precision` registers, 1 byte each). - pub fn seeded(precision: u8, seed: u128) -> Self { - Self::with_hasher(precision, DefaultHasher::seeded(&seed.to_be_bytes())) + pub fn seeded(precision: u8, seed: u64) -> Self { + Self::with_hasher(precision, DefaultHasher::seeded(seed)) } }