metrics_util/common.rs
1use std::fmt::Debug;
2use std::hash::{Hash, Hasher};
3
4use metrics::{Key, KeyHasher};
5
6/// A type that can hash itself.
7///
8/// In high-performance use cases, an object can pre-hash itself, or memoize its hash value, when it
9/// is anticipated that an object will be hashed multiple times. Rather than the standard library
10/// `Hash` trait, `Hashable` exposes an interface that forces objects to hash themselves entirely,
11/// providing only the resulting 8-byte hash.
12///
13/// As a key may sometimes need to be rehashed, we need to ensure that the same hashing algorithm
14/// used to pre-generate the hash for this value is used when rehashing it. All implementors must
15/// define the hashing algorithm used by specifying the `Hasher` associated type.
16///
17/// A default implementation, [`DefaultHashable`], is provided that utilizes the same hashing
18/// algorithm that [`Key`][metrics::Key] uses, which is high-performance. This type can be used to
19/// satisfy `Hashable` so long as the type itself is already [`Hash`].
20pub trait Hashable: Hash {
21 /// The hasher implementation used internally.
22 type Hasher: Hasher + Default;
23
24 /// Generate the hash of this object.
25 fn hashable(&self) -> u64 {
26 let mut hasher = Self::Hasher::default();
27 self.hash(&mut hasher);
28 hasher.finish()
29 }
30}
31
32impl Hashable for Key {
33 type Hasher = KeyHasher;
34
35 fn hashable(&self) -> u64 {
36 self.get_hash()
37 }
38}
39
40/// A wrapper type that provides `Hashable` for any type that is `Hash`.
41///
42/// As part of using [`Registry`][crate::registry::Registry], the chosen key type must implement
43/// [`Hashable`]. For use cases where performance is not the utmost concern and there is no desire
44/// to deal with pre-hashing keys, `DefaultHashable` can be used to wrap the key type and provide
45/// the implementation of `Hashable` so long as `H` itself is `Hash`.
46#[derive(Debug, Hash, Clone, PartialEq, Eq, PartialOrd, Ord)]
47pub struct DefaultHashable<H: Hash>(pub H);
48
49impl<H: Hash> Hashable for DefaultHashable<H> {
50 type Hasher = KeyHasher;
51
52 fn hashable(&self) -> u64 {
53 let mut hasher = KeyHasher::default();
54 self.hash(&mut hasher);
55 hasher.finish()
56 }
57}