• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

oasisprotocol / oasis-core / #4588

07 Mar 2024 09:50AM UTC coverage: 44.999% (-0.02%) from 45.016%
#4588

push

web-flow
Merge pull request #5587 from oasisprotocol/ptrus/stable/23.0.x/go-1.21.8

[stable/23.0.x] go: update to 1.21.8

3 of 4 new or added lines in 2 files covered. (75.0%)

41 existing lines in 19 files now uncovered.

2857 of 6349 relevant lines covered (45.0%)

0.96 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/runtime/src/cache.rs
1
//! In-memory cache of trees.
2
use std::{
3
    cell::RefCell,
4
    num::NonZeroUsize,
5
    rc::Rc,
6
    sync::{Arc, Mutex, MutexGuard},
7
};
8

9
use crate::{
10
    common::crypto::hash::Hash,
11
    protocol::Protocol,
12
    storage::mkvs::{sync::HostReadSyncer, Root, Tree},
13
    types::HostStorageEndpoint,
14
};
15

16
thread_local! {
17
    static QUERY_CACHE: RefCell<lru::LruCache<u64, Rc<RefCell<Cache>>>> = RefCell::new(lru::LruCache::new(NonZeroUsize::new(10).unwrap()));
×
18
}
19

20
/// A set of storage tree caches, one for each storage operation:
21
///
22
/// * **Execution** and **checking** of transactions each have their own cache guarded by a mutex
23
///   since the usual use case is that only one execution/check batch is running at any given time.
24
///
25
/// * **Queries** have a thread-local cache as there can be multiple queries running at any given
26
///   time and having a global lock would kill concurrency.
27
#[derive(Clone)]
28
pub struct CacheSet {
29
    protocol: Arc<Protocol>,
30
    execute: Arc<Mutex<Cache>>,
31
    check: Arc<Mutex<Cache>>,
32
}
33

34
impl CacheSet {
35
    /// Create a new empty cache set.
36
    pub fn new(protocol: Arc<Protocol>) -> Self {
×
37
        Self {
38
            execute: Arc::new(Mutex::new(Cache::new(&protocol))),
×
39
            check: Arc::new(Mutex::new(Cache::new(&protocol))),
×
40
            protocol,
41
        }
42
    }
43

44
    /// Cache used for executing transactions.
45
    pub fn execute(&self, root: Root) -> MutexGuard<'_, Cache> {
×
46
        let mut cache = self.execute.lock().unwrap();
×
47
        cache.maybe_replace(&self.protocol, root);
×
UNCOV
48
        cache
×
49
    }
50

51
    /// Cache used for checking transactions.
52
    pub fn check(&self, root: Root) -> MutexGuard<'_, Cache> {
×
53
        let mut cache = self.check.lock().unwrap();
×
54
        cache.maybe_replace(&self.protocol, root);
×
UNCOV
55
        cache
×
56
    }
57

58
    /// Cache used for queries.
59
    pub fn query(&self, root: Root) -> Rc<RefCell<Cache>> {
×
60
        let cache = QUERY_CACHE.with(|caches| {
×
61
            let mut caches = caches.borrow_mut();
×
62
            if let Some(cache) = caches.get(&root.version) {
×
63
                return cache.clone();
×
64
            }
65

66
            let cache = Rc::new(RefCell::new(Cache::new(&self.protocol)));
×
67
            caches.put(root.version, cache.clone());
×
68
            cache
×
69
        });
70
        cache.borrow_mut().maybe_replace(&self.protocol, root);
×
UNCOV
71
        cache
×
72
    }
73
}
74

75
/// Cached storage tree with an associated root.
76
pub struct Cache {
77
    root: Root,
78
    tree: Tree,
79
}
80

81
impl Cache {
82
    fn new(protocol: &Arc<Protocol>) -> Self {
×
83
        Self {
84
            root: Default::default(),
×
85
            tree: Self::build(protocol, Default::default()),
×
86
        }
87
    }
88

89
    fn build(protocol: &Arc<Protocol>, root: Root) -> Tree {
×
90
        let config = protocol.get_config();
×
91
        let read_syncer = HostReadSyncer::new(protocol.clone(), HostStorageEndpoint::Runtime);
×
92
        Tree::builder()
×
93
            .with_capacity(
94
                config.storage.cache_node_capacity,
×
95
                config.storage.cache_value_capacity,
×
96
            )
97
            .with_root(root)
98
            .build(Box::new(read_syncer))
×
99
    }
100

101
    fn maybe_replace(&mut self, protocol: &Arc<Protocol>, root: Root) {
×
102
        if self.root == root {
×
103
            return;
104
        }
105

106
        self.tree = Self::build(protocol, root);
×
107
        self.root = root;
×
108
    }
109

110
    /// Reference to the cached tree.
111
    pub fn tree(&self) -> &Tree {
×
112
        &self.tree
×
113
    }
114

115
    /// Mutable reference to the cached tree.
116
    pub fn tree_mut(&mut self) -> &mut Tree {
×
117
        &mut self.tree
×
118
    }
119

120
    /// Commits a specific version and root as being stored by the tree.
121
    pub fn commit(&mut self, version: u64, hash: Hash) {
×
122
        self.root.version = version;
×
123
        self.root.hash = hash;
×
124
    }
125
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc