1use super::types::{Key, Value};
6use fuchsia_sync::MappedMutexGuard;
7use std::fmt;
8
9pub trait ObjectCachePlaceholder<V: Value>: Send + Sync {
10 fn complete(self: Box<Self>, value: Option<&V>);
14}
15
16pub enum ObjectCacheResult<'a, V: Value> {
18 Value(MappedMutexGuard<'a, V>),
20 Placeholder(Box<dyn ObjectCachePlaceholder<V> + 'a>),
23 NoCache,
25}
26
27impl<'a, V: Value> fmt::Debug for ObjectCacheResult<'a, V> {
28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29 let (name, contents) = match self {
30 Self::Value(v) => ("Value", Some(format!("{:?}", v))),
31 Self::NoCache => ("NoCache", None),
32 Self::Placeholder(_) => ("Placeholder", None),
33 };
34 if contents.is_some() {
35 f.debug_struct("ObjectCacheResult").field(name, &contents.unwrap()).finish()
36 } else {
37 f.debug_struct("ObjectCacheResult").field(name, &"").finish()
38 }
39 }
40}
41
42pub trait ObjectCache<K: Key, V: Value>: Send + Sync {
43 fn lookup_or_reserve<'a>(&'a self, key: &K) -> ObjectCacheResult<'a, V>;
45
46 fn is_cacheable(&self, key: &K) -> bool;
51
52 fn invalidate(&self, key: &K, value: Option<V>);
56
57 fn clear(&self);
59
60 fn len(&self) -> usize {
62 0
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69 use crate::object_store::object_record::{ObjectKey, ObjectValue};
70 use fuchsia_sync::{Mutex, MutexGuard};
71
72 struct DummyPlaceholder;
73 impl ObjectCachePlaceholder<ObjectValue> for DummyPlaceholder {
74 fn complete(self: Box<Self>, _value: Option<&ObjectValue>) {}
75 }
76
77 struct DummyCache;
78 impl ObjectCache<ObjectKey, ObjectValue> for DummyCache {
79 fn lookup_or_reserve(&self, _key: &ObjectKey) -> ObjectCacheResult<'_, ObjectValue> {
80 ObjectCacheResult::NoCache
81 }
82 fn is_cacheable(&self, _key: &ObjectKey) -> bool {
83 false
84 }
85 fn invalidate(&self, _key: &ObjectKey, _value: Option<ObjectValue>) {}
86 fn clear(&self) {}
87 }
88
89 #[fuchsia::test]
90 fn test_object_cache_result_debug_and_default_len() {
91 let mutex = Mutex::new(ObjectValue::None);
92 let guard = MutexGuard::map(mutex.lock(), |v| v);
93 let val_res: ObjectCacheResult<'_, ObjectValue> = ObjectCacheResult::Value(guard);
94 assert!(format!("{:?}", val_res).contains("Value"));
95
96 let placeholder_res: ObjectCacheResult<'_, ObjectValue> =
97 ObjectCacheResult::Placeholder(Box::new(DummyPlaceholder));
98 assert!(format!("{:?}", placeholder_res).contains("Placeholder"));
99
100 let no_cache_res: ObjectCacheResult<'_, ObjectValue> = ObjectCacheResult::NoCache;
101 assert!(format!("{:?}", no_cache_res).contains("NoCache"));
102
103 let cache = DummyCache;
104 assert_eq!(cache.len(), 0);
105 assert!(!cache.is_cacheable(&ObjectKey::object(1)));
106 assert!(matches!(
107 cache.lookup_or_reserve(&ObjectKey::object(1)),
108 ObjectCacheResult::NoCache
109 ));
110 cache.invalidate(&ObjectKey::object(1), None);
111 cache.clear();
112 Box::new(DummyPlaceholder).complete(None);
113 }
114}