@@ -93,12 +93,15 @@ impl Query {
9393pub trait SymbolsDatabase : HirDatabase + SourceDatabaseExt + Upcast < dyn HirDatabase > {
9494 /// The symbol index for a given module. These modules should only be in source roots that
9595 /// are inside local_roots.
96- // FIXME: We should probably LRU this
9796 fn module_symbols ( & self , module : Module ) -> Arc < SymbolIndex > ;
9897
9998 /// The symbol index for a given source root within library_roots.
10099 fn library_symbols ( & self , source_root_id : SourceRootId ) -> Arc < SymbolIndex > ;
101100
101+ #[ salsa:: transparent]
102+ /// The symbol indices of modules that make up a given crate.
103+ fn crate_symbols ( & self , krate : Crate ) -> Box < [ Arc < SymbolIndex > ] > ;
104+
102105 /// The set of "local" (that is, from the current workspace) roots.
103106 /// Files in local roots are assumed to change frequently.
104107 #[ salsa:: input]
@@ -113,26 +116,33 @@ pub trait SymbolsDatabase: HirDatabase + SourceDatabaseExt + Upcast<dyn HirDatab
113116fn library_symbols ( db : & dyn SymbolsDatabase , source_root_id : SourceRootId ) -> Arc < SymbolIndex > {
114117 let _p = profile:: span ( "library_symbols" ) ;
115118
116- // todo: this could be parallelized, once I figure out how to do that...
117- let symbols = db
118- . source_root_crates ( source_root_id)
119+ let mut symbol_collector = SymbolCollector :: new ( db . upcast ( ) ) ;
120+
121+ db . source_root_crates ( source_root_id)
119122 . iter ( )
120123 . flat_map ( |& krate| Crate :: from ( krate) . modules ( db. upcast ( ) ) )
121- // we specifically avoid calling SymbolsDatabase::module_symbols here, even they do the same thing,
124+ // we specifically avoid calling other SymbolsDatabase queries here, even though they do the same thing,
122125 // as the index for a library is not going to really ever change, and we do not want to store each
123- // module's index in salsa.
124- . flat_map ( |module| SymbolCollector :: collect ( db. upcast ( ) , module) )
125- . collect ( ) ;
126+ // the module or crate indices for those in salsa unless we need to.
127+ . for_each ( |module| symbol_collector. collect ( module) ) ;
126128
129+ let mut symbols = symbol_collector. finish ( ) ;
130+ symbols. shrink_to_fit ( ) ;
127131 Arc :: new ( SymbolIndex :: new ( symbols) )
128132}
129133
130134fn module_symbols ( db : & dyn SymbolsDatabase , module : Module ) -> Arc < SymbolIndex > {
131135 let _p = profile:: span ( "module_symbols" ) ;
132- let symbols = SymbolCollector :: collect ( db. upcast ( ) , module) ;
136+
137+ let symbols = SymbolCollector :: collect_module ( db. upcast ( ) , module) ;
133138 Arc :: new ( SymbolIndex :: new ( symbols) )
134139}
135140
141+ pub fn crate_symbols ( db : & dyn SymbolsDatabase , krate : Crate ) -> Box < [ Arc < SymbolIndex > ] > {
142+ let _p = profile:: span ( "crate_symbols" ) ;
143+ krate. modules ( db. upcast ( ) ) . into_iter ( ) . map ( |module| db. module_symbols ( module) ) . collect ( )
144+ }
145+
136146/// Need to wrap Snapshot to provide `Clone` impl for `map_with`
137147struct Snap < DB > ( DB ) ;
138148impl < DB : ParallelDatabase > Snap < salsa:: Snapshot < DB > > {
@@ -188,36 +198,21 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec<FileSymbol> {
188198 . map_with ( Snap :: new ( db) , |snap, & root| snap. library_symbols ( root) )
189199 . collect ( )
190200 } else {
191- let mut modules = Vec :: new ( ) ;
201+ let mut crates = Vec :: new ( ) ;
192202
193203 for & root in db. local_roots ( ) . iter ( ) {
194- let crates = db. source_root_crates ( root) ;
195- for & krate in crates. iter ( ) {
196- modules. extend ( Crate :: from ( krate) . modules ( db) ) ;
197- }
204+ crates. extend ( db. source_root_crates ( root) . iter ( ) . copied ( ) )
198205 }
199-
200- modules
201- . par_iter ( )
202- . map_with ( Snap :: new ( db ) , |snap , & module| snap . module_symbols ( module ) )
203- . collect ( )
206+ let indices : Vec < _ > = crates
207+ . into_par_iter ( )
208+ . map_with ( Snap :: new ( db ) , |snap , krate| snap . crate_symbols ( krate . into ( ) ) )
209+ . collect ( ) ;
210+ indices . iter ( ) . flat_map ( |indices| indices . iter ( ) . cloned ( ) ) . collect ( )
204211 } ;
205212
206213 query. search ( & indices)
207214}
208215
209- pub fn crate_symbols ( db : & RootDatabase , krate : Crate , query : Query ) -> Vec < FileSymbol > {
210- let _p = profile:: span ( "crate_symbols" ) . detail ( || format ! ( "{query:?}" ) ) ;
211-
212- let modules = krate. modules ( db) ;
213- let indices: Vec < _ > = modules
214- . par_iter ( )
215- . map_with ( Snap :: new ( db) , |snap, & module| snap. module_symbols ( module) )
216- . collect ( ) ;
217-
218- query. search ( & indices)
219- }
220-
221216#[ derive( Default ) ]
222217pub struct SymbolIndex {
223218 symbols : Vec < FileSymbol > ,
@@ -275,7 +270,12 @@ impl SymbolIndex {
275270 builder. insert ( key, value) . unwrap ( ) ;
276271 }
277272
278- let map = fst:: Map :: new ( builder. into_inner ( ) . unwrap ( ) ) . unwrap ( ) ;
273+ let map = fst:: Map :: new ( {
274+ let mut buf = builder. into_inner ( ) . unwrap ( ) ;
275+ buf. shrink_to_fit ( ) ;
276+ buf
277+ } )
278+ . unwrap ( ) ;
279279 SymbolIndex { symbols, map }
280280 }
281281
@@ -419,7 +419,7 @@ struct StructInModB;
419419 . modules ( & db)
420420 . into_iter ( )
421421 . map ( |module_id| {
422- let mut symbols = SymbolCollector :: collect ( & db, module_id) ;
422+ let mut symbols = SymbolCollector :: collect_module ( & db, module_id) ;
423423 symbols. sort_by_key ( |it| it. name . clone ( ) ) ;
424424 ( module_id, symbols)
425425 } )
0 commit comments