mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 05:38:46 +00:00
any-cache
This commit is contained in:
parent
dbdf72e2e2
commit
907d44a751
2 changed files with 18 additions and 21 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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()))
|
||||||
|
|
Loading…
Reference in a new issue