switch interning to use HashTable rather than HashMap

This commit is contained in:
Jacob Lifshay 2025-04-09 19:30:02 -07:00
parent 36f1b9bbb6
commit 07725ab489
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ

View file

@ -3,7 +3,7 @@
#![allow(clippy::type_complexity)]
use crate::intern::type_map::TypeIdMap;
use bitvec::{ptr::BitPtr, slice::BitSlice, vec::BitVec};
use hashbrown::{hash_map::RawEntryMut, HashMap, HashTable};
use hashbrown::{HashTable, hash_map::DefaultHashBuilder as DefaultBuildHasher};
use serde::{Deserialize, Serialize};
use std::{
any::{Any, TypeId},
@ -17,7 +17,7 @@ use std::{
sync::{Mutex, RwLock},
};
pub mod type_map;
mod type_map;
pub trait LazyInternedTrait<T: ?Sized + Send + Sync + 'static>: Send + Sync + Any {
fn get(&self) -> Interned<T>;
@ -316,8 +316,13 @@ pub trait Intern: Any + Send + Sync {
}
}
struct InternerState<T: ?Sized + 'static + Send + Sync> {
table: HashTable<&'static T>,
hasher: DefaultBuildHasher,
}
pub struct Interner<T: ?Sized + 'static + Send + Sync> {
map: Mutex<HashMap<&'static T, ()>>,
state: Mutex<InternerState<T>>,
}
impl<T: ?Sized + 'static + Send + Sync> Interner<T> {
@ -330,7 +335,10 @@ impl<T: ?Sized + 'static + Send + Sync> Interner<T> {
impl<T: ?Sized + 'static + Send + Sync> Default for Interner<T> {
fn default() -> Self {
Self {
map: Default::default(),
state: Mutex::new(InternerState {
table: HashTable::new(),
hasher: Default::default(),
}),
}
}
}
@ -341,17 +349,16 @@ impl<T: ?Sized + 'static + Send + Sync + Hash + Eq + ToOwned> Interner<T> {
alloc: F,
value: Cow<'_, T>,
) -> Interned<T> {
let mut map = self.map.lock().unwrap();
let hasher = map.hasher().clone();
let hash = hasher.hash_one(&*value);
let inner = match map.raw_entry_mut().from_hash(hash, |k| **k == *value) {
RawEntryMut::Occupied(entry) => *entry.key(),
RawEntryMut::Vacant(entry) => {
*entry
.insert_with_hasher(hash, alloc(value), (), |k| hasher.hash_one(&**k))
.0
}
};
let mut state = self.state.lock().unwrap();
let InternerState { table, hasher } = &mut *state;
let inner = *table
.entry(
hasher.hash_one(&*value),
|k| **k == *value,
|k| hasher.hash_one(&**k),
)
.or_insert_with(|| alloc(value))
.get();
Interned { inner }
}
}
@ -742,7 +749,7 @@ pub trait MemoizeGeneric: 'static + Send + Sync + Hash + Eq + Copy {
fn get_cow(self, input: Self::InputCow<'_>) -> Self::Output {
static TYPE_ID_MAP: TypeIdMap = TypeIdMap::new();
let map: &RwLock<(
hashbrown::hash_map::DefaultHashBuilder,
DefaultBuildHasher,
HashTable<(Self, Self::InputOwned, Self::Output)>,
)> = TYPE_ID_MAP.get_or_insert_default();
fn hash_eq_key<'a, 'b, T: MemoizeGeneric>(