erg_common/
cache.rs

1use std::borrow::{Borrow, ToOwned};
2use std::hash::Hash;
3use std::sync::Arc;
4
5use crate::dict::Dict;
6use crate::set::Set;
7use crate::shared::Shared;
8use crate::traits::Immutable;
9use crate::{ArcArray, Str};
10
11#[derive(Debug)]
12pub struct CacheSet<T: ?Sized>(Shared<Set<Arc<T>>>);
13
14impl<T: ?Sized> Default for CacheSet<T> {
15    fn default() -> Self {
16        Self::new()
17    }
18}
19
20impl<T: ?Sized> CacheSet<T> {
21    pub fn new() -> Self {
22        Self(Shared::new(Set::new()))
23    }
24}
25
26impl Clone for CacheSet<str> {
27    fn clone(&self) -> Self {
28        Self(self.0.clone())
29    }
30}
31
32impl<T: Hash + Eq> Clone for CacheSet<T> {
33    fn clone(&self) -> Self {
34        Self(self.0.clone())
35    }
36}
37
38impl CacheSet<str> {
39    pub fn get(&self, s: &str) -> Str {
40        if let Some(cached) = self.0.borrow().get(s) {
41            return cached.clone().into();
42        } // &self.0 is dropped
43        let s = Str::rc(s);
44        self.0.borrow_mut().insert(s.clone().into_rc());
45        s
46    }
47}
48
49impl<T: Hash + Eq + Clone + Immutable> CacheSet<[T]> {
50    pub fn get(&self, q: &[T]) -> Arc<[T]> {
51        if let Some(cached) = self.0.borrow().get(q) {
52            return cached.clone();
53        } // &self.0 is dropped
54        let s = ArcArray::from(q);
55        self.0.borrow_mut().insert(s.clone());
56        s
57    }
58}
59
60impl<T: Hash + Eq + Clone> CacheSet<[T]> {
61    pub fn linear_get(&self, q: &[T]) -> Arc<[T]> {
62        if let Some(cached) = self.0.borrow().linear_get(q) {
63            return cached.clone();
64        } // &self.0 is dropped
65        let s = ArcArray::from(q);
66        self.0.borrow_mut().insert(s.clone());
67        s
68    }
69}
70
71impl<T: Hash + Eq + Immutable> CacheSet<T> {
72    pub fn get<Q>(&self, q: &Q) -> Arc<T>
73    where
74        Arc<T>: Borrow<Q>,
75        Q: ?Sized + Hash + Eq + ToOwned<Owned = T>,
76    {
77        if let Some(cached) = self.0.borrow().get(q) {
78            return cached.clone();
79        } // &self.0 is dropped
80        let s = Arc::from(q.to_owned());
81        self.0.borrow_mut().insert(s.clone());
82        s
83    }
84}
85
86impl<T: Hash + Eq> CacheSet<T> {
87    pub fn linear_get<Q>(&self, q: &Q) -> Arc<T>
88    where
89        Arc<T>: Borrow<Q>,
90        Q: ?Sized + Eq + ToOwned<Owned = T>,
91    {
92        if let Some(cached) = self.0.borrow().linear_get(q) {
93            return cached.clone();
94        } // &self.0 is dropped
95        let s = Arc::from(q.to_owned());
96        self.0.borrow_mut().insert(s.clone());
97        s
98    }
99}
100
101#[derive(Debug, Clone)]
102pub struct CacheDict<K, V: ?Sized>(Shared<Dict<K, Arc<V>>>);
103
104impl<K: Hash + Eq, V: ?Sized> Default for CacheDict<K, V> {
105    fn default() -> Self {
106        Self::new()
107    }
108}
109
110impl<K: Hash + Eq, V: ?Sized> CacheDict<K, V> {
111    pub fn new() -> Self {
112        Self(Shared::new(Dict::new()))
113    }
114}
115
116impl<K: Hash + Eq + Immutable, V> CacheDict<K, V> {
117    pub fn get<Q: ?Sized + Hash + Eq>(&self, k: &Q) -> Option<Arc<V>>
118    where
119        K: Borrow<Q>,
120    {
121        self.0.borrow().get(k).cloned()
122    }
123}
124
125impl<K: Hash + Eq, V> CacheDict<K, V> {
126    pub fn insert(&self, k: K, v: V) {
127        self.0.borrow_mut().insert(k, Arc::new(v));
128    }
129}
130
131impl<K: Eq, V> CacheDict<K, V> {
132    pub fn linear_get<Q: ?Sized + Eq>(&self, k: &Q) -> Option<Arc<V>>
133    where
134        K: Borrow<Q>,
135    {
136        self.0.borrow().linear_get(k).cloned()
137    }
138}