any-cache
This commit is contained in:
parent
dbdf72e2e2
commit
907d44a751
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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()))
|
||||
|
Loading…
Reference in New Issue
Block a user