@@ -93,12 +93,15 @@ impl Query {
93
93
pub trait SymbolsDatabase : HirDatabase + SourceDatabaseExt + Upcast < dyn HirDatabase > {
94
94
/// The symbol index for a given module. These modules should only be in source roots that
95
95
/// are inside local_roots.
96
- // FIXME: We should probably LRU this
97
96
fn module_symbols ( & self , module : Module ) -> Arc < SymbolIndex > ;
98
97
99
98
/// The symbol index for a given source root within library_roots.
100
99
fn library_symbols ( & self , source_root_id : SourceRootId ) -> Arc < SymbolIndex > ;
101
100
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
+
102
105
/// The set of "local" (that is, from the current workspace) roots.
103
106
/// Files in local roots are assumed to change frequently.
104
107
#[ salsa:: input]
@@ -113,26 +116,33 @@ pub trait SymbolsDatabase: HirDatabase + SourceDatabaseExt + Upcast<dyn HirDatab
113
116
fn library_symbols ( db : & dyn SymbolsDatabase , source_root_id : SourceRootId ) -> Arc < SymbolIndex > {
114
117
let _p = profile:: span ( "library_symbols" ) ;
115
118
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)
119
122
. iter ( )
120
123
. 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,
122
125
// 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) ) ;
126
128
129
+ let mut symbols = symbol_collector. finish ( ) ;
130
+ symbols. shrink_to_fit ( ) ;
127
131
Arc :: new ( SymbolIndex :: new ( symbols) )
128
132
}
129
133
130
134
fn module_symbols ( db : & dyn SymbolsDatabase , module : Module ) -> Arc < SymbolIndex > {
131
135
let _p = profile:: span ( "module_symbols" ) ;
132
- let symbols = SymbolCollector :: collect ( db. upcast ( ) , module) ;
136
+
137
+ let symbols = SymbolCollector :: collect_module ( db. upcast ( ) , module) ;
133
138
Arc :: new ( SymbolIndex :: new ( symbols) )
134
139
}
135
140
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
+
136
146
/// Need to wrap Snapshot to provide `Clone` impl for `map_with`
137
147
struct Snap < DB > ( DB ) ;
138
148
impl < DB : ParallelDatabase > Snap < salsa:: Snapshot < DB > > {
@@ -188,36 +198,21 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec<FileSymbol> {
188
198
. map_with ( Snap :: new ( db) , |snap, & root| snap. library_symbols ( root) )
189
199
. collect ( )
190
200
} else {
191
- let mut modules = Vec :: new ( ) ;
201
+ let mut crates = Vec :: new ( ) ;
192
202
193
203
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 ( ) )
198
205
}
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 ( )
204
211
} ;
205
212
206
213
query. search ( & indices)
207
214
}
208
215
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
-
221
216
#[ derive( Default ) ]
222
217
pub struct SymbolIndex {
223
218
symbols : Vec < FileSymbol > ,
@@ -275,7 +270,12 @@ impl SymbolIndex {
275
270
builder. insert ( key, value) . unwrap ( ) ;
276
271
}
277
272
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 ( ) ;
279
279
SymbolIndex { symbols, map }
280
280
}
281
281
@@ -419,7 +419,7 @@ struct StructInModB;
419
419
. modules ( & db)
420
420
. into_iter ( )
421
421
. map ( |module_id| {
422
- let mut symbols = SymbolCollector :: collect ( & db, module_id) ;
422
+ let mut symbols = SymbolCollector :: collect_module ( & db, module_id) ;
423
423
symbols. sort_by_key ( |it| it. name . clone ( ) ) ;
424
424
( module_id, symbols)
425
425
} )
0 commit comments