#![feature(core_intrinsics)]
extern crate const_random;
extern crate arrayref;
#[macro_use]
mod convert;
mod fallback_hash;
#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes"))]
mod aes_hash;
#[cfg(test)]
mod hash_quality_test;
use const_random::const_random;
use std::collections::HashMap;
use std::hash::{BuildHasher};
#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes"))]
pub use crate::aes_hash::AHasher;
#[cfg(not(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes")))]
pub use crate::fallback_hash::AHasher;
pub type AHashMap<K, V> = HashMap<K, V, ABuildHasher>;
const DEFAULT_KEYS: [u64; 2] = [const_random!(u64), const_random!(u64)];
impl Default for AHasher {
#[inline]
fn default() -> AHasher {
#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes"))]
return AHasher::new_with_key(DEFAULT_KEYS, 0);
#[cfg(not(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes")))]
return AHasher::new_with_key(DEFAULT_KEYS[0], 0);
}
}
pub struct ABuildHasher{}
impl ABuildHasher {
#[inline]
pub fn new() -> ABuildHasher {
ABuildHasher{}
}
}
impl Default for ABuildHasher {
#[inline]
fn default() -> ABuildHasher {
ABuildHasher{}
}
}
impl BuildHasher for ABuildHasher {
type Hasher = AHasher;
#[inline]
fn build_hasher(&self) -> AHasher {
let mem_loc = self as *const _ as usize;
#[cfg(not(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes")))]
return AHasher::new_with_key(DEFAULT_KEYS[0], mem_loc as u64);
#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes"))]
return AHasher::new_with_key(DEFAULT_KEYS, mem_loc);
}
}
#[inline(never)]
#[no_mangle]
fn hash_test_final(input: usize) -> u64 {
use std::hash::{Hasher};
let builder = ABuildHasher::default();
let mut hasher = builder.build_hasher();
hasher.write_usize(input);
hasher.finish()
}
#[cfg(test)]
mod test {
use std::hash::BuildHasherDefault;
use crate::convert::Convert;
use crate::*;
#[test]
fn test_default_builder() {
let mut map = HashMap::<u32, u64, BuildHasherDefault<AHasher>>::default();
map.insert(1, 3);
}
#[test]
fn test_builder() {
let mut map = HashMap::<u32, u64, ABuildHasher>::default();
map.insert(1, 3);
}
#[test]
fn test_conversion() {
let input: &[u8] = "dddddddd".as_bytes();
let bytes: u64 = as_array!(input, 8).convert();
assert_eq!(bytes, 0x6464646464646464);
}
}