summaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs76
1 files changed, 2 insertions, 74 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 06324c11..5173b022 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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)
- }
-}