forked from libre-chip/fayalite
switch interning to use HashTable rather than HashMap
This commit is contained in:
parent
36f1b9bbb6
commit
07725ab489
1 changed files with 23 additions and 16 deletions
|
@ -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>(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue