seedable_hash/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#![doc = include_str!("../README.md")]

mod map;
pub use map::{map16_to_16, map32_to_32, map64_to_32, map64_to_64, map_usize};

use std::hash::{BuildHasher, Hash, Hasher};

#[cfg(all(not(feature = "fnv"), not(feature = "sip13"), not(feature = "wyhash")))]
use std::{hash::BuildHasherDefault, collections::hash_map::DefaultHasher};

#[cfg(feature = "sip13")]
#[allow(deprecated)]
use std::hash::SipHasher13;

/// Family of hash functions that allows the creation of
/// [`Hasher`] instances initialized with a given seed.
pub trait BuildSeededHasher {
    type Hasher: Hasher;

    /// Creates a new hasher initialized with the given `seed`.
    fn build_hasher(&self, seed: u32) -> Self::Hasher;

    /// Calculates the hash of a single value `x`, using given `seed`.
    #[inline]
    fn hash_one<T: Hash>(&self, x: T, seed: u32) -> u64 {
        let mut h = self.build_hasher(seed);
        x.hash(&mut h);
        h.finish()
    }
}

/// [`BuildSeededHasher`] that uses standard [`BuildHasher`].
#[derive(Default, Copy, Clone)]
pub struct Seedable<BH: BuildHasher>(BH);

impl<BH: BuildHasher> BuildSeededHasher for Seedable<BH> {
    type Hasher = BH::Hasher;

    #[inline]
    fn build_hasher(&self, seed: u32) -> Self::Hasher {
        let mut result = self.0.build_hasher();
        result.write_u32(seed);
        result
    }
}

/// [`BuildSeededHasher`] that uses [`std::hash::SipHasher13`].
#[cfg(feature = "sip13")]
#[derive(Default, Copy, Clone)]
pub struct BuildSip13;

#[cfg(feature = "sip13")]
#[allow(deprecated)]
impl BuildSeededHasher for BuildSip13 {
    type Hasher = SipHasher13;

    #[inline] fn build_hasher(&self, seed: u32) -> Self::Hasher {
        Self::Hasher::new_with_keys(seed as u64, seed as u64)
    }
}

/// [`BuildSeededHasher`] that uses `wyhash` crate.
#[cfg(feature = "wyhash")]
#[derive(Default, Copy, Clone)]
pub struct BuildWyHash;

#[cfg(feature = "wyhash")]
impl BuildSeededHasher for BuildWyHash {
    type Hasher = wyhash::WyHash;

    #[inline] fn build_hasher(&self, seed: u32) -> Self::Hasher {
        Self::Hasher::with_seed(seed as u64)
    }
}

/*#[cfg(feature = "wyhash_git")]
#[derive(Default, Copy, Clone)]
pub struct BuildWyHashGit;

#[cfg(feature = "wyhash_git")]
impl BuildSeededHasher for BuildWyHashGit {
    type Hasher = wyhash_git::WyHash;

    #[inline] fn build_hasher(&self, mut seed: u32) -> Self::Hasher {
        Self::Hasher::new(seed as u64, [0xa076_1d64_78bd_642f, 0xe703_7ed1_a0b4_28db, 0x8ebc_6af0_9c88_c6e3, 0x5899_65cc_7537_4cc3])
    }
}*/

/// [`BuildSeededHasher`] that uses `fnv` crate.
#[cfg(feature = "fnv")]
impl BuildSeededHasher for fnv::FnvBuildHasher {
    type Hasher = fnv::FnvHasher;

    #[inline] fn build_hasher(&self, seed: u32) -> Self::Hasher {
        Self::Hasher::with_key(seed as u64)
    }
}

/// [`BuildSeededHasher`] that uses `gxhash` crate.
#[cfg(feature = "gxhash")]
impl BuildSeededHasher for gxhash::GxBuildHasher {
    type Hasher = gxhash::GxHasher;

    #[inline] fn build_hasher(&self, seed: u32) -> Self::Hasher {
        Self::Hasher::with_seed(seed)
    }
}

/// [`BuildSeededHasher`] that uses `rapidhash::RapidBuildHasher`.
#[cfg(feature = "rapidhash")]
impl BuildSeededHasher for rapidhash::RapidBuildHasher {
    type Hasher = rapidhash::RapidHasher;

    #[inline] fn build_hasher(&self, seed: u32) -> Self::Hasher {
        Self::Hasher::new(seed as u64)
    }
}

/// [`BuildSeededHasher`] that uses `rapidhash::RapidInlineBuildHasher`.
#[cfg(feature = "rapidhash")]
impl BuildSeededHasher for rapidhash::RapidInlineBuildHasher {
    type Hasher = rapidhash::RapidInlineHasher;

    #[inline] fn build_hasher(&self, seed: u32) -> Self::Hasher {
        Self::Hasher::new(seed as u64)
    }
}

/// The default [`BuildSeededHasher`].
#[cfg(feature = "wyhash")]
pub type BuildDefaultSeededHasher = BuildWyHash;

/// The default [`BuildSeededHasher`].
#[cfg(all(feature = "sip13", not(feature = "wyhash")))]
pub type BuildDefaultSeededHasher = BuildSip13;

/// The default [`BuildSeededHasher`].
#[cfg(all(feature = "fnv", not(feature = "sip13"), not(feature = "wyhash")))]
pub type BuildDefaultSeededHasher = fnv::FnvBuildHasher;

/// The default [`BuildSeededHasher`].
#[cfg(all(not(feature = "fnv"), not(feature = "sip13"), not(feature = "wyhash")))]
pub type BuildDefaultSeededHasher = Seedable<BuildHasherDefault<DefaultHasher>>;