From 51c6e2d196dec5b159c7ab638ee1ce6a91448c80 Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 20 Jun 2024 17:09:02 +0200 Subject: [PATCH 1/2] Remove `StableHasher::finalize` by inlining it's routine --- CHANGELOG.md | 1 + src/stable_hasher.rs | 9 ++------- src/stable_hasher/tests.rs | 25 +++++++++++++++++-------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 877691c..103b4ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,4 @@ # Unreleased +- Remove `StableHasher::finalize` (#4) - Import stable hasher implementation from rustc ([db8aca48129](https://github.com/rust-lang/rust/blob/db8aca48129d86b2623e3ac8cbcf2902d4d313ad/compiler/rustc_data_structures/src/)) diff --git a/src/stable_hasher.rs b/src/stable_hasher.rs index 200d313..436bc35 100644 --- a/src/stable_hasher.rs +++ b/src/stable_hasher.rs @@ -10,7 +10,7 @@ mod tests; /// Trait for retrieving the result of the stable hashing operation. pub trait StableHasherResult: Sized { - fn finish(hasher: StableHasher) -> Self; + fn finish(hash: (u64, u64)) -> Self; } /// When hashing something that ends up affecting properties like symbol names, @@ -40,12 +40,7 @@ impl StableHasher { #[inline] pub fn finish(self) -> W { - W::finish(self) - } - - #[inline] - pub fn finalize(self) -> (u64, u64) { - self.state.finish128() + W::finish(self.state.finish128()) } } diff --git a/src/stable_hasher/tests.rs b/src/stable_hasher/tests.rs index 1aaec46..fecc421 100644 --- a/src/stable_hasher/tests.rs +++ b/src/stable_hasher/tests.rs @@ -9,6 +9,15 @@ use super::*; // ways). The expected values depend on the hashing algorithm used, so they // need to be updated whenever StableHasher changes its hashing algorithm. +#[derive(Debug, PartialEq)] +struct TestHash((u64, u64)); + +impl StableHasherResult for TestHash { + fn finish(hash: (u64, u64)) -> TestHash { + TestHash(hash) + } +} + #[test] fn test_hash_integers() { // Test that integers are handled consistently across platforms. @@ -41,9 +50,9 @@ fn test_hash_integers() { test_isize.hash(&mut h); // This depends on the hashing algorithm. See note at top of file. - let expected = (13997337031081104755, 6178945012502239489); + let expected = TestHash((13997337031081104755, 6178945012502239489)); - assert_eq!(h.finalize(), expected); + assert_eq!(expected, h.finish()); } #[test] @@ -55,9 +64,9 @@ fn test_hash_usize() { test_usize.hash(&mut h); // This depends on the hashing algorithm. See note at top of file. - let expected = (12037165114281468837, 3094087741167521712); + let expected = TestHash((12037165114281468837, 3094087741167521712)); - assert_eq!(h.finalize(), expected); + assert_eq!(expected, h.finish()); } #[test] @@ -69,15 +78,15 @@ fn test_hash_isize() { test_isize.hash(&mut h); // This depends on the hashing algorithm. See note at top of file. - let expected = (3979067582695659080, 2322428596355037273); + let expected = TestHash((3979067582695659080, 2322428596355037273)); - assert_eq!(h.finalize(), expected); + assert_eq!(expected, h.finish()); } -fn hash(t: &T) -> (u64, u64) { +fn hash(t: &T) -> TestHash { let mut h = StableHasher::new(); t.hash(&mut h); - h.finalize() + h.finish() } // Check that the `isize` hashing optimization does not produce the same hash when permuting two From eceea7abb343dc03542c130faa1e4bce6a24f33d Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 20 Jun 2024 18:52:40 +0200 Subject: [PATCH 2/2] Switch to an array representation `[u64; 2]` instead of a tuple --- src/sip128.rs | 4 ++-- src/sip128/tests.rs | 9 +++++---- src/stable_hasher.rs | 2 +- src/stable_hasher/tests.rs | 10 +++++----- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/sip128.rs b/src/sip128.rs index 564f175..724d96c 100644 --- a/src/sip128.rs +++ b/src/sip128.rs @@ -378,7 +378,7 @@ impl SipHasher128 { } #[inline] - pub fn finish128(mut self) -> (u64, u64) { + pub fn finish128(mut self) -> [u64; 2] { debug_assert!(self.nbuf < BUFFER_SIZE); // Process full elements in buffer. @@ -426,7 +426,7 @@ impl SipHasher128 { Sip13Rounds::d_rounds(&mut state); let _1 = state.v0 ^ state.v1 ^ state.v2 ^ state.v3; - (_0, _1) + [_0, _1] } } diff --git a/src/sip128/tests.rs b/src/sip128/tests.rs index e9dd0f1..71ee07d 100644 --- a/src/sip128/tests.rs +++ b/src/sip128/tests.rs @@ -14,14 +14,15 @@ impl<'a> Hash for Bytes<'a> { } } -fn hash_with(mut st: SipHasher128, x: &T) -> (u64, u64) { +fn hash_with(mut st: SipHasher128, x: &T) -> [u64; 2] { x.hash(&mut st); st.finish128() } -fn hash(x: &T) -> (u64, u64) { +fn hash(x: &T) -> [u64; 2] { hash_with(SipHasher128::new_with_keys(0, 0), x) } + #[rustfmt::skip] const TEST_VECTOR: [[u8; 16]; 64] = [ [0xe7, 0x7e, 0xbc, 0xb2, 0x27, 0x88, 0xa5, 0xbe, 0xfd, 0x62, 0xdb, 0x6a, 0xdd, 0x30, 0x30, 0x01], @@ -99,7 +100,7 @@ fn test_siphash_1_3_test_vector() { for i in 0..64 { let out = hash_with(SipHasher128::new_with_keys(k0, k1), &Bytes(&input[..])); - let expected = ( + let expected = [ ((TEST_VECTOR[i][0] as u64) << 0) | ((TEST_VECTOR[i][1] as u64) << 8) | ((TEST_VECTOR[i][2] as u64) << 16) @@ -116,7 +117,7 @@ fn test_siphash_1_3_test_vector() { | ((TEST_VECTOR[i][13] as u64) << 40) | ((TEST_VECTOR[i][14] as u64) << 48) | ((TEST_VECTOR[i][15] as u64) << 56), - ); + ]; assert_eq!(out, expected); input.push(i as u8); diff --git a/src/stable_hasher.rs b/src/stable_hasher.rs index 436bc35..5a6aa6c 100644 --- a/src/stable_hasher.rs +++ b/src/stable_hasher.rs @@ -10,7 +10,7 @@ mod tests; /// Trait for retrieving the result of the stable hashing operation. pub trait StableHasherResult: Sized { - fn finish(hash: (u64, u64)) -> Self; + fn finish(hash: [u64; 2]) -> Self; } /// When hashing something that ends up affecting properties like symbol names, diff --git a/src/stable_hasher/tests.rs b/src/stable_hasher/tests.rs index fecc421..e6560db 100644 --- a/src/stable_hasher/tests.rs +++ b/src/stable_hasher/tests.rs @@ -10,10 +10,10 @@ use super::*; // need to be updated whenever StableHasher changes its hashing algorithm. #[derive(Debug, PartialEq)] -struct TestHash((u64, u64)); +struct TestHash([u64; 2]); impl StableHasherResult for TestHash { - fn finish(hash: (u64, u64)) -> TestHash { + fn finish(hash: [u64; 2]) -> TestHash { TestHash(hash) } } @@ -50,7 +50,7 @@ fn test_hash_integers() { test_isize.hash(&mut h); // This depends on the hashing algorithm. See note at top of file. - let expected = TestHash((13997337031081104755, 6178945012502239489)); + let expected = TestHash([13997337031081104755, 6178945012502239489]); assert_eq!(expected, h.finish()); } @@ -64,7 +64,7 @@ fn test_hash_usize() { test_usize.hash(&mut h); // This depends on the hashing algorithm. See note at top of file. - let expected = TestHash((12037165114281468837, 3094087741167521712)); + let expected = TestHash([12037165114281468837, 3094087741167521712]); assert_eq!(expected, h.finish()); } @@ -78,7 +78,7 @@ fn test_hash_isize() { test_isize.hash(&mut h); // This depends on the hashing algorithm. See note at top of file. - let expected = TestHash((3979067582695659080, 2322428596355037273)); + let expected = TestHash([3979067582695659080, 2322428596355037273]); assert_eq!(expected, h.finish()); }