hash32/lib.rs
1//! 32-bit hashing algorithms
2//!
3//! # Why?
4//!
5//! Because 32-bit architectures are a thing (e.g. ARM Cortex-M) and you don't want your hashing
6//! function to pull in a bunch of slow 64-bit compiler intrinsics (software implementations of
7//! 64-bit operations).
8//!
9//! # Relationship to `core::hash`
10//!
11//! This crate extends [`core::hash`] with a 32-bit version of `Hasher`, which extends
12//! `core::hash::Hasher`. It requires that the hasher only performs 32-bit operations when computing
13//! the hash, and adds [`finish32`] to get the hasher's result as a `u32`. The standard `finish`
14//! method should just zero-extend this result.
15//!
16//! Since it extends `core::hash::Hasher`, `Hasher` can be used with any type which implements the
17//! standard `Hash` trait.
18//!
19//! This crate also adds a version of `BuildHasherDefault` with a const constructor, to work around
20//! the `core` version's lack of one.
21//!
22//! [`core::hash`]: https://doc.rust-lang.org/std/hash/index.html
23//! [`finish32`]: crate::Hasher::finish32
24//!
25//! # Hashers
26//!
27//! This crate provides implementations of the following 32-bit hashing algorithms:
28//!
29//! - [Fowler-Noll-Vo](struct.FnvHasher.html)
30//! - [MurmurHash3](struct.Murmur3Hasher.html)
31//!
32//! # Generic code
33//!
34//! In generic code, the trait bound `H: core::hash::Hasher` accepts *both* 64-bit hashers like
35//! `std::collections::hash_map::DefaultHasher`; and 32-bit hashers like the ones defined in this
36//! crate (`hash32::FnvHasher` and `hash32::Murmur3Hasher`)
37//!
38//! The trait bound `H: hash32::Hasher` is *more* restrictive as it only accepts 32-bit hashers.
39//!
40//! The `BuildHasherDefault<H>` type implements the `core::hash::BuildHasher` trait so it can
41//! construct both 32-bit and 64-bit hashers. To constrain the type to only produce 32-bit hasher
42//! you can add the trait bound `H::Hasher: hash32::Hasher`
43//!
44//! # MSRV
45//!
46//! This crate is guaranteed to compile on latest stable Rust. It *might* compile on older
47//! versions but that may change in any new patch release.
48
49#![deny(missing_docs)]
50#![deny(warnings)]
51#![no_std]
52
53extern crate byteorder;
54
55use core::fmt;
56use core::hash::BuildHasher;
57use core::marker::PhantomData;
58
59pub use fnv::Hasher as FnvHasher;
60pub use murmur3::Hasher as Murmur3Hasher;
61
62mod fnv;
63mod murmur3;
64
65/// A copy of [`core::hash::BuildHasherDefault`][0], but with a const constructor.
66///
67/// This will eventually be deprecated once the version in `core` becomes const-constructible
68/// (presumably using `const Default`).
69///
70/// [0]: https://doc.rust-lang.org/core/hash/struct.BuildHasherDefault.html
71pub struct BuildHasherDefault<H> {
72 _marker: PhantomData<H>,
73}
74
75impl<H> Default for BuildHasherDefault<H> {
76 fn default() -> Self {
77 BuildHasherDefault {
78 _marker: PhantomData,
79 }
80 }
81}
82
83impl<H> Clone for BuildHasherDefault<H> {
84 fn clone(&self) -> Self {
85 BuildHasherDefault::default()
86 }
87}
88
89impl<H> PartialEq for BuildHasherDefault<H> {
90 fn eq(&self, _other: &BuildHasherDefault<H>) -> bool {
91 true
92 }
93}
94
95impl<H> Eq for BuildHasherDefault<H> {}
96
97impl<H> fmt::Debug for BuildHasherDefault<H> {
98 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99 f.pad("BuildHasherDefault")
100 }
101}
102
103impl<H> BuildHasherDefault<H> {
104 /// `const` constructor
105 pub const fn new() -> Self {
106 BuildHasherDefault {
107 _marker: PhantomData,
108 }
109 }
110}
111
112impl<H> BuildHasher for BuildHasherDefault<H>
113where
114 H: Default + core::hash::Hasher,
115{
116 type Hasher = H;
117
118 fn build_hasher(&self) -> Self::Hasher {
119 H::default()
120 }
121}
122
123/// An extension of [core::hash::Hasher][0] for hashers which use 32 bits.
124///
125/// For hashers which implement this trait, the standard `finish` method should just return a
126/// zero-extended version of the result of `finish32`.
127///
128/// [0]: https://doc.rust-lang.org/core/hash/trait.Hasher.html
129///
130/// # Contract
131///
132/// Implementers of this trait must *not* perform any 64-bit (or 128-bit) operation while computing
133/// the hash.
134pub trait Hasher: core::hash::Hasher {
135 /// The equivalent of [`core::hash::Hasher.finish`][0] for 32-bit hashers.
136 ///
137 /// This returns the hash directly; `finish` zero-extends it to 64 bits for compatibility.
138 ///
139 /// [0]: https://doc.rust-lang.org/std/hash/trait.Hasher.html#tymethod.finish
140 fn finish32(&self) -> u32;
141}