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

View File

@ -30,10 +30,6 @@ impl Query for ParentModule {
}
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> {
let file = ctx.get::<FileSyntax>(file_id);
Arc::new(descr::ModuleDescr::new(file.ast()))