diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-10-12 16:21:39 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-10-12 16:21:39 +0100 |
commit | 05faeb50f3d78aac24b9581e846d010d815d7747 (patch) | |
tree | 3d9b18ddb480dbfa2b2593b31660b3776629d514 /crates/ide | |
parent | fac59f4f28e3ede6c88999aa43d28e7caa7df3a7 (diff) | |
parent | cde7392ec809599e6337d91561971e08c8e06831 (diff) |
Merge #6153
6153: Improve prime_caches and display its progress r=matklad a=jonas-schievink
It now computes the `CrateDefMap` of all crates, which is generally a reasonable approximation for "IDE features ready". There is still some delay after this finishes, I suspect mostly due to impl collection, which takes a while, but this should be an improvement already.
For more accurate progress reports, this topologically sorts all crates before starting this operation. ~~Because that is also the ordering in which parallelization makes sense (which was previously attempted in https://github.com/rust-analyzer/rust-analyzer/pull/3529), I decided to throw that into the mix as well. It still doesn't provide *that* much of a performance boost, but it does scale beyond the current single-core architecture, and adding it was very easy.~~
~~Unfortunately, as written, this will not tell the user which crate is actually causing slowdowns, since the displayed crate is the last one that was *started*, not the one we are currently *blocked* on, but that seems fairly difficult to implement unless I'm missing something.~~
(I have removed rayon for now since it does not work correctly with cancellation.)
Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates/ide')
-rw-r--r-- | crates/ide/src/lib.rs | 8 | ||||
-rw-r--r-- | crates/ide/src/prime_caches.rs | 43 |
2 files changed, 45 insertions, 6 deletions
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index 686cee3a1..aaf9b3b4b 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs | |||
@@ -77,6 +77,7 @@ pub use crate::{ | |||
77 | hover::{HoverAction, HoverConfig, HoverGotoTypeData, HoverResult}, | 77 | hover::{HoverAction, HoverConfig, HoverGotoTypeData, HoverResult}, |
78 | inlay_hints::{InlayHint, InlayHintsConfig, InlayKind}, | 78 | inlay_hints::{InlayHint, InlayHintsConfig, InlayKind}, |
79 | markup::Markup, | 79 | markup::Markup, |
80 | prime_caches::PrimeCachesProgress, | ||
80 | references::{ | 81 | references::{ |
81 | Declaration, Reference, ReferenceAccess, ReferenceKind, ReferenceSearchResult, RenameError, | 82 | Declaration, Reference, ReferenceAccess, ReferenceKind, ReferenceSearchResult, RenameError, |
82 | }, | 83 | }, |
@@ -223,8 +224,11 @@ impl Analysis { | |||
223 | self.with_db(|db| status::status(&*db, file_id)) | 224 | self.with_db(|db| status::status(&*db, file_id)) |
224 | } | 225 | } |
225 | 226 | ||
226 | pub fn prime_caches(&self, files: Vec<FileId>) -> Cancelable<()> { | 227 | pub fn prime_caches<F>(&self, cb: F) -> Cancelable<()> |
227 | self.with_db(|db| prime_caches::prime_caches(db, files)) | 228 | where |
229 | F: Fn(PrimeCachesProgress) + Sync + std::panic::UnwindSafe, | ||
230 | { | ||
231 | self.with_db(move |db| prime_caches::prime_caches(db, &cb)) | ||
228 | } | 232 | } |
229 | 233 | ||
230 | /// Gets the text of the source file. | 234 | /// Gets the text of the source file. |
diff --git a/crates/ide/src/prime_caches.rs b/crates/ide/src/prime_caches.rs index c5ab5a1d8..9687c2734 100644 --- a/crates/ide/src/prime_caches.rs +++ b/crates/ide/src/prime_caches.rs | |||
@@ -3,10 +3,45 @@ | |||
3 | //! request takes longer to compute. This modules implemented prepopulating of | 3 | //! request takes longer to compute. This modules implemented prepopulating of |
4 | //! various caches, it's not really advanced at the moment. | 4 | //! various caches, it's not really advanced at the moment. |
5 | 5 | ||
6 | use crate::{FileId, RootDatabase}; | 6 | use base_db::SourceDatabase; |
7 | use hir::db::DefDatabase; | ||
7 | 8 | ||
8 | pub(crate) fn prime_caches(db: &RootDatabase, files: Vec<FileId>) { | 9 | use crate::RootDatabase; |
9 | for file in files { | 10 | |
10 | let _ = crate::syntax_highlighting::highlight(db, file, None, false); | 11 | #[derive(Debug)] |
12 | pub enum PrimeCachesProgress { | ||
13 | Started, | ||
14 | /// We started indexing a crate. | ||
15 | StartedOnCrate { | ||
16 | on_crate: String, | ||
17 | n_done: usize, | ||
18 | n_total: usize, | ||
19 | }, | ||
20 | /// We finished indexing all crates. | ||
21 | Finished, | ||
22 | } | ||
23 | |||
24 | pub(crate) fn prime_caches(db: &RootDatabase, cb: &(dyn Fn(PrimeCachesProgress) + Sync)) { | ||
25 | let _p = profile::span("prime_caches"); | ||
26 | let graph = db.crate_graph(); | ||
27 | let topo = &graph.crates_in_topological_order(); | ||
28 | |||
29 | cb(PrimeCachesProgress::Started); | ||
30 | |||
31 | // FIXME: This would be easy to parallelize, since it's in the ideal ordering for that. | ||
32 | // Unfortunately rayon prevents panics from propagation out of a `scope`, which breaks | ||
33 | // cancellation, so we cannot use rayon. | ||
34 | for (i, krate) in topo.iter().enumerate() { | ||
35 | let crate_name = | ||
36 | graph[*krate].declaration_name.as_ref().map(ToString::to_string).unwrap_or_default(); | ||
37 | |||
38 | cb(PrimeCachesProgress::StartedOnCrate { | ||
39 | on_crate: crate_name, | ||
40 | n_done: i, | ||
41 | n_total: topo.len(), | ||
42 | }); | ||
43 | db.crate_def_map(*krate); | ||
11 | } | 44 | } |
45 | |||
46 | cb(PrimeCachesProgress::Finished); | ||
12 | } | 47 | } |