diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-10-02 16:50:20 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-10-02 16:50:20 +0100 |
commit | 673e1ddb9ae12c565f966549ba7ea8c306cfba87 (patch) | |
tree | a1d9c304711806c393163547fe6da69289aa9f16 /crates/ide_db/src/apply_change.rs | |
parent | a360832c95dbfe10167ebebe4978760e9be6a4bd (diff) | |
parent | b06259673f9b535a63c0cabf4eeb935ff73d86d0 (diff) |
Merge #6123
6123: Reduce duplication in fixtures r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ide_db/src/apply_change.rs')
-rw-r--r-- | crates/ide_db/src/apply_change.rs | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/crates/ide_db/src/apply_change.rs b/crates/ide_db/src/apply_change.rs new file mode 100644 index 000000000..da16fa21d --- /dev/null +++ b/crates/ide_db/src/apply_change.rs | |||
@@ -0,0 +1,239 @@ | |||
1 | //! Applies changes to the IDE state transactionally. | ||
2 | |||
3 | use std::{fmt, sync::Arc}; | ||
4 | |||
5 | use base_db::{ | ||
6 | salsa::{Database, Durability, SweepStrategy}, | ||
7 | Change, FileId, SourceRootId, | ||
8 | }; | ||
9 | use profile::{memory_usage, Bytes}; | ||
10 | use rustc_hash::FxHashSet; | ||
11 | |||
12 | use crate::{symbol_index::SymbolsDatabase, RootDatabase}; | ||
13 | |||
14 | #[derive(Debug)] | ||
15 | struct AddFile { | ||
16 | file_id: FileId, | ||
17 | path: String, | ||
18 | text: Arc<String>, | ||
19 | } | ||
20 | |||
21 | #[derive(Debug)] | ||
22 | struct RemoveFile { | ||
23 | file_id: FileId, | ||
24 | path: String, | ||
25 | } | ||
26 | |||
27 | #[derive(Default)] | ||
28 | struct RootChange { | ||
29 | added: Vec<AddFile>, | ||
30 | removed: Vec<RemoveFile>, | ||
31 | } | ||
32 | |||
33 | impl fmt::Debug for RootChange { | ||
34 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||
35 | fmt.debug_struct("AnalysisChange") | ||
36 | .field("added", &self.added.len()) | ||
37 | .field("removed", &self.removed.len()) | ||
38 | .finish() | ||
39 | } | ||
40 | } | ||
41 | |||
42 | impl RootDatabase { | ||
43 | pub fn request_cancellation(&mut self) { | ||
44 | let _p = profile::span("RootDatabase::request_cancellation"); | ||
45 | self.salsa_runtime_mut().synthetic_write(Durability::LOW); | ||
46 | } | ||
47 | |||
48 | pub fn apply_change(&mut self, change: Change) { | ||
49 | let _p = profile::span("RootDatabase::apply_change"); | ||
50 | self.request_cancellation(); | ||
51 | log::info!("apply_change {:?}", change); | ||
52 | if let Some(roots) = &change.roots { | ||
53 | let mut local_roots = FxHashSet::default(); | ||
54 | let mut library_roots = FxHashSet::default(); | ||
55 | for (idx, root) in roots.iter().enumerate() { | ||
56 | let root_id = SourceRootId(idx as u32); | ||
57 | if root.is_library { | ||
58 | library_roots.insert(root_id); | ||
59 | } else { | ||
60 | local_roots.insert(root_id); | ||
61 | } | ||
62 | } | ||
63 | self.set_local_roots_with_durability(Arc::new(local_roots), Durability::HIGH); | ||
64 | self.set_library_roots_with_durability(Arc::new(library_roots), Durability::HIGH); | ||
65 | } | ||
66 | change.apply(self); | ||
67 | } | ||
68 | |||
69 | pub fn collect_garbage(&mut self) { | ||
70 | if cfg!(feature = "wasm") { | ||
71 | return; | ||
72 | } | ||
73 | |||
74 | let _p = profile::span("RootDatabase::collect_garbage"); | ||
75 | |||
76 | let sweep = SweepStrategy::default().discard_values().sweep_all_revisions(); | ||
77 | |||
78 | base_db::ParseQuery.in_db(self).sweep(sweep); | ||
79 | hir::db::ParseMacroQuery.in_db(self).sweep(sweep); | ||
80 | |||
81 | // Macros do take significant space, but less then the syntax trees | ||
82 | // self.query(hir::db::MacroDefQuery).sweep(sweep); | ||
83 | // self.query(hir::db::MacroArgTextQuery).sweep(sweep); | ||
84 | // self.query(hir::db::MacroExpandQuery).sweep(sweep); | ||
85 | |||
86 | hir::db::AstIdMapQuery.in_db(self).sweep(sweep); | ||
87 | |||
88 | hir::db::BodyWithSourceMapQuery.in_db(self).sweep(sweep); | ||
89 | |||
90 | hir::db::ExprScopesQuery.in_db(self).sweep(sweep); | ||
91 | hir::db::InferQueryQuery.in_db(self).sweep(sweep); | ||
92 | hir::db::BodyQuery.in_db(self).sweep(sweep); | ||
93 | } | ||
94 | |||
95 | // Feature: Memory Usage | ||
96 | // | ||
97 | // Clears rust-analyzer's internal database and prints memory usage statistics. | ||
98 | // | ||
99 | // |=== | ||
100 | // | Editor | Action Name | ||
101 | // | ||
102 | // | VS Code | **Rust Analyzer: Memory Usage (Clears Database)** | ||
103 | // |=== | ||
104 | pub fn per_query_memory_usage(&mut self) -> Vec<(String, Bytes)> { | ||
105 | let mut acc: Vec<(String, Bytes)> = vec![]; | ||
106 | let sweep = SweepStrategy::default().discard_values().sweep_all_revisions(); | ||
107 | macro_rules! sweep_each_query { | ||
108 | ($($q:path)*) => {$( | ||
109 | let before = memory_usage().allocated; | ||
110 | $q.in_db(self).sweep(sweep); | ||
111 | let after = memory_usage().allocated; | ||
112 | let q: $q = Default::default(); | ||
113 | let name = format!("{:?}", q); | ||
114 | acc.push((name, before - after)); | ||
115 | |||
116 | let before = memory_usage().allocated; | ||
117 | $q.in_db(self).sweep(sweep.discard_everything()); | ||
118 | let after = memory_usage().allocated; | ||
119 | let q: $q = Default::default(); | ||
120 | let name = format!("{:?} (deps)", q); | ||
121 | acc.push((name, before - after)); | ||
122 | |||
123 | let before = memory_usage().allocated; | ||
124 | $q.in_db(self).purge(); | ||
125 | let after = memory_usage().allocated; | ||
126 | let q: $q = Default::default(); | ||
127 | let name = format!("{:?} (purge)", q); | ||
128 | acc.push((name, before - after)); | ||
129 | )*} | ||
130 | } | ||
131 | sweep_each_query![ | ||
132 | // SourceDatabase | ||
133 | base_db::ParseQuery | ||
134 | base_db::CrateGraphQuery | ||
135 | |||
136 | // SourceDatabaseExt | ||
137 | base_db::FileTextQuery | ||
138 | base_db::FileSourceRootQuery | ||
139 | base_db::SourceRootQuery | ||
140 | base_db::SourceRootCratesQuery | ||
141 | |||
142 | // AstDatabase | ||
143 | hir::db::AstIdMapQuery | ||
144 | hir::db::MacroArgTextQuery | ||
145 | hir::db::MacroDefQuery | ||
146 | hir::db::ParseMacroQuery | ||
147 | hir::db::MacroExpandQuery | ||
148 | |||
149 | // DefDatabase | ||
150 | hir::db::ItemTreeQuery | ||
151 | hir::db::CrateDefMapQueryQuery | ||
152 | hir::db::StructDataQuery | ||
153 | hir::db::UnionDataQuery | ||
154 | hir::db::EnumDataQuery | ||
155 | hir::db::ImplDataQuery | ||
156 | hir::db::TraitDataQuery | ||
157 | hir::db::TypeAliasDataQuery | ||
158 | hir::db::FunctionDataQuery | ||
159 | hir::db::ConstDataQuery | ||
160 | hir::db::StaticDataQuery | ||
161 | hir::db::BodyWithSourceMapQuery | ||
162 | hir::db::BodyQuery | ||
163 | hir::db::ExprScopesQuery | ||
164 | hir::db::GenericParamsQuery | ||
165 | hir::db::AttrsQuery | ||
166 | hir::db::ModuleLangItemsQuery | ||
167 | hir::db::CrateLangItemsQuery | ||
168 | hir::db::LangItemQuery | ||
169 | hir::db::DocumentationQuery | ||
170 | hir::db::ImportMapQuery | ||
171 | |||
172 | // HirDatabase | ||
173 | hir::db::InferQueryQuery | ||
174 | hir::db::TyQuery | ||
175 | hir::db::ValueTyQuery | ||
176 | hir::db::ImplSelfTyQuery | ||
177 | hir::db::ImplTraitQuery | ||
178 | hir::db::FieldTypesQuery | ||
179 | hir::db::CallableItemSignatureQuery | ||
180 | hir::db::GenericPredicatesForParamQuery | ||
181 | hir::db::GenericPredicatesQuery | ||
182 | hir::db::GenericDefaultsQuery | ||
183 | hir::db::InherentImplsInCrateQuery | ||
184 | hir::db::TraitImplsInCrateQuery | ||
185 | hir::db::TraitImplsInDepsQuery | ||
186 | hir::db::AssociatedTyDataQuery | ||
187 | hir::db::AssociatedTyDataQuery | ||
188 | hir::db::TraitDatumQuery | ||
189 | hir::db::StructDatumQuery | ||
190 | hir::db::ImplDatumQuery | ||
191 | hir::db::FnDefDatumQuery | ||
192 | hir::db::ReturnTypeImplTraitsQuery | ||
193 | hir::db::InternCallableDefQuery | ||
194 | hir::db::InternTypeParamIdQuery | ||
195 | hir::db::InternImplTraitIdQuery | ||
196 | hir::db::InternClosureQuery | ||
197 | hir::db::AssociatedTyValueQuery | ||
198 | hir::db::TraitSolveQuery | ||
199 | |||
200 | // SymbolsDatabase | ||
201 | crate::symbol_index::FileSymbolsQuery | ||
202 | crate::symbol_index::LibrarySymbolsQuery | ||
203 | crate::symbol_index::LocalRootsQuery | ||
204 | crate::symbol_index::LibraryRootsQuery | ||
205 | |||
206 | // LineIndexDatabase | ||
207 | crate::LineIndexQuery | ||
208 | ]; | ||
209 | |||
210 | // To collect interned data, we need to bump the revision counter by performing a synthetic | ||
211 | // write. | ||
212 | // We do this after collecting the non-interned queries to correctly attribute memory used | ||
213 | // by interned data. | ||
214 | self.salsa_runtime_mut().synthetic_write(Durability::HIGH); | ||
215 | |||
216 | sweep_each_query![ | ||
217 | // AstDatabase | ||
218 | hir::db::InternMacroQuery | ||
219 | hir::db::InternEagerExpansionQuery | ||
220 | |||
221 | // InternDatabase | ||
222 | hir::db::InternFunctionQuery | ||
223 | hir::db::InternStructQuery | ||
224 | hir::db::InternUnionQuery | ||
225 | hir::db::InternEnumQuery | ||
226 | hir::db::InternConstQuery | ||
227 | hir::db::InternStaticQuery | ||
228 | hir::db::InternTraitQuery | ||
229 | hir::db::InternTypeAliasQuery | ||
230 | hir::db::InternImplQuery | ||
231 | |||
232 | // HirDatabase | ||
233 | hir::db::InternTypeParamIdQuery | ||
234 | ]; | ||
235 | |||
236 | acc.sort_by_key(|it| std::cmp::Reverse(it.1)); | ||
237 | acc | ||
238 | } | ||
239 | } | ||