Do not cache "one-hit wonders"
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
//! System caches.
|
||||
|
||||
use crate::func::{CallableFunction, StraightHashMap};
|
||||
use crate::types::BloomFilterU64;
|
||||
use crate::{Identifier, StaticVec};
|
||||
use std::marker::PhantomData;
|
||||
#[cfg(feature = "no_std")]
|
||||
@@ -16,12 +17,27 @@ pub struct FnResolutionCacheEntry {
|
||||
pub source: Option<Box<Identifier>>,
|
||||
}
|
||||
|
||||
/// _(internals)_ A function resolution cache.
|
||||
/// _(internals)_ A function resolution cache with a bloom filter.
|
||||
/// Exported under the `internals` feature only.
|
||||
///
|
||||
/// [`FnResolutionCacheEntry`] is [`Box`]ed in order to pack as many entries inside a single B-Tree
|
||||
/// level as possible.
|
||||
pub type FnResolutionCache = StraightHashMap<u64, Option<FnResolutionCacheEntry>>;
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct FnResolutionCache {
|
||||
/// Hash map containing cached functions.
|
||||
pub map: StraightHashMap<u64, Option<FnResolutionCacheEntry>>,
|
||||
/// Bloom filter to avoid caching "one-hit wonders".
|
||||
pub filter: BloomFilterU64,
|
||||
}
|
||||
|
||||
impl FnResolutionCache {
|
||||
/// Clear the [`FnResolutionCache`].
|
||||
#[inline(always)]
|
||||
pub fn clear(&mut self) {
|
||||
self.map.clear();
|
||||
self.filter.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// _(internals)_ A type containing system-wide caches.
|
||||
/// Exported under the `internals` feature only.
|
||||
@@ -31,7 +47,7 @@ pub type FnResolutionCache = StraightHashMap<u64, Option<FnResolutionCacheEntry>
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Caches<'a> {
|
||||
/// Stack of [function resolution caches][FnResolutionCache].
|
||||
fn_resolution: StaticVec<FnResolutionCache>,
|
||||
fn_resolution_caches: StaticVec<FnResolutionCache>,
|
||||
/// Take care of the lifetime parameter.
|
||||
dummy: PhantomData<&'a ()>,
|
||||
}
|
||||
@@ -42,7 +58,7 @@ impl Caches<'_> {
|
||||
#[must_use]
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
fn_resolution: StaticVec::new_const(),
|
||||
fn_resolution_caches: StaticVec::new_const(),
|
||||
dummy: PhantomData,
|
||||
}
|
||||
}
|
||||
@@ -50,27 +66,27 @@ impl Caches<'_> {
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn fn_resolution_caches_len(&self) -> usize {
|
||||
self.fn_resolution.len()
|
||||
self.fn_resolution_caches.len()
|
||||
}
|
||||
/// Get a mutable reference to the current function resolution cache.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn fn_resolution_cache_mut(&mut self) -> &mut FnResolutionCache {
|
||||
if self.fn_resolution.is_empty() {
|
||||
if self.fn_resolution_caches.is_empty() {
|
||||
// Push a new function resolution cache if the stack is empty
|
||||
self.push_fn_resolution_cache();
|
||||
}
|
||||
self.fn_resolution.last_mut().unwrap()
|
||||
self.fn_resolution_caches.last_mut().unwrap()
|
||||
}
|
||||
/// Push an empty function resolution cache onto the stack and make it current.
|
||||
#[allow(dead_code)]
|
||||
#[inline(always)]
|
||||
pub fn push_fn_resolution_cache(&mut self) {
|
||||
self.fn_resolution.push(StraightHashMap::default());
|
||||
self.fn_resolution_caches.push(Default::default());
|
||||
}
|
||||
/// Rewind the function resolution caches stack to a particular size.
|
||||
#[inline(always)]
|
||||
pub fn rewind_fn_resolution_caches(&mut self, len: usize) {
|
||||
self.fn_resolution.truncate(len);
|
||||
self.fn_resolution_caches.truncate(len);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user