diff options
Diffstat (limited to 'src/lib.rs')
| -rw-r--r-- | src/lib.rs | 76 |
1 files changed, 2 insertions, 74 deletions
@@ -47,13 +47,11 @@ pub mod library; pub mod loading; pub mod model; pub mod parse; +pub mod query; pub mod source; pub mod syntax; -use std::any::Any; use std::collections::HashMap; -use std::fmt::{self, Display, Formatter}; -use std::hash::Hash; use std::mem; use std::path::PathBuf; use std::sync::Arc; @@ -68,7 +66,7 @@ use crate::model::StyleMap; use crate::source::{SourceId, SourceStore}; use crate::util::PathExt; -/// The core context which holds the loader, configuration and cached artifacts. +/// The core context which holds the loader, stores, and configuration. pub struct Context { /// The loader the context was created with. pub loader: Arc<dyn Loader>, @@ -86,8 +84,6 @@ pub struct Context { styles: Arc<StyleMap>, /// Cached modules. modules: HashMap<SourceId, Module>, - /// Cached queries. - cache: HashMap<u64, CacheEntry>, /// The stack of imported files that led to evaluation of the current file. route: Vec<SourceId>, /// The dependencies of the current evaluation process. @@ -236,77 +232,9 @@ impl ContextBuilder { std: self.std.clone().unwrap_or_else(|| Arc::new(library::new())), styles: self.styles.clone().unwrap_or_default(), modules: HashMap::new(), - cache: HashMap::new(), route: vec![], deps: vec![], flow: None, } } } - -/// An entry in the query cache. -struct CacheEntry { - /// The query's results. - data: Box<dyn Any>, - /// How many evictions have passed since the entry has been last used. - age: usize, -} - -impl Context { - /// Execute a query. - /// - /// This hashes all inputs to the query and then either returns a cached - /// version or executes the query, saves the results in the cache and - /// returns a reference to them. - pub fn query<I, O>( - &mut self, - input: I, - query: fn(ctx: &mut Self, input: I) -> O, - ) -> &O - where - I: Hash, - O: 'static, - { - let hash = fxhash::hash64(&input); - if !self.cache.contains_key(&hash) { - let output = query(self, input); - self.cache.insert(hash, CacheEntry { data: Box::new(output), age: 0 }); - } - - let entry = self.cache.get_mut(&hash).unwrap(); - entry.age = 0; - entry.data.downcast_ref().expect("oh no, a hash collision") - } - - /// Garbage-collect the query cache. This deletes elements which haven't - /// been used in a while. - /// - /// Returns details about the eviction. - pub fn evict(&mut self) -> Eviction { - const MAX_AGE: usize = 5; - - let before = self.cache.len(); - self.cache.retain(|_, entry| { - entry.age += 1; - entry.age <= MAX_AGE - }); - - Eviction { before, after: self.cache.len() } - } -} - -/// Details about a cache eviction. -pub struct Eviction { - /// The number of items in the cache before the eviction. - pub before: usize, - /// The number of items in the cache after the eviction. - pub after: usize, -} - -impl Display for Eviction { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - writeln!(f, "Before: {}", self.before)?; - writeln!(f, "Evicted: {}", self.before - self.after)?; - writeln!(f, "After: {}", self.after) - } -} |
