diff options
Diffstat (limited to 'crates/ra_ide_api/src/imp.rs')
-rw-r--r-- | crates/ra_ide_api/src/imp.rs | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/crates/ra_ide_api/src/imp.rs b/crates/ra_ide_api/src/imp.rs index 399433a01..31e0f5d6d 100644 --- a/crates/ra_ide_api/src/imp.rs +++ b/crates/ra_ide_api/src/imp.rs | |||
@@ -1,4 +1,7 @@ | |||
1 | use std::sync::Arc; | 1 | use std::{ |
2 | sync::Arc, | ||
3 | time, | ||
4 | }; | ||
2 | 5 | ||
3 | use hir::{ | 6 | use hir::{ |
4 | self, Problem, source_binder | 7 | self, Problem, source_binder |
@@ -19,12 +22,14 @@ use crate::{ | |||
19 | CrateId, db, Diagnostic, FileId, FilePosition, FileRange, FileSystemEdit, | 22 | CrateId, db, Diagnostic, FileId, FilePosition, FileRange, FileSystemEdit, |
20 | Query, RootChange, SourceChange, SourceFileEdit, | 23 | Query, RootChange, SourceChange, SourceFileEdit, |
21 | symbol_index::{FileSymbol, SymbolsDatabase}, | 24 | symbol_index::{FileSymbol, SymbolsDatabase}, |
25 | status::syntax_tree_stats | ||
22 | }; | 26 | }; |
23 | 27 | ||
28 | const GC_COOLDOWN: time::Duration = time::Duration::from_millis(100); | ||
29 | |||
24 | impl db::RootDatabase { | 30 | impl db::RootDatabase { |
25 | pub(crate) fn apply_change(&mut self, change: AnalysisChange) { | 31 | pub(crate) fn apply_change(&mut self, change: AnalysisChange) { |
26 | log::info!("apply_change {:?}", change); | 32 | log::info!("apply_change {:?}", change); |
27 | // self.gc_syntax_trees(); | ||
28 | if !change.new_roots.is_empty() { | 33 | if !change.new_roots.is_empty() { |
29 | let mut local_roots = Vec::clone(&self.local_roots()); | 34 | let mut local_roots = Vec::clone(&self.local_roots()); |
30 | for (root_id, is_local) in change.new_roots { | 35 | for (root_id, is_local) in change.new_roots { |
@@ -72,18 +77,36 @@ impl db::RootDatabase { | |||
72 | self.set_source_root(root_id, Arc::new(source_root)); | 77 | self.set_source_root(root_id, Arc::new(source_root)); |
73 | } | 78 | } |
74 | 79 | ||
75 | /// Ideally, we should call this function from time to time to collect heavy | 80 | pub(crate) fn maybe_collect_garbage(&mut self) { |
76 | /// syntax trees. However, if we actually do that, everything is recomputed | 81 | if self.last_gc_check.elapsed() > GC_COOLDOWN { |
77 | /// for some reason. Needs investigation. | 82 | self.last_gc_check = time::Instant::now(); |
83 | let retained_trees = syntax_tree_stats(self).retained; | ||
84 | if retained_trees > 100 { | ||
85 | log::info!( | ||
86 | "automatic garbadge collection, {} retained trees", | ||
87 | retained_trees | ||
88 | ); | ||
89 | self.collect_garbage(); | ||
90 | } | ||
91 | } | ||
92 | } | ||
93 | |||
78 | pub(crate) fn collect_garbage(&mut self) { | 94 | pub(crate) fn collect_garbage(&mut self) { |
79 | self.query(ra_db::ParseQuery) | 95 | self.last_gc = time::Instant::now(); |
80 | .sweep(SweepStrategy::default().discard_values()); | 96 | |
81 | self.query(hir::db::HirParseQuery) | 97 | let sweep = SweepStrategy::default() |
82 | .sweep(SweepStrategy::default().discard_values()); | 98 | .discard_values() |
83 | self.query(hir::db::FileItemsQuery) | 99 | .sweep_all_revisions(); |
84 | .sweep(SweepStrategy::default().discard_values()); | 100 | |
85 | self.query(hir::db::FileItemQuery) | 101 | self.query(ra_db::ParseQuery).sweep(sweep); |
86 | .sweep(SweepStrategy::default().discard_values()); | 102 | |
103 | self.query(hir::db::HirParseQuery).sweep(sweep); | ||
104 | self.query(hir::db::FileItemsQuery).sweep(sweep); | ||
105 | self.query(hir::db::FileItemQuery).sweep(sweep); | ||
106 | |||
107 | self.query(hir::db::LowerModuleQuery).sweep(sweep); | ||
108 | self.query(hir::db::LowerModuleSourceMapQuery).sweep(sweep); | ||
109 | self.query(hir::db::BodySyntaxMappingQuery).sweep(sweep); | ||
87 | } | 110 | } |
88 | } | 111 | } |
89 | 112 | ||