1use std::{
3 any::{Any, TypeId},
4 collections::HashMap,
5 hash::Hash,
6};
7
8use once_cell::sync::Lazy;
9use parking_lot::{RwLock, RwLockUpgradableReadGuard};
10
11use crate::{HashInterner, OrdInterner};
12
13static HASH_INTERNERS: Lazy<RwLock<HashInternerPool>> = Lazy::new(Default::default);
14
15pub struct HashInternerPool {
22 type_map: HashMap<TypeId, Box<dyn Any + Send + Sync + 'static>>,
23}
24
25impl Default for HashInternerPool {
26 fn default() -> Self {
27 Self::new()
28 }
29}
30
31impl HashInternerPool {
32 pub fn new() -> Self {
33 Self {
34 type_map: HashMap::new(),
35 }
36 }
37
38 pub fn get<T>(&self) -> Option<HashInterner<T>>
40 where
41 T: Eq + Hash + Send + Sync + Any + ?Sized + 'static,
42 {
43 self.type_map
44 .get(&TypeId::of::<T>())
45 .map(|v| v.downcast_ref::<HashInterner<T>>().unwrap().clone())
46 }
47
48 pub fn get_or_create<T>(&mut self) -> HashInterner<T>
50 where
51 T: Eq + Hash + Send + Sync + Any + ?Sized + 'static,
52 {
53 self.get::<T>().unwrap_or_else(|| {
54 let ret = HashInterner::new();
55 self.type_map
56 .insert(TypeId::of::<T>(), Box::new(ret.clone()));
57 ret
58 })
59 }
60}
61
62pub fn hash_interner<T>() -> HashInterner<T>
67where
68 T: Eq + Hash + Send + Sync + Any + ?Sized + 'static,
69{
70 let map = HASH_INTERNERS.upgradable_read();
71 if let Some(interner) = map.get::<T>() {
72 return interner;
73 }
74 let mut map = RwLockUpgradableReadGuard::upgrade(map);
75 map.get_or_create::<T>()
76}
77
78static ORD_INTERNERS: Lazy<RwLock<OrdInternerPool>> = Lazy::new(Default::default);
79
80pub struct OrdInternerPool {
87 type_map: HashMap<TypeId, Box<dyn Any + Send + Sync + 'static>>,
88}
89
90impl Default for OrdInternerPool {
91 fn default() -> Self {
92 Self::new()
93 }
94}
95
96impl OrdInternerPool {
97 pub fn new() -> Self {
98 Self {
99 type_map: HashMap::new(),
100 }
101 }
102
103 pub fn get<T>(&self) -> Option<OrdInterner<T>>
105 where
106 T: Ord + Send + Sync + Any + ?Sized + 'static,
107 {
108 self.type_map
109 .get(&TypeId::of::<T>())
110 .map(|v| v.downcast_ref::<OrdInterner<T>>().unwrap().clone())
111 }
112
113 pub fn get_or_create<T>(&mut self) -> OrdInterner<T>
115 where
116 T: Ord + Send + Sync + Any + ?Sized + 'static,
117 {
118 self.get::<T>().unwrap_or_else(|| {
119 let ret = OrdInterner::new();
120 self.type_map
121 .insert(TypeId::of::<T>(), Box::new(ret.clone()));
122 ret
123 })
124 }
125}
126
127pub fn ord_interner<T>() -> OrdInterner<T>
132where
133 T: Ord + Send + Sync + Any + ?Sized + 'static,
134{
135 let map = ORD_INTERNERS.upgradable_read();
136 if let Some(interner) = map.get::<T>() {
137 return interner;
138 }
139 let mut map = RwLockUpgradableReadGuard::upgrade(map);
140 map.get_or_create::<T>()
141}