pub struct LazyHash<T: ?Sized> { /* private fields */ }Expand description
A wrapper type with lazily-computed 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(LazyHash::new(v)). Writing the precomputed hash into a hasher’s
state produces different output than writing the value’s parts directly.
However, that seldom matters as you are typically either dealing with values
of type T or with values of type LazyHash<T>, not a mix of both.
§Equality
Because Typst 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.
§Usage
If the value is expected to be cloned, it is best used inside of an Arc
or Rc to best re-use the hash once it has been computed.
§Unsized coercions
The LazyHash type supports unsized payload types and coercions to such.
For instance, a LazyHash<&'static str> can be coerced to a
LazyHash<dyn YourTrait> when &'static str: YourTrait. When it is hashed,
a LazyHash will always use the Hash impl of the underlying type. This
underlying type changes through an unsized coercion. When coercing a
LazyHash that has an already populated internal hash, you’ll thus get a
cached hash that was hashed with another impl than a fresh hash would have
used. To avoid this, when performing unsized coercions, avoid hashing the
value before the coercion and overall try to minimize the timespan in which
the original type is active. Typical usages of unsized coercions have a very
minimal lifetime of the original type only upon construction.
Implementations§
Trait Implementations§
impl<T: Hash + ?Sized + 'static> Eq for LazyHash<T>
Auto Trait Implementations§
impl<T> !Freeze for LazyHash<T>
impl<T> RefUnwindSafe for LazyHash<T>where
T: RefUnwindSafe + ?Sized,
impl<T> Send for LazyHash<T>
impl<T> Sync for LazyHash<T>
impl<T> Unpin for LazyHash<T>
impl<T> UnsafeUnpin for LazyHash<T>where
T: UnsafeUnpin + ?Sized,
impl<T> UnwindSafe for LazyHash<T>where
T: UnwindSafe + ?Sized,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more