4
4
//! various caches, it's not really advanced at the moment.
5
5
6
6
use hir:: db:: DefDatabase ;
7
- use ide_db:: base_db:: SourceDatabase ;
7
+ use ide_db:: base_db:: { CrateGraph , CrateId , SourceDatabase , SourceDatabaseExt } ;
8
+ use rustc_hash:: FxHashSet ;
8
9
9
10
use crate :: RootDatabase ;
10
11
@@ -19,7 +20,18 @@ pub struct PrimeCachesProgress {
19
20
pub ( crate ) fn prime_caches ( db : & RootDatabase , cb : & ( dyn Fn ( PrimeCachesProgress ) + Sync ) ) {
20
21
let _p = profile:: span ( "prime_caches" ) ;
21
22
let graph = db. crate_graph ( ) ;
22
- let topo = & graph. crates_in_topological_order ( ) ;
23
+ // We're only interested in the transitive dependencies of all workspace crates.
24
+ let to_prime: FxHashSet < _ > = graph
25
+ . iter ( )
26
+ . filter ( |& id| {
27
+ let file_id = graph[ id] . root_file_id ;
28
+ let root_id = db. file_source_root ( file_id) ;
29
+ !db. source_root ( root_id) . is_library
30
+ } )
31
+ . flat_map ( |id| graph. transitive_deps ( id) )
32
+ . collect ( ) ;
33
+
34
+ let topo = toposort ( & graph, & to_prime) ;
23
35
24
36
// FIXME: This would be easy to parallelize, since it's in the ideal ordering for that.
25
37
// Unfortunately rayon prevents panics from propagation out of a `scope`, which breaks
@@ -32,3 +44,16 @@ pub(crate) fn prime_caches(db: &RootDatabase, cb: &(dyn Fn(PrimeCachesProgress)
32
44
db. import_map ( crate_id) ;
33
45
}
34
46
}
47
+
48
+ fn toposort ( graph : & CrateGraph , crates : & FxHashSet < CrateId > ) -> Vec < CrateId > {
49
+ // Just subset the full topologically sorted set for simplicity.
50
+
51
+ let all = graph. crates_in_topological_order ( ) ;
52
+ let mut result = Vec :: with_capacity ( crates. len ( ) ) ;
53
+ for krate in all {
54
+ if crates. contains ( & krate) {
55
+ result. push ( krate) ;
56
+ }
57
+ }
58
+ result
59
+ }
0 commit comments