1use crate::util::hash128;
2use hayro_syntax::object::{Array, Dict, MaybeRef, Name, Null, ObjRef, Object, Stream};
3use kurbo::Affine;
4use std::any::Any;
5use std::collections::HashMap;
6use std::collections::hash_map::Entry;
7use std::sync::{Arc, Mutex};
8
9type CacheMap = HashMap<u128, Option<Box<dyn Any + Send + Sync>>>;
10#[derive(Clone)]
11pub(crate) struct Cache(Arc<Mutex<CacheMap>>);
12
13impl Default for Cache {
14 fn default() -> Self {
15 Self::new()
16 }
17}
18
19impl Cache {
20 pub(crate) fn new() -> Self {
21 Self(Arc::new(Mutex::new(HashMap::new())))
22 }
23
24 pub(crate) fn get_or_insert_with<T: Clone + Send + Sync + 'static>(
25 &self,
26 id: u128,
27 f: impl FnOnce() -> Option<T>,
28 ) -> Option<T> {
29 let mut locked = self.0.lock().unwrap();
30
31 match locked.entry(id) {
34 Entry::Occupied(o) => o
35 .get()
36 .as_ref()
37 .and_then(|val| val.downcast_ref::<T>().cloned()),
38 Entry::Vacant(_) => {
39 drop(locked);
40 let val = f();
41 self.0.lock().unwrap().insert(
42 id,
43 val.clone()
44 .map(|val| Box::new(val) as Box<dyn Any + Send + Sync>),
45 );
46
47 val
48 }
49 }
50 }
51}
52
53pub trait CacheKey {
55 fn cache_key(&self) -> u128;
57}
58
59impl<T: CacheKey, U: CacheKey> CacheKey for (T, U) {
60 fn cache_key(&self) -> u128 {
61 hash128(&(self.0.cache_key(), self.1.cache_key()))
62 }
63}
64
65impl CacheKey for Dict<'_> {
66 fn cache_key(&self) -> u128 {
67 hash128(self.data())
68 }
69}
70
71impl CacheKey for Stream<'_> {
72 fn cache_key(&self) -> u128 {
73 self.dict().cache_key()
74 }
75}
76
77impl CacheKey for Null {
78 fn cache_key(&self) -> u128 {
79 hash128(self)
80 }
81}
82
83impl CacheKey for bool {
84 fn cache_key(&self) -> u128 {
85 hash128(self)
86 }
87}
88
89impl CacheKey for hayro_syntax::object::Number {
90 fn cache_key(&self) -> u128 {
91 hash128(&self.as_f64().to_bits())
92 }
93}
94
95impl CacheKey for hayro_syntax::object::String<'_> {
96 fn cache_key(&self) -> u128 {
97 hash128(self.get().as_ref())
98 }
99}
100
101impl CacheKey for Name<'_> {
102 fn cache_key(&self) -> u128 {
103 hash128(self)
104 }
105}
106
107impl CacheKey for Array<'_> {
108 fn cache_key(&self) -> u128 {
109 hash128(self.data())
110 }
111}
112
113impl CacheKey for Object<'_> {
114 fn cache_key(&self) -> u128 {
115 match self {
116 Object::Null(n) => n.cache_key(),
117 Object::Boolean(b) => b.cache_key(),
118 Object::Number(n) => n.cache_key(),
119 Object::String(s) => s.cache_key(),
120 Object::Name(n) => n.cache_key(),
121 Object::Dict(d) => d.cache_key(),
122 Object::Array(a) => a.cache_key(),
123 Object::Stream(s) => s.cache_key(),
124 }
125 }
126}
127
128impl CacheKey for ObjRef {
129 fn cache_key(&self) -> u128 {
130 hash128(self)
131 }
132}
133
134impl<T: CacheKey> CacheKey for MaybeRef<T> {
135 fn cache_key(&self) -> u128 {
136 match self {
137 Self::Ref(r) => r.cache_key(),
138 Self::NotRef(o) => o.cache_key(),
139 }
140 }
141}
142
143impl CacheKey for Affine {
144 fn cache_key(&self) -> u128 {
145 let c = self.as_coeffs();
146 hash128(&[
147 c[0].to_bits(),
148 c[1].to_bits(),
149 c[2].to_bits(),
150 c[3].to_bits(),
151 c[4].to_bits(),
152 c[5].to_bits(),
153 ])
154 }
155}
156
157impl CacheKey for u128 {
158 fn cache_key(&self) -> u128 {
159 hash128(self)
160 }
161}