aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/imp.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/imp.rs')
-rw-r--r--crates/ra_ide_api/src/imp.rs49
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 @@
1use std::sync::Arc; 1use std::{
2 sync::Arc,
3 time,
4};
2 5
3use hir::{ 6use 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
28const GC_COOLDOWN: time::Duration = time::Duration::from_millis(100);
29
24impl db::RootDatabase { 30impl 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