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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/hash/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
//! | `cityHash64` | [`CityHash64::hash_with_seed`] | u64 → u64 |
//! | `xxHash32` | [`XxHash32::hash`] | u32 → u32 |
//! | `xxHash64` | [`XxHash64::hash`] | u64 → u64 |
//! | `xxHash3` | [`XxHash3::hash`] | u64 → u64 |
//! | `xxHash3` | `bun_highway::xxhash3_64` | u64 → u64 |
//! | `murmur32v2` | [`Murmur2_32::hash_with_seed`] | u32 → u32 |
//! | `murmur32v3` | [`Murmur3_32::hash_with_seed`] | u32 → u32 |
//! | `murmur64v2` | [`Murmur2_64::hash_with_seed`] | u64 → u64 |
Expand All @@ -31,7 +31,7 @@ pub use adler32::Adler32;
pub use cityhash::{CityHash32, CityHash64};
pub use murmur::{Murmur2_32, Murmur2_64, Murmur3_32};
pub use rapidhash::RapidHash;
pub use xxhash::{XxHash3, XxHash32, XxHash64, XxHash64Streaming};
pub use xxhash::{XxHash32, XxHash64, XxHash64Streaming};

#[cfg(test)]
pub(crate) mod verify {
Expand Down
171 changes: 0 additions & 171 deletions src/hash/murmur.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,51 +66,6 @@ impl Murmur2_32 {
h1 ^= h1 >> 15;
h1
}

#[inline]
pub fn hash_uint32(v: u32) -> u32 {
Self::hash_uint32_with_seed(v, DEFAULT_SEED)
}

pub fn hash_uint32_with_seed(v: u32, seed: u32) -> u32 {
const M: u32 = 0x5bd1e995;
let len: u32 = 4;
let mut h1: u32 = seed ^ len;
let mut k1 = v.wrapping_mul(M);
k1 ^= k1 >> 24;
k1 = k1.wrapping_mul(M);
h1 = h1.wrapping_mul(M);
h1 ^= k1;
h1 ^= h1 >> 13;
h1 = h1.wrapping_mul(M);
h1 ^= h1 >> 15;
h1
}

#[inline]
pub fn hash_uint64(v: u64) -> u32 {
Self::hash_uint64_with_seed(v, DEFAULT_SEED)
}

pub fn hash_uint64_with_seed(v: u64, seed: u32) -> u32 {
const M: u32 = 0x5bd1e995;
let len: u32 = 8;
let mut h1: u32 = seed ^ len;
let mut k1 = (v as u32).wrapping_mul(M);
k1 ^= k1 >> 24;
k1 = k1.wrapping_mul(M);
h1 = h1.wrapping_mul(M);
h1 ^= k1;
k1 = ((v >> 32) as u32).wrapping_mul(M);
k1 ^= k1 >> 24;
k1 = k1.wrapping_mul(M);
h1 = h1.wrapping_mul(M);
h1 ^= k1;
h1 ^= h1 >> 13;
h1 = h1.wrapping_mul(M);
h1 ^= h1 >> 15;
h1
}
}

// ──────────────────────────────────────────────────────────────────────────
Expand Down Expand Up @@ -156,44 +111,6 @@ impl Murmur2_64 {
h1 ^= h1 >> 47;
h1
}

#[inline]
pub fn hash_uint32(v: u32) -> u64 {
Self::hash_uint32_with_seed(v, DEFAULT_SEED as u64)
}

pub fn hash_uint32_with_seed(v: u32, seed: u64) -> u64 {
const M: u64 = 0xc6a4a7935bd1e995;
let len: u64 = 4;
let mut h1: u64 = seed ^ len.wrapping_mul(M);
let k1: u64 = v as u64;
h1 ^= k1;
h1 = h1.wrapping_mul(M);
h1 ^= h1 >> 47;
h1 = h1.wrapping_mul(M);
h1 ^= h1 >> 47;
h1
}

#[inline]
pub fn hash_uint64(v: u64) -> u64 {
Self::hash_uint64_with_seed(v, DEFAULT_SEED as u64)
}

pub fn hash_uint64_with_seed(v: u64, seed: u64) -> u64 {
const M: u64 = 0xc6a4a7935bd1e995;
let len: u64 = 8;
let mut h1: u64 = seed ^ len.wrapping_mul(M);
let mut k1 = v.wrapping_mul(M);
k1 ^= k1 >> 47;
k1 = k1.wrapping_mul(M);
h1 ^= k1;
h1 = h1.wrapping_mul(M);
h1 ^= h1 >> 47;
h1 = h1.wrapping_mul(M);
h1 ^= h1 >> 47;
h1
}
}

// ──────────────────────────────────────────────────────────────────────────
Expand Down Expand Up @@ -264,111 +181,23 @@ impl Murmur3_32 {
h1 ^= len;
fmix32(h1)
}

#[inline]
pub fn hash_uint32(v: u32) -> u32 {
Self::hash_uint32_with_seed(v, DEFAULT_SEED)
}

pub fn hash_uint32_with_seed(v: u32, seed: u32) -> u32 {
const C1: u32 = 0xcc9e2d51;
const C2: u32 = 0x1b873593;
let len: u32 = 4;
let mut h1: u32 = seed;
let mut k1 = v.wrapping_mul(C1);
k1 = Self::rotl32(k1, 15);
k1 = k1.wrapping_mul(C2);
h1 ^= k1;
h1 = Self::rotl32(h1, 13);
h1 = h1.wrapping_mul(5).wrapping_add(0xe6546b64);
h1 ^= len;
fmix32(h1)
}

#[inline]
pub fn hash_uint64(v: u64) -> u32 {
Self::hash_uint64_with_seed(v, DEFAULT_SEED)
}

pub fn hash_uint64_with_seed(v: u64, seed: u32) -> u32 {
const C1: u32 = 0xcc9e2d51;
const C2: u32 = 0x1b873593;
let len: u32 = 8;
let mut h1: u32 = seed;
let mut k1 = (v as u32).wrapping_mul(C1);
k1 = Self::rotl32(k1, 15);
k1 = k1.wrapping_mul(C2);
h1 ^= k1;
h1 = Self::rotl32(h1, 13);
h1 = h1.wrapping_mul(5).wrapping_add(0xe6546b64);
k1 = ((v >> 32) as u32).wrapping_mul(C1);
k1 = Self::rotl32(k1, 15);
k1 = k1.wrapping_mul(C2);
h1 ^= k1;
h1 = Self::rotl32(h1, 13);
h1 = h1.wrapping_mul(5).wrapping_add(0xe6546b64);
h1 ^= len;
fmix32(h1)
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::verify::{smhasher_32, smhasher_64};

#[test]
fn murmur2_32_uint() {
let v0: u32 = 0x12345678;
let v1: u64 = 0x1234567812345678;
assert_eq!(
Murmur2_32::hash(&v0.to_le_bytes()),
Murmur2_32::hash_uint32(v0)
);
assert_eq!(
Murmur2_32::hash(&v1.to_le_bytes()),
Murmur2_32::hash_uint64(v1)
);
}

#[test]
fn murmur2_32_smhasher() {
assert_eq!(smhasher_32(Murmur2_32::hash_with_seed), 0x27864C1E);
}

#[test]
fn murmur2_64_uint() {
let v0: u32 = 0x12345678;
let v1: u64 = 0x1234567812345678;
assert_eq!(
Murmur2_64::hash(&v0.to_le_bytes()),
Murmur2_64::hash_uint32(v0)
);
assert_eq!(
Murmur2_64::hash(&v1.to_le_bytes()),
Murmur2_64::hash_uint64(v1)
);
}

#[test]
fn murmur2_64_smhasher() {
assert_eq!(smhasher_64(Murmur2_64::hash_with_seed), 0x1F0D3804);
}

#[test]
fn murmur3_32_uint() {
let v0: u32 = 0x12345678;
let v1: u64 = 0x1234567812345678;
assert_eq!(
Murmur3_32::hash(&v0.to_le_bytes()),
Murmur3_32::hash_uint32(v0)
);
assert_eq!(
Murmur3_32::hash(&v1.to_le_bytes()),
Murmur3_32::hash_uint64(v1)
);
}

#[test]
fn murmur3_32_smhasher() {
assert_eq!(smhasher_32(Murmur3_32::hash_with_seed), 0xB0F57EE3);
Expand Down
17 changes: 4 additions & 13 deletions src/hash/xxhash.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//! XxHash32 / XxHash64 / XxHash3.
//! XxHash32 / XxHash64.
//!
//! Thin wrappers over the C++/Highway xxHash kernel in
//! `src/jsc/bindings/xxhash3.cpp` (exposed by `bun_highway`). XXH3's long-input
//! stripe loop is runtime-dispatched to the widest SIMD ISA the CPU supports;
//! XXH32/XXH64 are scalar (no SIMD form exists in the reference). Output is
//! `src/jsc/bindings/xxhash3.cpp` (exposed by `bun_highway`).
//! XXH32/XXH64 are scalar (no SIMD form exists in the reference);
//! `HashObject.rs` calls `bun_highway::xxhash3_64` directly for XXH3. Output is
//! bit-identical to the xxHash
//! reference test vectors — verified against the reference (and across every
//! dispatch target) by `test/js/bun/util/hash.test.js`, which runs in CI.
Expand Down Expand Up @@ -59,12 +59,3 @@ impl Default for XxHash64Streaming {
Self::new(0)
}
}
Comment thread
robobun marked this conversation as resolved.

pub struct XxHash3;

impl XxHash3 {
#[inline]
pub fn hash(seed: u64, input: &[u8]) -> u64 {
bun_highway::xxhash3_64(seed, input)
}
}
Loading