1// Copyright 2023 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
45use super::types::{Key, Value};
6use std::fmt;
78pub trait ObjectCachePlaceholder<V: Value>: Send + Sync {
9/// Consumes itself in delivering the cache value for which the placeholder was reserved.
10 /// Passing None for value should not be inserted into the cache, but interpreted as an
11 /// incomplete search.
12fn complete(self: Box<Self>, value: Option<&V>);
13}
1415/// Possible results for a cache `lookup_or_reserve()`
16pub enum ObjectCacheResult<'a, V: Value> {
17/// Contains the value successfully retrieved from the cache.
18Value(V),
19/// The object was not found in the cache, so this placeholder can be used to insert the
20 /// calculated result.
21Placeholder(Box<dyn ObjectCachePlaceholder<V> + 'a>),
22/// Returned for items that are not wanted to be inserted into the cache.
23NoCache,
24}
2526impl<'a, V: Value> fmt::Debug for ObjectCacheResult<'a, V> {
27fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28let (name, contents) = match self {
29Self::Value(v) => ("Value", Some(format!("{:?}", v))),
30Self::NoCache => ("NoCache", None),
31Self::Placeholder(_) => ("Placeholder", None),
32 };
33if contents.is_some() {
34 f.debug_struct("ObjectCacheResult").field(name, &contents.unwrap()).finish()
35 } else {
36 f.debug_struct("ObjectCacheResult").field(name, &"").finish()
37 }
38 }
39}
4041pub trait ObjectCache<K: Key, V: Value>: Send + Sync {
42/// Looks up a key in the cache and may return a cached value for it. See `ObjectCacheResult`.
43fn lookup_or_reserve<'a>(&'a self, key: &K) -> ObjectCacheResult<'_, V>;
4445/// Removes key from cache if `value` is None, invalidates the results of placeholders that have
46 /// not been resolved. When `value` is provided then the value may be inserted, and may replace
47 /// an existing value.
48fn invalidate(&self, key: K, value: Option<V>);
49}
5051/// A cache that will always return NoCache in lookups, and does no actual work.
52pub struct NullCache {}
5354impl<K: Key, V: Value> ObjectCache<K, V> for NullCache {
55fn lookup_or_reserve(&self, _key: &K) -> ObjectCacheResult<'_, V> {
56 ObjectCacheResult::NoCache
57 }
5859fn invalidate(&self, _key: K, _value: Option<V>) {}
60}