aboutsummaryrefslogtreecommitdiff
path: root/crates/libanalysis/src
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-09-10 18:48:32 +0100
committerAleksey Kladov <[email protected]>2018-09-15 22:00:05 +0100
commit3ae3b3eb0682a4550578b4c35dc6e099d8a04e66 (patch)
tree8bd66ec01b5ec07ca74d2e16250469fe98bc8627 /crates/libanalysis/src
parent99d02fe583f4747f67debc1973a3eb3ca62e2005 (diff)
initial query tracing
Diffstat (limited to 'crates/libanalysis/src')
-rw-r--r--crates/libanalysis/src/db.rs28
-rw-r--r--crates/libanalysis/src/module_map_db.rs40
2 files changed, 55 insertions, 13 deletions
diff --git a/crates/libanalysis/src/db.rs b/crates/libanalysis/src/db.rs
index 335c79e76..5e3c8fb7a 100644
--- a/crates/libanalysis/src/db.rs
+++ b/crates/libanalysis/src/db.rs
@@ -1,6 +1,7 @@
1use std::{ 1use std::{
2 hash::Hash, 2 hash::Hash,
3 sync::Arc, 3 sync::Arc,
4 cell::RefCell,
4}; 5};
5use libsyntax2::{File}; 6use libsyntax2::{File};
6use im; 7use im;
@@ -36,17 +37,38 @@ impl Db {
36 self.file_resolver = file_resolver 37 self.file_resolver = file_resolver
37 } 38 }
38 pub(crate) fn query_ctx(&self) -> QueryCtx { 39 pub(crate) fn query_ctx(&self) -> QueryCtx {
39 QueryCtx { db: self.clone() } 40 QueryCtx {
41 db: self.clone(),
42 trace: RefCell::new(Vec::new()),
43 }
40 } 44 }
41} 45}
42 46
43pub(crate) struct QueryCtx { 47pub(crate) struct QueryCtx {
44 db: Db 48 db: Db,
49 pub(crate) trace: RefCell<Vec<TraceEvent>>,
50}
51
52#[derive(Clone, Copy, Debug)]
53pub(crate) struct TraceEvent {
54 pub(crate) query_id: u32,
55 pub(crate) kind: TraceEventKind
56}
57
58#[derive(Clone, Copy, Debug, PartialEq, Eq)]
59pub(crate) enum TraceEventKind {
60 Start, Finish
45} 61}
46 62
47impl QueryCtx { 63impl QueryCtx {
48 pub(crate) fn get<Q: Get>(&self, params: &Q::Params) -> Q::Output { 64 pub(crate) fn get<Q: Get>(&self, params: &Q::Params) -> Q::Output {
49 Q::get(self, params) 65 self.trace(TraceEvent { query_id: Q::ID, kind: TraceEventKind::Start });
66 let res = Q::get(self, params);
67 self.trace(TraceEvent { query_id: Q::ID, kind: TraceEventKind::Finish });
68 res
69 }
70 fn trace(&self, event: TraceEvent) {
71 self.trace.borrow_mut().push(event)
50 } 72 }
51} 73}
52 74
diff --git a/crates/libanalysis/src/module_map_db.rs b/crates/libanalysis/src/module_map_db.rs
index 1ef87ab3f..25dbe8dd4 100644
--- a/crates/libanalysis/src/module_map_db.rs
+++ b/crates/libanalysis/src/module_map_db.rs
@@ -94,14 +94,15 @@ mod descr {
94 94
95#[cfg(test)] 95#[cfg(test)]
96mod tests { 96mod tests {
97 use super::*; 97 use std::collections::HashMap;
98 use im; 98 use im;
99 use relative_path::{RelativePath, RelativePathBuf}; 99 use relative_path::{RelativePath, RelativePathBuf};
100 use { 100 use {
101 db::Db, 101 db::{Query, Db, TraceEventKind},
102 imp::FileResolverImp, 102 imp::FileResolverImp,
103 FileId, FileResolver, 103 FileId, FileResolver,
104 }; 104 };
105 use super::*;
105 106
106 #[derive(Debug)] 107 #[derive(Debug)]
107 struct FileMap(im::HashMap<FileId, RelativePathBuf>); 108 struct FileMap(im::HashMap<FileId, RelativePathBuf>);
@@ -154,10 +155,29 @@ mod tests {
154 fn change_file(&mut self, file_id: FileId, new_text: &str) { 155 fn change_file(&mut self, file_id: FileId, new_text: &str) {
155 self.db.change_file(file_id, Some(new_text.to_string())); 156 self.db.change_file(file_id, Some(new_text.to_string()));
156 } 157 }
157 fn check_parent_modules(&self, file_id: FileId, expected: &[FileId]) { 158 fn check_parent_modules(
159 &self,
160 file_id: FileId,
161 expected: &[FileId],
162 queries: &[(u32, u64)]
163 ) {
158 let ctx = self.db.query_ctx(); 164 let ctx = self.db.query_ctx();
159 let actual = ctx.get::<ParentModule>(&file_id); 165 let actual = ctx.get::<ParentModule>(&file_id);
160 assert_eq!(actual.as_slice(), expected); 166 assert_eq!(actual.as_slice(), expected);
167 let mut counts = HashMap::new();
168 ctx.trace.borrow().iter()
169 .filter(|event| event.kind == TraceEventKind::Start)
170 .for_each(|event| *counts.entry(event.query_id).or_insert(0) += 1);
171 for &(query_id, expected_count) in queries.iter() {
172 let actual_count = *counts.get(&query_id).unwrap_or(&0);
173 assert_eq!(
174 actual_count,
175 expected_count,
176 "counts for {} differ",
177 query_id,
178 )
179 }
180
161 } 181 }
162 } 182 }
163 183
@@ -165,25 +185,25 @@ mod tests {
165 fn test_parent_module() { 185 fn test_parent_module() {
166 let mut f = Fixture::new(); 186 let mut f = Fixture::new();
167 let foo = f.add_file("/foo.rs", ""); 187 let foo = f.add_file("/foo.rs", "");
168 f.check_parent_modules(foo, &[]); 188 f.check_parent_modules(foo, &[], &[(FileSyntax::ID, 1)]);
169 189
170 let lib = f.add_file("/lib.rs", "mod foo;"); 190 let lib = f.add_file("/lib.rs", "mod foo;");
171 f.check_parent_modules(foo, &[lib]); 191 f.check_parent_modules(foo, &[lib], &[(FileSyntax::ID, 2)]);
172 192
173 f.change_file(lib, ""); 193 f.change_file(lib, "");
174 f.check_parent_modules(foo, &[]); 194 f.check_parent_modules(foo, &[], &[(ModuleDescr::ID, 2)]);
175 195
176 f.change_file(lib, "mod foo;"); 196 f.change_file(lib, "mod foo;");
177 f.check_parent_modules(foo, &[lib]); 197 f.check_parent_modules(foo, &[lib], &[(ModuleDescr::ID, 2)]);
178 198
179 f.change_file(lib, "mod bar;"); 199 f.change_file(lib, "mod bar;");
180 f.check_parent_modules(foo, &[]); 200 f.check_parent_modules(foo, &[], &[(ModuleDescr::ID, 2)]);
181 201
182 f.change_file(lib, "mod foo;"); 202 f.change_file(lib, "mod foo;");
183 f.check_parent_modules(foo, &[lib]); 203 f.check_parent_modules(foo, &[lib], &[(ModuleDescr::ID, 2)]);
184 204
185 f.remove_file(lib); 205 f.remove_file(lib);
186 f.check_parent_modules(foo, &[]); 206 f.check_parent_modules(foo, &[], &[(ModuleDescr::ID, 1)]);
187 } 207 }
188 208
189} 209}