mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 16:21:33 +11:00
Change hash mixing and add distance_histogram method
This commit is contained in:
parent
1fa4d8e970
commit
65dd1341e5
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
use alloc::alloc::Global;
|
use alloc::{alloc::Global, vec::Vec};
|
||||||
use core::{
|
use core::{
|
||||||
alloc::Allocator,
|
alloc::Allocator,
|
||||||
borrow::Borrow,
|
borrow::Borrow,
|
||||||
|
@ -174,6 +174,12 @@ impl<K, V> HashMap<K, V> {
|
||||||
pub fn with_capacity(capacity: usize) -> Self {
|
pub fn with_capacity(capacity: usize) -> Self {
|
||||||
Self::with_capacity_in(capacity, Global)
|
Self::with_capacity_in(capacity, Global)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[must_use]
|
||||||
|
pub fn distance_histogram(&self) -> (Vec<usize>, usize) {
|
||||||
|
self.nodes.distance_histogram()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K, V, ALLOCATOR: ClonableAllocator> HashMap<K, V, ALLOCATOR> {
|
impl<K, V, ALLOCATOR: ClonableAllocator> HashMap<K, V, ALLOCATOR> {
|
||||||
|
@ -898,7 +904,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
const fn number_before_resize(capacity: usize) -> usize {
|
const fn number_before_resize(capacity: usize) -> usize {
|
||||||
capacity * 85 / 100
|
capacity * 60 / 100
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Clone, Copy, PartialEq, Eq)]
|
#[derive(Default, Clone, Copy, PartialEq, Eq)]
|
||||||
|
@ -915,12 +921,18 @@ impl From<usize> for HashType {
|
||||||
impl HashType {
|
impl HashType {
|
||||||
// 32 bit mix function from here: https://gist.github.com/badboy/6267743
|
// 32 bit mix function from here: https://gist.github.com/badboy/6267743
|
||||||
fn bit_mix(key: u32) -> Self {
|
fn bit_mix(key: u32) -> Self {
|
||||||
let key = !key.wrapping_add(key << 15);
|
use core::num::Wrapping;
|
||||||
let key = key ^ key.rotate_right(12);
|
|
||||||
let key = key.wrapping_add(key << 2);
|
let key = Wrapping(key);
|
||||||
let key = key ^ key.rotate_right(4);
|
|
||||||
let key = key.wrapping_add(key << 3).wrapping_add(key << 11);
|
let key = (key + Wrapping(0x7ed55d16u32)) + (key << 12);
|
||||||
Self(key ^ key.rotate_right(16))
|
let key = (key ^ Wrapping(0xc761c23c)) ^ (key >> 19);
|
||||||
|
let key = (key + Wrapping(0x165667b1)) + (key << 5);
|
||||||
|
let key = (key + Wrapping(0xd3a2646c)) ^ (key << 9);
|
||||||
|
let key = (key + Wrapping(0xfd7046c5)) + (key << 3);
|
||||||
|
let key = (key ^ Wrapping(0xb55a4f09)) ^ (key >> 16);
|
||||||
|
|
||||||
|
Self(key.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fast_mod(self, len: usize) -> usize {
|
pub(crate) fn fast_mod(self, len: usize) -> usize {
|
||||||
|
@ -1085,9 +1097,9 @@ mod test {
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
let mut rng = rand::rngs::SmallRng::seed_from_u64(20);
|
let mut rng = rand::rngs::SmallRng::seed_from_u64(20);
|
||||||
|
|
||||||
let mut answers: [Option<i32>; 128] = [None; 128];
|
let mut answers: [Option<i32>; 512] = [None; 512];
|
||||||
|
|
||||||
for _ in 0..5_000 {
|
for _ in 0..15_000 {
|
||||||
let command = rng.next_i32().rem_euclid(2);
|
let command = rng.next_i32().rem_euclid(2);
|
||||||
let key = rng.next_i32().rem_euclid(answers.len().try_into().unwrap());
|
let key = rng.next_i32().rem_euclid(answers.len().try_into().unwrap());
|
||||||
let value = rng.next_i32();
|
let value = rng.next_i32();
|
||||||
|
|
|
@ -194,4 +194,20 @@ impl<K, V, ALLOCATOR: ClonableAllocator> NodeStorage<K, V, ALLOCATOR> {
|
||||||
pub(crate) unsafe fn node_at_unchecked_mut(&mut self, at: usize) -> &mut Node<K, V> {
|
pub(crate) unsafe fn node_at_unchecked_mut(&mut self, at: usize) -> &mut Node<K, V> {
|
||||||
self.nodes.get_unchecked_mut(at)
|
self.nodes.get_unchecked_mut(at)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn distance_histogram(&self) -> (Vec<usize>, usize) {
|
||||||
|
let mut ret = Vec::new();
|
||||||
|
|
||||||
|
for node in self.nodes.iter() {
|
||||||
|
let distance = node.distance();
|
||||||
|
|
||||||
|
if distance >= 0 {
|
||||||
|
let distance = distance as usize;
|
||||||
|
ret.resize(ret.len().max(distance + 1), 0);
|
||||||
|
ret[distance] += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(ret, self.max_distance_to_initial_bucket as usize)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue