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.rs58
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;
}
};