protect unsafety in plainhasher; do more hashing (#1841)
This commit is contained in:
parent
8702a29e6f
commit
b20833154e
@ -543,27 +543,37 @@ impl_hash!(H2048, 256);
|
|||||||
// Specialized HashMap and HashSet
|
// Specialized HashMap and HashSet
|
||||||
|
|
||||||
/// Hasher that just takes 8 bytes of the provided value.
|
/// Hasher that just takes 8 bytes of the provided value.
|
||||||
pub struct PlainHasher(u64);
|
/// May only be used for keys which are 32 bytes.
|
||||||
|
pub struct PlainHasher {
|
||||||
|
prefix: [u8; 8],
|
||||||
|
_marker: [u64; 0], // for alignment
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for PlainHasher {
|
impl Default for PlainHasher {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default() -> PlainHasher {
|
fn default() -> PlainHasher {
|
||||||
PlainHasher(0)
|
PlainHasher {
|
||||||
|
prefix: [0; 8],
|
||||||
|
_marker: [0; 0],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hasher for PlainHasher {
|
impl Hasher for PlainHasher {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn finish(&self) -> u64 {
|
fn finish(&self) -> u64 {
|
||||||
self.0
|
unsafe { ::std::mem::transmute(self.prefix) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write(&mut self, bytes: &[u8]) {
|
fn write(&mut self, bytes: &[u8]) {
|
||||||
debug_assert!(bytes.len() == 32);
|
debug_assert!(bytes.len() == 32);
|
||||||
let mut prefix = [0u8; 8];
|
|
||||||
prefix.clone_from_slice(&bytes[0..8]);
|
for quarter in bytes.chunks(8) {
|
||||||
self.0 = unsafe { ::std::mem::transmute(prefix) };
|
for (x, y) in self.prefix.iter_mut().zip(quarter) {
|
||||||
|
*x ^= *y
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -578,6 +588,12 @@ mod tests {
|
|||||||
use bigint::uint::*;
|
use bigint::uint::*;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn hasher_alignment() {
|
||||||
|
use std::mem::align_of;
|
||||||
|
assert_eq!(align_of::<u64>(), align_of::<PlainHasher>());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg_attr(feature="dev", allow(eq_op))]
|
#[cfg_attr(feature="dev", allow(eq_op))]
|
||||||
fn hash() {
|
fn hash() {
|
||||||
|
Loading…
Reference in New Issue
Block a user