Skip to main content

harmos_runtime/operations/manager/
cache.rs

1/* ***
2 *
3 * Harmos
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * ***
8 */
9
10/* === Modules === */
11
12/* === Re-Exports === */
13
14/* === Imports === */
15
16// Standard Library Imports
17
18// Third Party Imports
19
20// Local Imports
21use super::*;
22
23/* === Constants === */
24
25/* === Macros === */
26
27/* === Type Aliases === */
28
29/* === Structs === */
30
31/* === Enums === */
32
33/* === Traits === */
34
35/* === Implementations === */
36
37impl OperationManager {
38    pub fn cache_capacity(&self) -> usize {
39        self.registry.state.lock().expect("operation registry lock is healthy").cache_capacity
40    }
41
42    pub fn set_cache_capacity(&self, capacity: usize) {
43        let retired = {
44            let mut state = self.registry.state.lock().expect("operation registry lock is healthy");
45            state.cache_capacity = capacity;
46            state.evict_to(capacity)
47        };
48        drop(retired);
49    }
50
51    pub fn clear_cache(&self) {
52        let retired = std::mem::take(&mut self.registry.state.lock().expect("operation registry lock is healthy").cache);
53        drop(retired);
54    }
55
56    pub fn invalidate<O: OperationDeclaration>(&self, key: &CacheKey) -> Result<()> {
57        let entry = self.entry(O::ID)?;
58        self.invalidate_entry(&entry, key);
59        Ok(())
60    }
61
62    pub fn invalidate_from<O: OperationDeclaration>(&self, owner: &str, key: &CacheKey) -> Result<()> {
63        let entry = self.capture_provider(O::ID, Some(owner))?;
64        entry.available()?;
65        self.invalidate_entry(&entry, key);
66        Ok(())
67    }
68
69    pub(super) fn invalidate_entry(&self, entry: &Arc<Entry>, key: &CacheKey) {
70        let retired = self
71            .registry
72            .state
73            .lock()
74            .expect("operation registry lock is healthy")
75            .remove_cache(|cached| cached.key == *key && cached.target.upgrade().is_some_and(|target| Arc::ptr_eq(&target, entry)));
76        drop(retired);
77    }
78
79    pub(in crate::operations) fn lookup<O: OperationDeclaration>(
80        &self, entry: &Arc<Entry>, key: &CacheKey, identity: &Identity,
81    ) -> Option<crate::operations::Response<O::Response>> {
82        let mut state = self.registry.state.lock().expect("operation registry lock is healthy");
83        if state.closing || entry.available().is_err() {
84            return None;
85        }
86        let index = state.cache.iter().position(|cached| {
87            cached.key == *key
88                && cached.identity == *identity
89                && cached.target.upgrade().is_some_and(|target| Arc::ptr_eq(&target, entry) && target.generation == entry.generation)
90        })?;
91        let cached = state.cache.remove(index)?;
92        let response = cached.response.clone().restore::<O::Response>();
93        state.cache.push_back(cached);
94        response
95    }
96}
97
98/* === Public Functions === */
99
100/* === Private Functions === */
101
102/* === Tests === */