rhai/src/eval/cache.rs

93 lines
3.0 KiB
Rust
Raw Normal View History

2022-04-16 10:36:53 +02:00
//! System caches.
use crate::func::{CallableFunction, StraightHashMap};
2022-09-12 13:47:29 +02:00
use crate::types::BloomFilterU64;
2022-04-16 10:36:53 +02:00
use crate::{Identifier, StaticVec};
use std::marker::PhantomData;
2022-04-16 10:36:53 +02:00
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
/// _(internals)_ An entry in a function resolution cache.
/// Exported under the `internals` feature only.
#[derive(Debug, Clone)]
pub struct FnResolutionCacheEntry {
/// Function.
pub func: CallableFunction,
/// Optional source.
2022-05-07 09:54:44 +02:00
pub source: Option<Box<Identifier>>,
2022-04-16 10:36:53 +02:00
}
2022-09-12 13:47:29 +02:00
/// _(internals)_ A function resolution cache with a bloom filter.
2022-04-16 10:36:53 +02:00
/// 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.
2022-09-12 13:47:29 +02:00
#[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();
}
}
2022-04-16 10:36:53 +02:00
/// _(internals)_ A type containing system-wide caches.
/// Exported under the `internals` feature only.
///
/// The following caches are contained inside this type:
/// * A stack of [function resolution caches][FnResolutionCache]
#[derive(Debug, Clone)]
2022-05-24 13:34:47 +02:00
pub struct Caches<'a> {
/// Stack of [function resolution caches][FnResolutionCache].
2022-09-12 13:47:29 +02:00
fn_resolution_caches: StaticVec<FnResolutionCache>,
2022-05-24 13:34:47 +02:00
/// Take care of the lifetime parameter.
dummy: PhantomData<&'a ()>,
}
2022-04-16 10:36:53 +02:00
2022-05-24 05:52:03 +02:00
impl Caches<'_> {
2022-04-16 10:36:53 +02:00
/// Create an empty [`Caches`].
#[inline(always)]
#[must_use]
pub const fn new() -> Self {
2022-05-24 13:34:47 +02:00
Self {
2022-09-12 13:47:29 +02:00
fn_resolution_caches: StaticVec::new_const(),
2022-05-24 13:34:47 +02:00
dummy: PhantomData,
}
2022-04-16 10:36:53 +02:00
}
/// Get the number of function resolution cache(s) in the stack.
#[inline(always)]
#[must_use]
pub fn fn_resolution_caches_len(&self) -> usize {
2022-09-12 13:47:29 +02:00
self.fn_resolution_caches.len()
2022-04-16 10:36:53 +02:00
}
/// Get a mutable reference to the current function resolution cache.
#[inline]
#[must_use]
pub fn fn_resolution_cache_mut(&mut self) -> &mut FnResolutionCache {
2022-09-12 13:47:29 +02:00
if self.fn_resolution_caches.is_empty() {
2022-04-16 10:36:53 +02:00
// Push a new function resolution cache if the stack is empty
self.push_fn_resolution_cache();
}
2022-09-12 13:47:29 +02:00
self.fn_resolution_caches.last_mut().unwrap()
2022-04-16 10:36:53 +02:00
}
/// 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) {
2022-09-12 13:47:29 +02:00
self.fn_resolution_caches.push(Default::default());
2022-04-16 10:36:53 +02:00
}
/// Rewind the function resolution caches stack to a particular size.
#[inline(always)]
pub fn rewind_fn_resolution_caches(&mut self, len: usize) {
2022-09-12 13:47:29 +02:00
self.fn_resolution_caches.truncate(len);
2022-04-16 10:36:53 +02:00
}
}