intern_all/
typed_interner.rs1use std::borrow::Borrow;
2use std::hash::{BuildHasher, Hash};
3use std::sync::{Arc, RwLock};
4
5use hashbrown::HashMap;
6
7use super::token::{Tok, WeakTok};
8use crate::token::Internable;
9
10pub struct TypedInterner<T: Internable> {
15 tokens: RwLock<HashMap<Arc<T>, WeakTok<T>>>,
16}
17impl<T: Internable> TypedInterner<T> {
18 #[must_use]
20 pub fn new() -> Arc<Self> { Arc::new(Self { tokens: RwLock::new(HashMap::new()) }) }
21
22 pub fn size(self: &Arc<Self>) -> usize { self.tokens.read().unwrap().len() }
24
25 pub fn sweep(&self) -> usize {
27 (self.tokens.write().unwrap()).extract_if(|_, v| v.upgrade().is_none()).count()
28 }
29
30 #[must_use]
32 pub fn i<Q>(self: &Arc<Self>, q: &Q) -> Tok<T>
33 where
34 Q: ?Sized + Eq + Hash + ToOwned<Owned = T>,
35 T: Borrow<Q>,
36 {
37 let mut tokens = self.tokens.write().unwrap();
38 let hash = tokens.hasher().hash_one(q);
39 let mut ret: Option<Tok<T>> = None;
40 tokens
41 .raw_entry_mut()
42 .from_hash(hash, |k| <T as Borrow<Q>>::borrow(k) == q)
43 .and_replace_entry_with(|_, v| {
44 ret = Some((v.upgrade()?).clone());
45 Some(v)
46 })
47 .or_insert_with(|| {
48 let keyrc = Arc::new(q.to_owned());
49 let token = Tok::<T>::new(keyrc.clone(), self.clone());
50 ret = Some(token.clone());
51 (keyrc, WeakTok::new(&token))
52 });
53 ret.expect("One of the above callbacks must have ran")
54 }
55}