move Interner into new mod interner
This commit is contained in:
parent
26b0dc3fd8
commit
39810043ea
2 changed files with 91 additions and 76 deletions
|
|
@ -16,9 +16,10 @@ use std::{
|
|||
marker::PhantomData,
|
||||
ops::Deref,
|
||||
path::{Path, PathBuf},
|
||||
sync::{Mutex, RwLock},
|
||||
sync::RwLock,
|
||||
};
|
||||
|
||||
mod interner;
|
||||
mod type_map;
|
||||
|
||||
pub trait LazyInternedTrait<T: ?Sized + Send + Sync + 'static>: Send + Sync + Any {
|
||||
|
|
@ -593,78 +594,6 @@ impl<T: ?Sized + 'static + Send + Sync + ToOwned> From<Interned<T>> for Cow<'_,
|
|||
}
|
||||
}
|
||||
|
||||
struct InternerState<T: ?Sized + 'static + Send + Sync> {
|
||||
table: HashTable<&'static T>,
|
||||
hasher: DefaultBuildHasher,
|
||||
}
|
||||
|
||||
pub(crate) struct Interner<T: ?Sized + 'static + Send + Sync> {
|
||||
state: Mutex<InternerState<T>>,
|
||||
}
|
||||
|
||||
impl<T: ?Sized + 'static + Send + Sync> Interner<T> {
|
||||
fn get() -> &'static Interner<T> {
|
||||
static TYPE_ID_MAP: TypeIdMap = TypeIdMap::new();
|
||||
thread_local! {
|
||||
static TYPE_ID_MAP_CACHE: TypeIdMap = const { TypeIdMap::new() };
|
||||
}
|
||||
TYPE_ID_MAP_CACHE.with(|cache| {
|
||||
cache.get_or_insert_with(|| {
|
||||
TYPE_ID_MAP.get_or_insert_with(|| Box::leak(Default::default()))
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized + 'static + Send + Sync> Default for Interner<T> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
state: Mutex::new(InternerState {
|
||||
table: HashTable::new(),
|
||||
hasher: Default::default(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized + 'static + Send + Sync + Hash + Eq + ToOwned> Interner<T> {
|
||||
fn intern<F: FnOnce(Cow<'_, T>) -> &'static T>(
|
||||
&self,
|
||||
alloc: F,
|
||||
value: Cow<'_, T>,
|
||||
) -> Interned<T> {
|
||||
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 }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone + 'static + Send + Sync + Hash + Eq> Interner<T> {
|
||||
fn intern_sized(&self, value: Cow<'_, T>) -> Interned<T> {
|
||||
self.intern(|value| Box::leak(Box::new(value.into_owned())), value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone + 'static + Send + Sync + Hash + Eq> Interner<[T]> {
|
||||
fn intern_slice(&self, value: Cow<'_, [T]>) -> Interned<[T]> {
|
||||
self.intern(|value| value.into_owned().leak(), value)
|
||||
}
|
||||
}
|
||||
|
||||
impl Interner<BitSlice> {
|
||||
fn intern_bit_slice(&self, value: Cow<'_, BitSlice>) -> Interned<BitSlice> {
|
||||
self.intern(|value| value.into_owned().leak(), value)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Interned<T: ?Sized + 'static + Send + Sync> {
|
||||
inner: &'static T,
|
||||
}
|
||||
|
|
@ -984,7 +913,7 @@ impl<T: Clone + Send + Sync + 'static + Hash + Eq> Intern for T {
|
|||
where
|
||||
Self: ToOwned,
|
||||
{
|
||||
Interner::get().intern_sized(this)
|
||||
interner::Interner::get().intern_sized(this)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1004,7 +933,7 @@ impl<T: Clone + Send + Sync + 'static + Hash + Eq> Intern for [T] {
|
|||
where
|
||||
Self: ToOwned,
|
||||
{
|
||||
Interner::get().intern_slice(this)
|
||||
interner::Interner::get().intern_slice(this)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1024,7 +953,7 @@ impl Intern for BitSlice {
|
|||
where
|
||||
Self: ToOwned,
|
||||
{
|
||||
Interner::get().intern_bit_slice(this)
|
||||
interner::Interner::get().intern_bit_slice(this)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
86
crates/fayalite/src/intern/interner.rs
Normal file
86
crates/fayalite/src/intern/interner.rs
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
// See Notices.txt for copyright information
|
||||
|
||||
use crate::{
|
||||
intern::{Interned, type_map::TypeIdMap},
|
||||
util::DefaultBuildHasher,
|
||||
};
|
||||
use bitvec::slice::BitSlice;
|
||||
use hashbrown::HashTable;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
hash::{BuildHasher, Hash},
|
||||
sync::Mutex,
|
||||
};
|
||||
|
||||
struct InternerState<T: ?Sized + 'static + Send + Sync> {
|
||||
table: HashTable<&'static T>,
|
||||
hasher: DefaultBuildHasher,
|
||||
}
|
||||
|
||||
pub(crate) struct Interner<T: ?Sized + 'static + Send + Sync> {
|
||||
state: Mutex<InternerState<T>>,
|
||||
}
|
||||
|
||||
impl<T: ?Sized + 'static + Send + Sync> Interner<T> {
|
||||
pub(crate) fn get() -> &'static Interner<T> {
|
||||
static TYPE_ID_MAP: TypeIdMap = TypeIdMap::new();
|
||||
thread_local! {
|
||||
static TYPE_ID_MAP_CACHE: TypeIdMap = const { TypeIdMap::new() };
|
||||
}
|
||||
TYPE_ID_MAP_CACHE.with(|cache| {
|
||||
cache.get_or_insert_with(|| {
|
||||
TYPE_ID_MAP.get_or_insert_with(|| Box::leak(Default::default()))
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized + 'static + Send + Sync> Default for Interner<T> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
state: Mutex::new(InternerState {
|
||||
table: HashTable::new(),
|
||||
hasher: Default::default(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized + 'static + Send + Sync + Hash + Eq + ToOwned> Interner<T> {
|
||||
fn intern<F: FnOnce(Cow<'_, T>) -> &'static T>(
|
||||
&self,
|
||||
alloc: F,
|
||||
value: Cow<'_, T>,
|
||||
) -> Interned<T> {
|
||||
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 }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone + 'static + Send + Sync + Hash + Eq> Interner<T> {
|
||||
pub(crate) fn intern_sized(&self, value: Cow<'_, T>) -> Interned<T> {
|
||||
self.intern(|value| Box::leak(Box::new(value.into_owned())), value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone + 'static + Send + Sync + Hash + Eq> Interner<[T]> {
|
||||
pub(crate) fn intern_slice(&self, value: Cow<'_, [T]>) -> Interned<[T]> {
|
||||
self.intern(|value| value.into_owned().leak(), value)
|
||||
}
|
||||
}
|
||||
|
||||
impl Interner<BitSlice> {
|
||||
pub(crate) fn intern_bit_slice(&self, value: Cow<'_, BitSlice>) -> Interned<BitSlice> {
|
||||
self.intern(|value| value.into_owned().leak(), value)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue