use crate::optimization::LayoutOption;
pub trait HashStrategy: LayoutOption + Copy + Default + 'static {
fn hash(key: usize) -> u64;
}
#[derive(Copy, Clone, Default, Debug)]
pub struct SipHashStrategy;
impl LayoutOption for SipHashStrategy {
const NAME: &'static str = "sip";
}
impl HashStrategy for SipHashStrategy {
fn hash(key: usize) -> u64 {
use std::{
collections::hash_map::DefaultHasher,
hash::{Hash, Hasher},
};
let mut h = DefaultHasher::new();
key.hash(&mut h);
h.finish()
}
}
#[derive(Copy, Clone, Default, Debug)]
pub struct FxHashStrategy;
impl LayoutOption for FxHashStrategy {
const NAME: &'static str = "fxhash";
}
impl HashStrategy for FxHashStrategy {
fn hash(key: usize) -> u64 {
use {
rustc_hash::FxHasher,
std::hash::{Hash, Hasher},
};
let mut h = FxHasher::default();
key.hash(&mut h);
h.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn sip_strategy_name_is_sip() {
assert_eq!(<SipHashStrategy as LayoutOption>::NAME, "sip");
}
#[test]
fn fxhash_strategy_name_is_fxhash() {
assert_eq!(<FxHashStrategy as LayoutOption>::NAME, "fxhash");
}
#[test]
fn sip_strategy_is_deterministic() {
assert_eq!(SipHashStrategy::hash(42), SipHashStrategy::hash(42));
}
#[test]
fn fxhash_strategy_is_deterministic() {
assert_eq!(FxHashStrategy::hash(42), FxHashStrategy::hash(42));
}
#[test]
fn sip_and_fxhash_produce_different_hashes() {
assert_ne!(SipHashStrategy::hash(42), FxHashStrategy::hash(42));
}
}