From 7a394530443b93c1c55c1af708f01a96c7be3381 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Mon, 1 Dec 2025 14:56:52 +0100 Subject: [PATCH] Remove `Prehashed` type --- src/hash.rs | 132 +--------------------------------------------------- src/lib.rs | 1 - 2 files changed, 1 insertion(+), 132 deletions(-) diff --git a/src/hash.rs b/src/hash.rs index 404854b..5474a39 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -1,8 +1,4 @@ -use std::any::Any; -use std::cmp::{Ord, PartialOrd}; -use std::fmt::{self, Debug, Formatter}; -use std::hash::{Hash, Hasher}; -use std::ops::Deref; +use std::hash::Hash; use siphasher::sip128::{Hasher128, SipHasher13}; @@ -13,129 +9,3 @@ pub fn hash(value: &T) -> u128 { value.hash(&mut state); state.finish128().as_u128() } - -/// Produce a 128-bit hash of a value's type and the value. -/// -/// Prefer this over `hash` if the resulting hash is used for the same purpose -/// as hashes of other types. -#[inline] -pub fn hash_any(item: &T) -> u128 { - // Also hash the TypeId because the type might be converted - // through an unsized coercion. - let mut state = SipHasher13::new(); - item.type_id().hash(&mut state); - item.hash(&mut state); - state.finish128().as_u128() -} - -/// A wrapper type with precomputed hash. -/// -/// This is useful if you want to pass large values of `T` to memoized -/// functions. Especially recursive structures like trees benefit from -/// intermediate prehashed nodes. -/// -/// Note that for a value `v` of type `T`, `hash(v)` is not necessarily equal to -/// `hash(Prehashed::new(v))`. Writing the precomputed hash into a hasher's -/// state produces different output than writing the value's parts directly. -/// However, that seldomly matters as you are typically either dealing with -/// values of type `T` or with values of type `Prehashed`, not a mix of both. -/// -/// # Equality -/// Because comemo uses high-quality 128 bit hashes in all places, the risk of a -/// hash collision is reduced to an absolute minimum. Therefore, this type -/// additionally provides `PartialEq` and `Eq` implementations that compare by -/// hash instead of by value. For this to be correct, your hash implementation -/// **must feed all information relevant to the `PartialEq` impl to the -/// hasher.** -#[derive(Copy, Clone)] -pub struct Prehashed { - /// The precomputed hash. - hash: u128, - /// The wrapped item. - item: T, -} - -impl Prehashed { - /// Compute an item's hash and wrap it. - #[inline] - pub fn new(item: T) -> Self { - Self { hash: hash_any(&item), item } - } - - /// Return the wrapped value. - #[inline] - pub fn into_inner(self) -> T { - self.item - } - - /// Update the wrapped value and recompute the hash. - #[inline] - pub fn update(&mut self, f: F) -> U - where - F: FnOnce(&mut T) -> U, - { - let output = f(&mut self.item); - self.hash = hash_any(&self.item); - output - } -} - -impl Deref for Prehashed { - type Target = T; - - #[inline] - fn deref(&self) -> &Self::Target { - &self.item - } -} - -impl From for Prehashed { - #[inline] - fn from(value: T) -> Self { - Self::new(value) - } -} - -impl Hash for Prehashed { - #[inline] - fn hash(&self, state: &mut H) { - state.write_u128(self.hash); - } -} - -impl Debug for Prehashed { - #[inline] - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - self.item.fmt(f) - } -} - -impl Default for Prehashed { - #[inline] - fn default() -> Self { - Self::new(T::default()) - } -} - -impl Eq for Prehashed {} - -impl PartialEq for Prehashed { - #[inline] - fn eq(&self, other: &Self) -> bool { - self.hash == other.hash - } -} - -impl Ord for Prehashed { - #[inline] - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.item.cmp(&other.item) - } -} - -impl PartialOrd for Prehashed { - #[inline] - fn partial_cmp(&self, other: &Self) -> Option { - self.item.partial_cmp(&other.item) - } -} diff --git a/src/lib.rs b/src/lib.rs index 90d85cf..0e8df80 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -100,7 +100,6 @@ mod tree; pub mod testing; pub use crate::constraint::Constraint; -pub use crate::hash::Prehashed; pub use crate::memoize::evict; pub use crate::track::{Track, Tracked, TrackedMut};