Skip to content

Commit

Permalink
Merge pull request #1 from jdonszelmann/ord
Browse files Browse the repository at this point in the history
Implement Ord and PartialOrd when T does
  • Loading branch information
pali6 authored Feb 14, 2024
2 parents 2d8c7b7 + 85c67c5 commit 891c55b
Showing 1 changed file with 19 additions and 6 deletions.
25 changes: 19 additions & 6 deletions src/cachedhash.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::borrow::{Borrow, BorrowMut};
use std::cmp::Ordering;
use std::collections::hash_map::DefaultHasher;
use std::hash::{BuildHasher, BuildHasherDefault, Hash, Hasher};
use std::num::NonZeroU64;
Expand Down Expand Up @@ -38,25 +39,25 @@ use crate::atomic::AtomicOptionNonZeroU64;
///
/// You can run `cargo bench` to see some simple naive benchmarks comparing
/// a plain `HashSet` with a `HashSet` that stores values wrapped in [`CachedHash`].
///
///
/// # Details
///
///
/// Whenever the hash is requested if it is not already computed it is computed
/// using the hasher provided by the `BH` [`BuildHasher`] and stored as an "internal
/// hash". Note that this is not the same as the hash returned by the [`Hash`] implementation.
/// That implementation feeds the internal hash into the hasher provided to the `hash`
/// function. This means that the resulting hash is the hash of the hash of the stored
/// value.
///
/// However, there is one more issue. If we wanted to represent both the full
///
/// However, there is one more issue. If we wanted to represent both the full
/// range of hash values and the possibility of the hash not being computed yet,
/// we would need 65 bits. In order to save space we need to reserve one value
/// we would need 65 bits. In order to save space we need to reserve one value
/// as a sentinel (this also lets us work with the stored "maybe-hash" atomically).
/// This means that we need to artificially create a hash collision. Current
/// implementation does this by changing the "internal hash" from 0 to 1 if it ends
/// up being zero. This is generally not an issue. However, if you are using a custom hasher
/// this might affect you.
///
///
/// This behaviour is not guaranteed and may change in the future. If this
/// behaviour does not fit for your use case please open an issue.
#[derive(Debug)]
Expand All @@ -66,6 +67,18 @@ pub struct CachedHash<T: Eq + Hash, BH: BuildHasher = BuildHasherDefault<Default
build_hasher: BH,
}

impl<T: Eq + Hash + PartialOrd> PartialOrd for CachedHash<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.value.partial_cmp(&other.value)
}
}

impl<T: Eq + Hash + Ord> Ord for CachedHash<T> {
fn cmp(&self, other: &Self) -> Ordering {
self.value.cmp(&other.value)
}
}

impl<T: Eq + Hash> CachedHash<T> {
/// Creates a new [`CachedHash`] with the given value using [`DefaultHasher`].
///
Expand Down

0 comments on commit 891c55b

Please sign in to comment.