any-cache

This commit is contained in:
Aleksey Kladov 2018-09-12 17:13:11 +03:00
parent dbdf72e2e2
commit 907d44a751
2 changed files with 18 additions and 21 deletions

View file

@ -3,6 +3,7 @@ use std::{
sync::Arc, sync::Arc,
cell::RefCell, cell::RefCell,
fmt::Debug, fmt::Debug,
any::Any,
}; };
use parking_lot::Mutex; use parking_lot::Mutex;
use libsyntax2::{File}; use libsyntax2::{File};
@ -10,7 +11,6 @@ use im;
use { use {
FileId, FileId,
imp::{FileResolverImp}, imp::{FileResolverImp},
module_map_db::ModuleDescr,
}; };
#[derive(Debug)] #[derive(Debug)]
@ -94,11 +94,13 @@ impl Clone for Db {
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub(crate) struct Cache { pub(crate) struct Cache {
pub(crate) module_descr: QueryCache<ModuleDescr>,
gen: Gen, gen: Gen,
green: im::HashMap<QueryInvocationId, (Gen, OutputHash)>, green: im::HashMap<QueryInvocationId, (Gen, OutputHash)>,
deps: im::HashMap<QueryInvocationId, Vec<(QueryInvocationId, OutputHash)>>, deps: im::HashMap<QueryInvocationId, Vec<(QueryInvocationId, OutputHash)>>,
results: im::HashMap<QueryInvocationId, Arc<Any>>,
} }
#[allow(type_alias_bounds)] #[allow(type_alias_bounds)]
pub(crate) type QueryCache<Q: Query> = im::HashMap< pub(crate) type QueryCache<Q: Query> = im::HashMap<
<Q as Query>::Params, <Q as Query>::Params,
@ -109,6 +111,15 @@ impl Cache {
fn new() -> Cache { fn new() -> Cache {
Default::default() Default::default()
} }
fn get_result<Q: Query>(&self, id: QueryInvocationId) -> Q::Output
where
Q::Output: Clone
{
let res = &self.results[&id];
let res = res.downcast_ref::<Q::Output>().unwrap();
res.clone()
}
} }
pub(crate) struct QueryCtx { pub(crate) struct QueryCtx {
@ -150,8 +161,8 @@ impl QueryCtx {
pub(crate) trait Query { pub(crate) trait Query {
const ID: u32; const ID: u32;
type Params: Hash + Eq + Debug; type Params: Hash + Eq + Debug + Any + 'static;
type Output: Hash + Debug; type Output: Hash + Debug + Any + 'static;
} }
pub(crate) trait Get: Query { pub(crate) trait Get: Query {
@ -164,11 +175,6 @@ where
Q::Output: Clone, Q::Output: Clone,
{ {
fn get(ctx: &QueryCtx, params: &Self::Params) -> Self::Output { fn get(ctx: &QueryCtx, params: &Self::Params) -> Self::Output {
if !Self::cacheable() {
ctx.trace(TraceEvent { query_id: Q::ID, kind: TraceEventKind::Evaluating });
return Self::eval(ctx, params);
}
if let Some(res) = try_reuse::<Q>(ctx, params) { if let Some(res) = try_reuse::<Q>(ctx, params) {
return res; return res;
} }
@ -185,8 +191,7 @@ where
let output_hash = output_hash::<Q>(&res); let output_hash = output_hash::<Q>(&res);
let id = id::<Q>(params); let id = id::<Q>(params);
cache.green.insert(id, (gen, output_hash)); cache.green.insert(id, (gen, output_hash));
let cache = Self::cache(&mut cache); cache.results.insert(me, Arc::new(res.clone()));
cache.insert(params.clone(), res.clone());
res res
} }
} }
@ -201,7 +206,7 @@ where
let curr_gen = cache.gen; let curr_gen = cache.gen;
let old_hash = match *cache.green.get(&id)? { let old_hash = match *cache.green.get(&id)? {
(gen, _) if gen == curr_gen => { (gen, _) if gen == curr_gen => {
return Some(Q::cache(&mut cache)[params].clone()); return Some(cache.get_result::<Q>(id));
} }
(_, hash) => hash, (_, hash) => hash,
}; };
@ -218,7 +223,7 @@ where
return None; return None;
} }
cache.green.insert(id, (curr_gen, old_hash)); cache.green.insert(id, (curr_gen, old_hash));
Some(Q::cache(&mut cache)[params].clone()) Some(cache.get_result::<Q>(id))
} }
pub(crate) trait Eval: Query pub(crate) trait Eval: Query
@ -226,10 +231,6 @@ where
Self::Params: Clone, Self::Params: Clone,
Self::Output: Clone, Self::Output: Clone,
{ {
fn cacheable() -> bool { false }
fn cache(_cache: &mut Cache) -> &mut QueryCache<Self> {
unimplemented!()
}
fn eval(ctx: &QueryCtx, params: &Self::Params) -> Self::Output; fn eval(ctx: &QueryCtx, params: &Self::Params) -> Self::Output;
} }

View file

@ -30,10 +30,6 @@ impl Query for ParentModule {
} }
impl Eval for ModuleDescr { impl Eval for ModuleDescr {
fn cacheable() -> bool { true }
fn cache(cache: &mut Cache) -> &mut QueryCache<Self> {
&mut cache.module_descr
}
fn eval(ctx: &QueryCtx, file_id: &FileId) -> Arc<descr::ModuleDescr> { fn eval(ctx: &QueryCtx, file_id: &FileId) -> Arc<descr::ModuleDescr> {
let file = ctx.get::<FileSyntax>(file_id); let file = ctx.get::<FileSyntax>(file_id);
Arc::new(descr::ModuleDescr::new(file.ast())) Arc::new(descr::ModuleDescr::new(file.ast()))