Skip to content

Commit b620be1

Browse files
committed
Expose metrics for the pinned memory cache
1 parent 5aad41e commit b620be1

File tree

2 files changed

+50
-5
lines changed

2 files changed

+50
-5
lines changed

packages/vm/src/cache.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ pub struct Metrics {
5353
pub size_memory_cache: usize,
5454
}
5555

56+
#[derive(Debug, Clone)]
57+
pub struct HeavyMetrics {
58+
// It is *intentional* that this is only a vector
59+
// We don't need a potentially expensive hashing algorithm here
60+
// The checksums are sourced from a hashmap already, ensuring uniqueness of the checksums
61+
pub hits_per_pinned_contract: Vec<(Checksum, u32)>,
62+
}
63+
5664
#[derive(Clone, Debug)]
5765
#[non_exhaustive]
5866
pub struct CacheOptions {
@@ -182,6 +190,19 @@ where
182190
self.inner.lock().unwrap().stats
183191
}
184192

193+
pub fn heavy_metrics(&self) -> HeavyMetrics {
194+
let cache = self.inner.lock().unwrap();
195+
let hits_per_pinned_contract = cache
196+
.pinned_memory_cache
197+
.iter()
198+
.map(|(checksum, module)| (*checksum, module.hits))
199+
.collect();
200+
201+
HeavyMetrics {
202+
hits_per_pinned_contract,
203+
}
204+
}
205+
185206
pub fn metrics(&self) -> Metrics {
186207
let cache = self.inner.lock().unwrap();
187208
Metrics {

packages/vm/src/modules/pinned_memory_cache.rs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,19 @@ use std::collections::HashMap;
44
use super::cached_module::CachedModule;
55
use crate::VmResult;
66

7+
/// Struct storing some additional metadata, which is only of interest for the pinned cache,
8+
/// alongside the cached module.
9+
// TODO: Maybe implement a `Deref` for this? But would it even worth it considering how little it is actually used?
10+
pub struct InstrumentedModule {
11+
/// Number of loads from memory this module received
12+
pub hits: u32,
13+
/// The actual cached module
14+
pub module: CachedModule,
15+
}
16+
717
/// An pinned in memory module cache
818
pub struct PinnedMemoryCache {
9-
modules: HashMap<Checksum, CachedModule>,
19+
modules: HashMap<Checksum, InstrumentedModule>,
1020
}
1121

1222
impl PinnedMemoryCache {
@@ -17,8 +27,19 @@ impl PinnedMemoryCache {
1727
}
1828
}
1929

30+
pub fn iter(&self) -> impl Iterator<Item = (&Checksum, &InstrumentedModule)> {
31+
self.modules.iter()
32+
}
33+
2034
pub fn store(&mut self, checksum: &Checksum, cached_module: CachedModule) -> VmResult<()> {
21-
self.modules.insert(*checksum, cached_module);
35+
self.modules.insert(
36+
*checksum,
37+
InstrumentedModule {
38+
hits: 0,
39+
module: cached_module,
40+
},
41+
);
42+
2243
Ok(())
2344
}
2445

@@ -31,8 +52,11 @@ impl PinnedMemoryCache {
3152

3253
/// Looks up a module in the cache and creates a new module
3354
pub fn load(&mut self, checksum: &Checksum) -> VmResult<Option<CachedModule>> {
34-
match self.modules.get(checksum) {
35-
Some(cached) => Ok(Some(cached.clone())),
55+
match self.modules.get_mut(checksum) {
56+
Some(cached) => {
57+
cached.hits = cached.hits.saturating_add(1);
58+
Ok(Some(cached.module.clone()))
59+
}
3660
None => Ok(None),
3761
}
3862
}
@@ -54,7 +78,7 @@ impl PinnedMemoryCache {
5478
pub fn size(&self) -> usize {
5579
self.modules
5680
.iter()
57-
.map(|(key, module)| std::mem::size_of_val(key) + module.size_estimate)
81+
.map(|(key, module)| std::mem::size_of_val(key) + module.module.size_estimate)
5882
.sum()
5983
}
6084
}

0 commit comments

Comments
 (0)