Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-db/src/prime_caches.rs')
| -rw-r--r-- | crates/ide-db/src/prime_caches.rs | 58 |
1 files changed, 28 insertions, 30 deletions
diff --git a/crates/ide-db/src/prime_caches.rs b/crates/ide-db/src/prime_caches.rs index 22dc3d9e29..17c3f75ce1 100644 --- a/crates/ide-db/src/prime_caches.rs +++ b/crates/ide-db/src/prime_caches.rs @@ -6,16 +6,14 @@ mod topologic_sort; use std::time::Duration; -use hir::{db::DefDatabase, Symbol}; +use hir::{Symbol, db::DefDatabase}; use itertools::Itertools; +use salsa::{Cancelled, Database}; use crate::{ - base_db::{ - ra_salsa::{Database, ParallelDatabase, Snapshot}, - Cancelled, CrateId, SourceDatabase, - }, - symbol_index::SymbolsDatabase, FxIndexMap, RootDatabase, + base_db::{Crate, RootQueryDb}, + symbol_index::SymbolsDatabase, }; /// We're indexing many crates. @@ -37,20 +35,22 @@ pub fn parallel_prime_caches( ) { let _p = tracing::info_span!("parallel_prime_caches").entered(); - let graph = db.crate_graph(); let mut crates_to_prime = { + // FIXME: We already have the crate list topologically sorted (but without the things + // `TopologicalSortIter` gives us). Maybe there is a way to avoid using it and rip it out + // of the codebase? let mut builder = topologic_sort::TopologicalSortIter::builder(); - for crate_id in graph.iter() { - builder.add(crate_id, graph[crate_id].dependencies.iter().map(|d| d.crate_id)); + for &crate_id in db.all_crates().iter() { + builder.add(crate_id, crate_id.data(db).dependencies.iter().map(|d| d.crate_id)); } builder.build() }; enum ParallelPrimeCacheWorkerProgress { - BeginCrate { crate_id: CrateId, crate_name: Symbol }, - EndCrate { crate_id: CrateId }, + BeginCrate { crate_id: Crate, crate_name: Symbol }, + EndCrate { crate_id: Crate }, } // We split off def map computation from other work, @@ -66,7 +66,7 @@ pub fn parallel_prime_caches( let (work_sender, progress_receiver) = { let (progress_sender, progress_receiver) = crossbeam_channel::unbounded(); let (work_sender, work_receiver) = crossbeam_channel::unbounded(); - let prime_caches_worker = move |db: Snapshot<RootDatabase>| { + let prime_caches_worker = move |db: RootDatabase| { while let Ok((crate_id, crate_name, kind)) = work_receiver.recv() { progress_sender .send(ParallelPrimeCacheWorkerProgress::BeginCrate { crate_id, crate_name })?; @@ -90,7 +90,7 @@ pub fn parallel_prime_caches( stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker) .allow_leak(true) .name(format!("PrimeCaches#{id}")) - .spawn(move || Cancelled::catch(|| worker(db))) + .spawn(move || Cancelled::catch(|| worker(db.snapshot()))) .expect("failed to spawn thread"); } @@ -108,18 +108,16 @@ pub fn parallel_prime_caches( let mut additional_phases = vec![]; while crates_done < crates_total { - db.unwind_if_cancelled(); - - for crate_id in &mut crates_to_prime { - let krate = &graph[crate_id]; - let name = krate - .display_name - .as_deref() - .cloned() - .unwrap_or_else(|| Symbol::integer(crate_id.into_raw().into_u32() as usize)); - if krate.origin.is_lang() { - additional_phases.push((crate_id, name.clone(), PrimingPhase::ImportMap)); - } else if krate.origin.is_local() { + db.unwind_if_revision_cancelled(); + + for krate in &mut crates_to_prime { + let name = krate.extra_data(db).display_name.as_deref().cloned().unwrap_or_else(|| { + Symbol::integer(salsa::plumbing::AsId::as_id(&krate).as_u32() as usize) + }); + let origin = &krate.data(db).origin; + if origin.is_lang() { + additional_phases.push((krate, name.clone(), PrimingPhase::ImportMap)); + } else if origin.is_local() { // Compute the symbol search index. // This primes the cache for `ide_db::symbol_index::world_symbols()`. // @@ -129,10 +127,10 @@ pub fn parallel_prime_caches( // FIXME: We should do it unconditionally if the configuration is set to default to // searching dependencies (rust-analyzer.workspace.symbol.search.scope), but we // would need to pipe that configuration information down here. - additional_phases.push((crate_id, name.clone(), PrimingPhase::CrateSymbols)); + additional_phases.push((krate, name.clone(), PrimingPhase::CrateSymbols)); } - work_sender.send((crate_id, name, PrimingPhase::DefMap)).ok(); + work_sender.send((krate, name, PrimingPhase::DefMap)).ok(); } // recv_timeout is somewhat a hack, we need a way to from this thread check to see if the current salsa revision @@ -145,7 +143,7 @@ pub fn parallel_prime_caches( } Err(crossbeam_channel::RecvTimeoutError::Disconnected) => { // our workers may have died from a cancelled task, so we'll check and re-raise here. - db.unwind_if_cancelled(); + db.unwind_if_revision_cancelled(); break; } }; @@ -177,7 +175,7 @@ pub fn parallel_prime_caches( } while crates_done < crates_total { - db.unwind_if_cancelled(); + db.unwind_if_revision_cancelled(); // recv_timeout is somewhat a hack, we need a way to from this thread check to see if the current salsa revision // is cancelled on a regular basis. workers will only exit if they are processing a task that is cancelled, or @@ -189,7 +187,7 @@ pub fn parallel_prime_caches( } Err(crossbeam_channel::RecvTimeoutError::Disconnected) => { // our workers may have died from a cancelled task, so we'll check and re-raise here. - db.unwind_if_cancelled(); + db.unwind_if_revision_cancelled(); break; } }; |