versatile_dataloader/
cache.rs1use std::{
2 borrow::Cow,
3 collections::{HashMap, hash_map::RandomState},
4 hash::{BuildHasher, Hash},
5 marker::PhantomData,
6 num::NonZeroUsize,
7};
8
9pub trait CacheFactory: Send + Sync + 'static {
11 fn create<K, V>(&self) -> Box<dyn CacheStorage<Key = K, Value = V>>
15 where
16 K: Send + Sync + Clone + Eq + Hash + 'static,
17 V: Send + Sync + Clone + 'static;
18}
19
20pub trait CacheStorage: Send + Sync + 'static {
22 type Key: Send + Sync + Clone + Eq + Hash + 'static;
24
25 type Value: Send + Sync + Clone + 'static;
27
28 fn get(&mut self, key: &Self::Key) -> Option<&Self::Value>;
31
32 fn insert(&mut self, key: Cow<'_, Self::Key>, val: Cow<'_, Self::Value>);
35
36 fn remove(&mut self, key: &Self::Key);
38
39 fn clear(&mut self);
41
42 fn iter(&self) -> Box<dyn Iterator<Item = (&'_ Self::Key, &'_ Self::Value)> + '_>;
44}
45
46pub struct NoCache;
48
49impl CacheFactory for NoCache {
50 fn create<K, V>(&self) -> Box<dyn CacheStorage<Key = K, Value = V>>
51 where
52 K: Send + Sync + Clone + Eq + Hash + 'static,
53 V: Send + Sync + Clone + 'static,
54 {
55 Box::new(NoCacheImpl {
56 _mark1: PhantomData,
57 _mark2: PhantomData,
58 })
59 }
60}
61
62struct NoCacheImpl<K, V> {
63 _mark1: PhantomData<K>,
64 _mark2: PhantomData<V>,
65}
66
67impl<K, V> CacheStorage for NoCacheImpl<K, V>
68where
69 K: Send + Sync + Clone + Eq + Hash + 'static,
70 V: Send + Sync + Clone + 'static,
71{
72 type Key = K;
73 type Value = V;
74
75 #[inline]
76 fn get(&mut self, _key: &K) -> Option<&V> {
77 None
78 }
79
80 #[inline]
81 fn insert(&mut self, _key: Cow<'_, Self::Key>, _val: Cow<'_, Self::Value>) {}
82
83 #[inline]
84 fn remove(&mut self, _key: &K) {}
85
86 #[inline]
87 fn clear(&mut self) {}
88
89 fn iter(&self) -> Box<dyn Iterator<Item = (&'_ Self::Key, &'_ Self::Value)> + '_> {
90 Box::new(std::iter::empty())
91 }
92}
93
94pub struct HashMapCache<S = RandomState> {
96 _mark: PhantomData<S>,
97}
98
99impl<S: Send + Sync + BuildHasher + Default + 'static> HashMapCache<S> {
100 #[must_use]
102 pub fn new() -> Self {
103 Self { _mark: PhantomData }
104 }
105}
106
107impl Default for HashMapCache<RandomState> {
108 fn default() -> Self {
109 Self { _mark: PhantomData }
110 }
111}
112
113impl<S: Send + Sync + BuildHasher + Default + 'static> CacheFactory for HashMapCache<S> {
114 fn create<K, V>(&self) -> Box<dyn CacheStorage<Key = K, Value = V>>
115 where
116 K: Send + Sync + Clone + Eq + Hash + 'static,
117 V: Send + Sync + Clone + 'static,
118 {
119 Box::new(HashMapCacheImpl::<K, V, S>(HashMap::<K, V, S>::default()))
120 }
121}
122
123struct HashMapCacheImpl<K, V, S>(HashMap<K, V, S>);
124
125impl<K, V, S> CacheStorage for HashMapCacheImpl<K, V, S>
126where
127 K: Send + Sync + Clone + Eq + Hash + 'static,
128 V: Send + Sync + Clone + 'static,
129 S: Send + Sync + BuildHasher + 'static,
130{
131 type Key = K;
132 type Value = V;
133
134 #[inline]
135 fn get(&mut self, key: &Self::Key) -> Option<&Self::Value> {
136 self.0.get(key)
137 }
138
139 #[inline]
140 fn insert(&mut self, key: Cow<'_, Self::Key>, val: Cow<'_, Self::Value>) {
141 self.0.insert(key.into_owned(), val.into_owned());
142 }
143
144 #[inline]
145 fn remove(&mut self, key: &Self::Key) {
146 self.0.remove(key);
147 }
148
149 #[inline]
150 fn clear(&mut self) {
151 self.0.clear();
152 }
153
154 fn iter(&self) -> Box<dyn Iterator<Item = (&'_ Self::Key, &'_ Self::Value)> + '_> {
155 Box::new(self.0.iter())
156 }
157}
158
159pub struct LruCache {
161 cap: usize,
162}
163
164impl LruCache {
165 #[must_use]
167 pub fn new(cap: usize) -> Self {
168 Self { cap }
169 }
170}
171
172impl CacheFactory for LruCache {
173 fn create<K, V>(&self) -> Box<dyn CacheStorage<Key = K, Value = V>>
174 where
175 K: Send + Sync + Clone + Eq + Hash + 'static,
176 V: Send + Sync + Clone + 'static,
177 {
178 Box::new(LruCacheImpl(lru::LruCache::new(
179 NonZeroUsize::new(self.cap).unwrap(),
180 )))
181 }
182}
183
184struct LruCacheImpl<K, V>(lru::LruCache<K, V>);
185
186impl<K, V> CacheStorage for LruCacheImpl<K, V>
187where
188 K: Send + Sync + Clone + Eq + Hash + 'static,
189 V: Send + Sync + Clone + 'static,
190{
191 type Key = K;
192 type Value = V;
193
194 #[inline]
195 fn get(&mut self, key: &Self::Key) -> Option<&Self::Value> {
196 self.0.get(key)
197 }
198
199 #[inline]
200 fn insert(&mut self, key: Cow<'_, Self::Key>, val: Cow<'_, Self::Value>) {
201 self.0.put(key.into_owned(), val.into_owned());
202 }
203
204 #[inline]
205 fn remove(&mut self, key: &Self::Key) {
206 self.0.pop(key);
207 }
208
209 #[inline]
210 fn clear(&mut self) {
211 self.0.clear();
212 }
213
214 fn iter(&self) -> Box<dyn Iterator<Item = (&'_ Self::Key, &'_ Self::Value)> + '_> {
215 Box::new(self.0.iter())
216 }
217}