pub struct Hashed<V> {
hash: u64,
value: V,
}Expand description
A value whose hash is computed once, up front.
Hashing one of these writes the stored word instead of walking the value,
and comparing two of them settles inequality on the word alone. That is
worth doing where a value is large, shared, and hashed once per entity per
frame — see VertexLayout.
Equality checks the hash before the value. That is sound because Hash
requires equal values to hash alike: a hash mismatch therefore means the
values differ, and a hash collision only costs the comparison that would
have run anyway. The hasher is fixed rather than chosen per instance for the
same reason — equal values have to keep hashing alike for the check to hold.
There is no DerefMut: editing the value through one would leave the
stored word stale, and equal values with different words would compare
unequal. A mutation goes through Hashed::update instead, which
recomputes the word after the value changes.
Fields§
§hash: u64The value’s hash.
value: VThe value the hash was taken from.
Implementations§
Source§impl<V: Hash> Hashed<V>
impl<V: Hash> Hashed<V>
Sourcepub fn update(&mut self, rewrite: impl FnOnce(&mut V))
pub fn update(&mut self, rewrite: impl FnOnce(&mut V))
Rewrite the value in place and recompute the stored word.
The closure receives the value itself, so a caller can apply one of the
value type’s own mutating methods — a set_-style rewrite, say — and
leave the word in step with the value it describes. The recomputation
costs what Self::new does, so this is the way to change a value
that is already built, not a cheaper one.
Trait Implementations§
impl<V: Eq> Eq for Hashed<V>
Auto Trait Implementations§
impl<V> Forget for Hashed<V>
impl<V> Freeze for Hashed<V>where
V: Freeze,
impl<V> RefUnwindSafe for Hashed<V>where
V: RefUnwindSafe,
impl<V> Send for Hashed<V>where
V: Send,
impl<V> Sync for Hashed<V>where
V: Sync,
impl<V> Unpin for Hashed<V>where
V: Unpin,
impl<V> UnsafeUnpin for Hashed<V>where
V: UnsafeUnpin,
impl<V> UnwindSafe for Hashed<V>where
V: UnwindSafe,
Blanket Implementations§
impl<T> AsId for T
impl<T> AsIdSalt for T
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
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 moreimpl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
impl<T> SerializableAny for T
§impl<F, T, S> SimdInto<T, S> for Fwhere
T: SimdFrom<F, S>,
S: Simd,
impl<F, T, S> SimdInto<T, S> for Fwhere
T: SimdFrom<F, S>,
S: Simd,
§impl<T> Source for T
impl<T> Source for T
§type Slice<'a> = <<T as Deref>::Target as Source>::Slice<'a>where
T: 'a,
type Slice<'a> = <<T as Deref>::Target as Source>::Slice<'a>where
T: 'a,
Source can be sliced into.§fn read<'a, Chunk>(&'a self, offset: usize) -> Option<Chunk>where
Chunk: Chunk<'a>,
fn read<'a, Chunk>(&'a self, offset: usize) -> Option<Chunk>where
Chunk: Chunk<'a>,
None when reading
out of bounds would occur. Read more§fn slice(&self, range: Range<usize>) -> Option<<T as Source>::Slice<'_>>
fn slice(&self, range: Range<usize>) -> Option<<T as Source>::Slice<'_>>
slice::get(range). Read more§unsafe fn slice_unchecked(
&self,
range: Range<usize>,
) -> <T as Source>::Slice<'_>
unsafe fn slice_unchecked( &self, range: Range<usize>, ) -> <T as Source>::Slice<'_>
forbid_unsafe only.slice::get_unchecked(range). Read more§fn is_boundary(&self, index: usize) -> bool
fn is_boundary(&self, index: usize) -> bool
§fn find_boundary(&self, index: usize) -> usize
fn find_boundary(&self, index: usize) -> usize
&str sources attempts to find the closest char boundary at which source
can be sliced, starting from index. Read more