forked from Orchid/orchid
September-october commit
- manual parser - stl refinements - all language constructs are now Send
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
use std::borrow::Borrow;
|
||||
use std::cell::RefCell;
|
||||
use std::hash::{BuildHasher, Hash};
|
||||
use std::rc::Rc;
|
||||
use std::sync::{RwLock, Arc};
|
||||
|
||||
use hashbrown::HashMap;
|
||||
|
||||
@@ -11,32 +10,32 @@ use super::token::Tok;
|
||||
/// Lasso but much simpler, in part because not much can be known about the
|
||||
/// type.
|
||||
pub struct TypedInterner<T: 'static + Eq + Hash + Clone> {
|
||||
tokens: RefCell<HashMap<Rc<T>, Tok<T>>>,
|
||||
tokens: RwLock<HashMap<Arc<T>, Tok<T>>>,
|
||||
}
|
||||
impl<T: Eq + Hash + Clone> TypedInterner<T> {
|
||||
/// Create a fresh interner instance
|
||||
#[must_use]
|
||||
pub fn new() -> Rc<Self> {
|
||||
Rc::new(Self { tokens: RefCell::new(HashMap::new()) })
|
||||
pub fn new() -> Arc<Self> {
|
||||
Arc::new(Self { tokens: RwLock::new(HashMap::new()) })
|
||||
}
|
||||
|
||||
/// Intern an object, returning a token
|
||||
#[must_use]
|
||||
pub fn i<Q: ?Sized + Eq + Hash + ToOwned<Owned = T>>(
|
||||
self: &Rc<Self>,
|
||||
self: &Arc<Self>,
|
||||
q: &Q,
|
||||
) -> Tok<T>
|
||||
where
|
||||
T: Borrow<Q>,
|
||||
{
|
||||
let mut tokens = self.tokens.borrow_mut();
|
||||
let mut tokens = self.tokens.write().unwrap();
|
||||
let hash = compute_hash(tokens.hasher(), q);
|
||||
let raw_entry = tokens
|
||||
.raw_entry_mut()
|
||||
.from_hash(hash, |k| <T as Borrow<Q>>::borrow(k) == q);
|
||||
let kv = raw_entry.or_insert_with(|| {
|
||||
let keyrc = Rc::new(q.to_owned());
|
||||
let token = Tok::<T>::new(keyrc.clone(), Rc::downgrade(self));
|
||||
let keyrc = Arc::new(q.to_owned());
|
||||
let token = Tok::<T>::new(keyrc.clone(), Arc::downgrade(self));
|
||||
(keyrc, token)
|
||||
});
|
||||
kv.1.clone()
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::any::{Any, TypeId};
|
||||
use std::borrow::Borrow;
|
||||
use std::cell::{RefCell, RefMut};
|
||||
use std::hash::Hash;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use hashbrown::HashMap;
|
||||
|
||||
@@ -13,7 +13,7 @@ use super::token::Tok;
|
||||
/// that implements [ToOwned]. Objects of the same type are stored together in a
|
||||
/// [TypedInterner].
|
||||
pub struct Interner {
|
||||
interners: RefCell<HashMap<TypeId, Rc<dyn Any>>>,
|
||||
interners: RefCell<HashMap<TypeId, Arc<dyn Any + Send + Sync>>>,
|
||||
}
|
||||
impl Interner {
|
||||
/// Create a new interner
|
||||
@@ -24,7 +24,7 @@ impl Interner {
|
||||
#[must_use]
|
||||
pub fn i<Q: ?Sized + Eq + Hash + ToOwned>(&self, q: &Q) -> Tok<Q::Owned>
|
||||
where
|
||||
Q::Owned: 'static + Eq + Hash + Clone + Borrow<Q>,
|
||||
Q::Owned: 'static + Eq + Hash + Clone + Borrow<Q> + Send + Sync,
|
||||
{
|
||||
let mut interners = self.interners.borrow_mut();
|
||||
let interner = get_interner(&mut interners);
|
||||
@@ -44,9 +44,9 @@ impl Default for Interner {
|
||||
|
||||
/// Get or create an interner for a given type.
|
||||
#[must_use]
|
||||
fn get_interner<T: 'static + Eq + Hash + Clone>(
|
||||
interners: &mut RefMut<HashMap<TypeId, Rc<dyn Any>>>,
|
||||
) -> Rc<TypedInterner<T>> {
|
||||
fn get_interner<T: 'static + Eq + Hash + Clone + Send + Sync>(
|
||||
interners: &mut RefMut<HashMap<TypeId, Arc<dyn Any + Send + Sync>>>,
|
||||
) -> Arc<TypedInterner<T>> {
|
||||
let boxed = interners
|
||||
.raw_entry_mut()
|
||||
.from_key(&TypeId::of::<T>())
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::fmt::{Debug, Display};
|
||||
use std::hash::Hash;
|
||||
use std::num::NonZeroUsize;
|
||||
use std::ops::Deref;
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
use super::TypedInterner;
|
||||
|
||||
@@ -13,13 +13,13 @@ use super::TypedInterner;
|
||||
/// currently not enforced.
|
||||
#[derive(Clone)]
|
||||
pub struct Tok<T: Eq + Hash + Clone + 'static> {
|
||||
data: Rc<T>,
|
||||
data: Arc<T>,
|
||||
interner: Weak<TypedInterner<T>>,
|
||||
}
|
||||
impl<T: Eq + Hash + Clone + 'static> Tok<T> {
|
||||
/// Create a new token. Used exclusively by the interner
|
||||
#[must_use]
|
||||
pub(crate) fn new(data: Rc<T>, interner: Weak<TypedInterner<T>>) -> Self {
|
||||
pub(crate) fn new(data: Arc<T>, interner: Weak<TypedInterner<T>>) -> Self {
|
||||
Self { data, interner }
|
||||
}
|
||||
/// Take the ID number out of a token
|
||||
|
||||
Reference in New Issue
Block a user