aboutsummaryrefslogtreecommitdiff
path: root/crates/libanalysis/src/db.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/libanalysis/src/db.rs')
-rw-r--r--crates/libanalysis/src/db.rs116
1 files changed, 94 insertions, 22 deletions
diff --git a/crates/libanalysis/src/db.rs b/crates/libanalysis/src/db.rs
index 5e3c8fb7a..31c73c402 100644
--- a/crates/libanalysis/src/db.rs
+++ b/crates/libanalysis/src/db.rs
@@ -2,50 +2,95 @@ use std::{
2 hash::Hash, 2 hash::Hash,
3 sync::Arc, 3 sync::Arc,
4 cell::RefCell, 4 cell::RefCell,
5 fmt::Debug,
5}; 6};
7use parking_lot::Mutex;
6use libsyntax2::{File}; 8use libsyntax2::{File};
7use im; 9use im;
8use { 10use {
9 FileId, 11 FileId,
10 imp::{FileResolverImp}, 12 imp::{FileResolverImp},
13 module_map_db::ModuleDescr,
11}; 14};
12 15
13#[derive(Clone)] 16#[derive(Debug)]
14pub(crate) struct Db { 17pub(crate) struct DbHost {
15 file_resolver: FileResolverImp, 18 db: Arc<Db>,
16 files: im::HashMap<FileId, Arc<String>>,
17} 19}
18 20
19impl Db { 21impl DbHost {
20 pub(crate) fn new() -> Db { 22 pub(crate) fn new() -> DbHost {
21 Db { 23 let db = Db {
22 file_resolver: FileResolverImp::default(), 24 file_resolver: FileResolverImp::default(),
23 files: im::HashMap::new(), 25 files: im::HashMap::new(),
24 } 26 cache: Mutex::new(Cache::new())
27 };
28 DbHost { db: Arc::new(db) }
25 } 29 }
26 pub(crate) fn change_file(&mut self, file_id: FileId, text: Option<String>) { 30 pub(crate) fn change_file(&mut self, file_id: FileId, text: Option<String>) {
31 let db = self.db_mut();
27 match text { 32 match text {
28 None => { 33 None => {
29 self.files.remove(&file_id); 34 db.files.remove(&file_id);
30 } 35 }
31 Some(text) => { 36 Some(text) => {
32 self.files.insert(file_id, Arc::new(text)); 37 db.files.insert(file_id, Arc::new(text));
33 } 38 }
34 } 39 }
35 } 40 }
36 pub(crate) fn set_file_resolver(&mut self, file_resolver: FileResolverImp) { 41 pub(crate) fn set_file_resolver(&mut self, file_resolver: FileResolverImp) {
37 self.file_resolver = file_resolver 42 let db = self.db_mut();
43 db.file_resolver = file_resolver
38 } 44 }
39 pub(crate) fn query_ctx(&self) -> QueryCtx { 45 pub(crate) fn query_ctx(&self) -> QueryCtx {
40 QueryCtx { 46 QueryCtx {
41 db: self.clone(), 47 db: Arc::clone(&self.db),
42 trace: RefCell::new(Vec::new()), 48 trace: RefCell::new(Vec::new()),
43 } 49 }
44 } 50 }
51 fn db_mut(&mut self) -> &mut Db {
52 // NB: this "forks" the database & clears the cache
53 let db = Arc::make_mut(&mut self.db);
54 *db.cache.get_mut() = Default::default();
55 db
56 }
57}
58
59#[derive(Debug)]
60pub(crate) struct Db {
61 file_resolver: FileResolverImp,
62 files: im::HashMap<FileId, Arc<String>>,
63 cache: Mutex<Cache>,
64}
65
66impl Clone for Db {
67 fn clone(&self) -> Db {
68 Db {
69 file_resolver: self.file_resolver.clone(),
70 files: self.files.clone(),
71 cache: Mutex::new(Cache::new()),
72 }
73 }
74}
75
76#[derive(Clone, Default, Debug)]
77pub(crate) struct Cache {
78 pub(crate) module_descr: QueryCache<ModuleDescr>
79}
80#[allow(type_alias_bounds)]
81pub(crate) type QueryCache<Q: Query> = im::HashMap<
82 <Q as Query>::Params,
83 <Q as Query>::Output
84>;
85
86impl Cache {
87 fn new() -> Cache {
88 Default::default()
89 }
45} 90}
46 91
47pub(crate) struct QueryCtx { 92pub(crate) struct QueryCtx {
48 db: Db, 93 db: Arc<Db>,
49 pub(crate) trace: RefCell<Vec<TraceEvent>>, 94 pub(crate) trace: RefCell<Vec<TraceEvent>>,
50} 95}
51 96
@@ -62,9 +107,7 @@ pub(crate) enum TraceEventKind {
62 107
63impl QueryCtx { 108impl QueryCtx {
64 pub(crate) fn get<Q: Get>(&self, params: &Q::Params) -> Q::Output { 109 pub(crate) fn get<Q: Get>(&self, params: &Q::Params) -> Q::Output {
65 self.trace(TraceEvent { query_id: Q::ID, kind: TraceEventKind::Start });
66 let res = Q::get(self, params); 110 let res = Q::get(self, params);
67 self.trace(TraceEvent { query_id: Q::ID, kind: TraceEventKind::Finish });
68 res 111 res
69 } 112 }
70 fn trace(&self, event: TraceEvent) { 113 fn trace(&self, event: TraceEvent) {
@@ -74,26 +117,55 @@ impl QueryCtx {
74 117
75pub(crate) trait Query { 118pub(crate) trait Query {
76 const ID: u32; 119 const ID: u32;
77 type Params: Hash; 120 type Params: Hash + Eq + Debug;
78 type Output; 121 type Output: Debug;
79} 122}
80 123
81pub(crate) trait Get: Query { 124pub(crate) trait Get: Query {
82 fn get(ctx: &QueryCtx, params: &Self::Params) -> Self::Output; 125 fn get(ctx: &QueryCtx, params: &Self::Params) -> Self::Output;
83} 126}
84 127
85impl<T: Eval> Get for T { 128impl<T: Eval> Get for T
129where
130 T::Params: Clone,
131 T::Output: Clone,
132{
86 fn get(ctx: &QueryCtx, params: &Self::Params) -> Self::Output { 133 fn get(ctx: &QueryCtx, params: &Self::Params) -> Self::Output {
87 Self::eval(ctx, params) 134 {
135 let mut cache = ctx.db.cache.lock();
136 if let Some(cache) = Self::cache(&mut cache) {
137 if let Some(res) = cache.get(params) {
138 return res.clone();
139 }
140 }
141 }
142 ctx.trace(TraceEvent { query_id: Self::ID, kind: TraceEventKind::Start });
143 let res = Self::eval(ctx, params);
144 ctx.trace(TraceEvent { query_id: Self::ID, kind: TraceEventKind::Finish });
145
146 let mut cache = ctx.db.cache.lock();
147 if let Some(cache) = Self::cache(&mut cache) {
148 cache.insert(params.clone(), res.clone());
149 }
150
151 res
88 } 152 }
89} 153}
90 154
91pub(crate) trait Eval: Query { 155pub(crate) trait Eval: Query
156where
157 Self::Params: Clone,
158 Self::Output: Clone,
159 {
160 fn cache(_cache: &mut Cache) -> Option<&mut QueryCache<Self>> {
161 None
162 }
92 fn eval(ctx: &QueryCtx, params: &Self::Params) -> Self::Output; 163 fn eval(ctx: &QueryCtx, params: &Self::Params) -> Self::Output;
93} 164}
94 165
166#[derive(Debug)]
95pub(crate) struct DbFiles { 167pub(crate) struct DbFiles {
96 db: Db, 168 db: Arc<Db>,
97} 169}
98 170
99impl DbFiles { 171impl DbFiles {
@@ -113,7 +185,7 @@ impl Query for Files {
113} 185}
114impl Get for Files { 186impl Get for Files {
115 fn get(ctx: &QueryCtx, _params: &()) -> DbFiles { 187 fn get(ctx: &QueryCtx, _params: &()) -> DbFiles {
116 DbFiles { db: ctx.db.clone() } 188 DbFiles { db: Arc::clone(&ctx.db) }
117 } 189 }
118} 190}
119 191