| 1 | //! A Rust implementation of the [XXHash] algorithm. |
| 2 | //! |
| 3 | //! [XXHash]: https://github.com/Cyan4973/xxHash |
| 4 | //! |
| 5 | //! ### With a fixed seed |
| 6 | //! |
| 7 | //! ```rust |
| 8 | //! use std::hash::BuildHasherDefault; |
| 9 | //! use std::collections::HashMap; |
| 10 | //! use twox_hash::XxHash64; |
| 11 | //! |
| 12 | //! let mut hash: HashMap<_, _, BuildHasherDefault<XxHash64>> = Default::default(); |
| 13 | //! hash.insert(42, "the answer" ); |
| 14 | //! assert_eq!(hash.get(&42), Some(&"the answer" )); |
| 15 | //! ``` |
| 16 | //! |
| 17 | //! ### With a random seed |
| 18 | //! |
| 19 | //! ```rust |
| 20 | //! use std::collections::HashMap; |
| 21 | //! use twox_hash::RandomXxHashBuilder64; |
| 22 | //! |
| 23 | //! let mut hash: HashMap<_, _, RandomXxHashBuilder64> = Default::default(); |
| 24 | //! hash.insert(42, "the answer" ); |
| 25 | //! assert_eq!(hash.get(&42), Some(&"the answer" )); |
| 26 | //! ``` |
| 27 | |
| 28 | #![no_std ] |
| 29 | |
| 30 | extern crate alloc; |
| 31 | |
| 32 | #[cfg (test)] |
| 33 | extern crate std; |
| 34 | |
| 35 | use core::{marker::PhantomData, mem}; |
| 36 | |
| 37 | mod sixty_four; |
| 38 | mod thirty_two; |
| 39 | pub mod xxh3; |
| 40 | |
| 41 | #[cfg (feature = "std" )] |
| 42 | mod std_support; |
| 43 | #[cfg (feature = "std" )] |
| 44 | pub use std_support::sixty_four::RandomXxHashBuilder64; |
| 45 | #[cfg (feature = "std" )] |
| 46 | pub use std_support::thirty_two::RandomXxHashBuilder32; |
| 47 | #[cfg (feature = "std" )] |
| 48 | pub use std_support::xxh3::{ |
| 49 | RandomHashBuilder128 as RandomXxh3HashBuilder128, |
| 50 | RandomHashBuilder64 as RandomXxh3HashBuilder64, |
| 51 | }; |
| 52 | |
| 53 | #[cfg (feature = "digest" )] |
| 54 | mod digest_support; |
| 55 | |
| 56 | #[cfg (feature = "digest_0_9" )] |
| 57 | mod digest_0_9_support; |
| 58 | |
| 59 | #[cfg (feature = "digest_0_10" )] |
| 60 | mod digest_0_10_support; |
| 61 | |
| 62 | pub use crate::sixty_four::XxHash64; |
| 63 | pub use crate::thirty_two::XxHash32; |
| 64 | pub use crate::xxh3::{Hash128 as Xxh3Hash128, Hash64 as Xxh3Hash64}; |
| 65 | |
| 66 | /// A backwards compatibility type alias. Consider directly using |
| 67 | /// `XxHash64` instead. |
| 68 | pub type XxHash = XxHash64; |
| 69 | |
| 70 | #[cfg (feature = "std" )] |
| 71 | /// A backwards compatibility type alias. Consider directly using |
| 72 | /// `RandomXxHashBuilder64` instead. |
| 73 | pub type RandomXxHashBuilder = RandomXxHashBuilder64; |
| 74 | |
| 75 | /// An unaligned buffer with iteration support for `UnalignedItem`. |
| 76 | struct UnalignedBuffer<'a, T> { |
| 77 | buf: &'a [u8], |
| 78 | phantom: PhantomData<T>, |
| 79 | } |
| 80 | |
| 81 | /// Types implementing this trait must be transmutable from a `*const |
| 82 | /// u8` to `*const Self` at any possible alignment. |
| 83 | /// |
| 84 | /// The intent is to use this with only primitive integer types (and |
| 85 | /// tightly-packed arrays of those integers). |
| 86 | #[allow (clippy::missing_safety_doc)] |
| 87 | unsafe trait UnalignedItem {} |
| 88 | |
| 89 | unsafe impl UnalignedItem for [u64; 4] {} |
| 90 | unsafe impl UnalignedItem for [u32; 4] {} |
| 91 | unsafe impl UnalignedItem for u64 {} |
| 92 | unsafe impl UnalignedItem for u32 {} |
| 93 | |
| 94 | impl<'a, T: UnalignedItem> UnalignedBuffer<'a, T> { |
| 95 | #[inline ] |
| 96 | fn new(buf: &'a [u8]) -> Self { |
| 97 | Self { |
| 98 | buf, |
| 99 | phantom: PhantomData, |
| 100 | } |
| 101 | } |
| 102 | |
| 103 | #[inline ] |
| 104 | fn remaining(&self) -> &[u8] { |
| 105 | self.buf |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | impl<'a, T: UnalignedItem> Iterator for UnalignedBuffer<'a, T> { |
| 110 | type Item = T; |
| 111 | |
| 112 | fn next(&mut self) -> Option<Self::Item> { |
| 113 | let size: usize = mem::size_of::<T>(); |
| 114 | self.buf.get(index:size..).map(|remaining: &[u8]| { |
| 115 | // `self.buf` has at least `size` bytes that can be read as `T`. |
| 116 | let result: T = unsafe { (self.buf.as_ptr() as *const T).read_unaligned() }; |
| 117 | self.buf = remaining; |
| 118 | result |
| 119 | }) |
| 120 | } |
| 121 | } |
| 122 | |