Optimized PlainHasher hashing

This commit is contained in:
debris 2017-08-17 14:59:43 +02:00
parent fefc756870
commit 697d17ae9b
2 changed files with 21 additions and 10 deletions

View File

@ -45,14 +45,14 @@ fn random_bytes(min_count: usize, diff_count: usize, seed: &mut H256) -> Vec<u8>
assert!(min_count + diff_count <= 32); assert!(min_count + diff_count <= 32);
*seed = seed.sha3(); *seed = seed.sha3();
let r = min_count + (seed[31] as usize % (diff_count + 1)); let r = min_count + (seed[31] as usize % (diff_count + 1));
seed[0..r].into_vec() seed[0..r].to_vec()
} }
fn random_value(seed: &mut H256) -> Bytes { fn random_value(seed: &mut H256) -> Bytes {
*seed = seed.sha3(); *seed = seed.sha3();
match seed[0] % 2 { match seed[0] % 2 {
1 => vec![seed[31];1], 1 => vec![seed[31];1],
_ => seed.into_vec(), _ => seed.to_vec(),
} }
} }

View File

@ -449,33 +449,44 @@ known_heap_size!(0, H32, H64, H128, H160, H256, H264, H512, H520, H1024, H2048);
/// Hasher that just takes 8 bytes of the provided value. /// Hasher that just takes 8 bytes of the provided value.
/// May only be used for keys which are 32 bytes. /// May only be used for keys which are 32 bytes.
pub struct PlainHasher { pub struct PlainHasher {
prefix: [u8; 8], prefix: u64,
_marker: [u64; 0], // for alignment
} }
impl Default for PlainHasher { impl Default for PlainHasher {
#[inline] #[inline]
fn default() -> PlainHasher { fn default() -> PlainHasher {
PlainHasher { PlainHasher {
prefix: [0; 8], prefix: 0,
_marker: [0; 0],
} }
} }
} }
impl PlainHasher {
#[inline]
fn mut_prefix(&mut self) -> &mut [u8; 8] {
unsafe { ::std::mem::transmute(&mut self.prefix) }
}
}
impl Hasher for PlainHasher { impl Hasher for PlainHasher {
#[inline] #[inline]
fn finish(&self) -> u64 { fn finish(&self) -> u64 {
unsafe { ::std::mem::transmute(self.prefix) } 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);
for quarter in bytes.chunks(8) { unsafe {
for (x, y) in self.prefix.iter_mut().zip(quarter) { let mut bytes_ptr = bytes.as_ptr();
*x ^= *y let mut prefix_ptr = self.mut_prefix().as_mut_ptr();
for _ in 0..8 {
*prefix_ptr ^= *bytes_ptr ^ *bytes_ptr.offset(8) ^ *bytes_ptr.offset(16) ^ *bytes_ptr.offset(24);
bytes_ptr = bytes_ptr.offset(1);
prefix_ptr = prefix_ptr.offset(1);
} }
} }
} }