Skip to content

Commit 43e52ac

Browse files
committed
Implement BatchDatabase construction
1 parent 15224df commit 43e52ac

File tree

5 files changed

+116
-22
lines changed

5 files changed

+116
-22
lines changed

Cargo.lock

Lines changed: 3 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ra_batch/Cargo.toml

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,16 @@ version = "0.1.0"
55
authors = ["Aleksey Kladov <[email protected]>"]
66

77
[dependencies]
8-
itertools = "0.8.0"
9-
join_to_string = "0.1.3"
108
log = "0.4.5"
11-
relative-path = "0.4.0"
12-
rayon = "1.0.2"
13-
fst = "0.3.1"
149
rustc-hash = "1.0"
15-
parking_lot = "0.7.0"
16-
unicase = "2.2.0"
10+
11+
failure = "0.1.4"
1712

1813
ra_syntax = { path = "../ra_syntax" }
1914
ra_db = { path = "../ra_db" }
2015
ra_hir = { path = "../ra_hir" }
16+
ra_vfs = { path = "../ra_vfs" }
17+
ra_project_model = { path = "../ra_project_model" }
2118

2219
[dev-dependencies]
2320
test_utils = { path = "../test_utils" }
24-
insta = "0.6.1"

crates/ra_batch/src/lib.rs

Lines changed: 96 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,28 @@
11
use std::sync::Arc;
2+
use std::path::Path;
3+
use std::collections::HashSet;
4+
5+
use rustc_hash::FxHashMap;
26

37
use ra_db::{
4-
FilePosition, FileId, CrateGraph, SourceRoot, SourceRootId, SourceDatabase, salsa,
8+
CrateGraph, FileId, SourceRoot, SourceRootId, SourceDatabase, salsa,
59
};
610
use ra_hir::{db, HirInterner};
11+
use ra_project_model::ProjectWorkspace;
12+
use ra_vfs::{Vfs, VfsChange};
13+
14+
type Result<T> = std::result::Result<T, failure::Error>;
715

816
#[salsa::database(
917
ra_db::SourceDatabaseStorage,
1018
db::HirDatabaseStorage,
1119
db::PersistentHirDatabaseStorage
1220
)]
1321
#[derive(Debug)]
14-
pub(crate) struct BatchDatabase {
22+
pub struct BatchDatabase {
1523
runtime: salsa::Runtime<BatchDatabase>,
1624
interner: Arc<HirInterner>,
17-
file_counter: u32,
25+
// file_counter: u32,
1826
}
1927

2028
impl salsa::Database for BatchDatabase {
@@ -28,3 +36,88 @@ impl AsRef<HirInterner> for BatchDatabase {
2836
&self.interner
2937
}
3038
}
39+
40+
fn vfs_file_to_id(f: ra_vfs::VfsFile) -> FileId {
41+
FileId(f.0.into())
42+
}
43+
fn vfs_root_to_id(r: ra_vfs::VfsRoot) -> SourceRootId {
44+
SourceRootId(r.0.into())
45+
}
46+
47+
impl BatchDatabase {
48+
pub fn load(crate_graph: CrateGraph, vfs: &mut Vfs) -> BatchDatabase {
49+
let mut db =
50+
BatchDatabase { runtime: salsa::Runtime::default(), interner: Default::default() };
51+
db.set_crate_graph(Arc::new(crate_graph));
52+
53+
// wait until Vfs has loaded all roots
54+
let receiver = vfs.task_receiver().clone();
55+
let mut roots_loaded = HashSet::new();
56+
for task in receiver {
57+
vfs.handle_task(task);
58+
let mut done = false;
59+
for change in vfs.commit_changes() {
60+
match change {
61+
VfsChange::AddRoot { root, files } => {
62+
let source_root_id = vfs_root_to_id(root);
63+
log::debug!("loaded source root {:?} with path {:?}", source_root_id, vfs.root2path(root));
64+
let mut file_map = FxHashMap::default();
65+
for (vfs_file, path, text) in files {
66+
let file_id = vfs_file_to_id(vfs_file);
67+
db.set_file_text(file_id, text);
68+
db.set_file_relative_path(file_id, path.clone());
69+
db.set_file_source_root(file_id, source_root_id);
70+
file_map.insert(path, file_id);
71+
}
72+
let source_root = SourceRoot { files: file_map };
73+
db.set_source_root(source_root_id, Arc::new(source_root));
74+
roots_loaded.insert(source_root_id);
75+
if roots_loaded.len() == vfs.num_roots() {
76+
done = true;
77+
}
78+
}
79+
VfsChange::AddFile { .. }
80+
| VfsChange::RemoveFile { .. }
81+
| VfsChange::ChangeFile { .. } => {
82+
// log::warn!("VFS changed while loading");
83+
}
84+
}
85+
}
86+
if done {
87+
break;
88+
}
89+
}
90+
91+
db
92+
}
93+
94+
pub fn load_cargo(root: impl AsRef<Path>) -> Result<(BatchDatabase, Vec<SourceRootId>)> {
95+
let root = root.as_ref().canonicalize()?;
96+
let ws = ProjectWorkspace::discover(root.as_ref())?;
97+
let mut roots = Vec::new();
98+
roots.push(root.clone());
99+
for pkg in ws.cargo.packages() {
100+
roots.push(pkg.root(&ws.cargo).to_path_buf());
101+
}
102+
for krate in ws.sysroot.crates() {
103+
roots.push(krate.root_dir(&ws.sysroot).to_path_buf())
104+
}
105+
let (mut vfs, roots) = Vfs::new(roots);
106+
let mut load = |path: &Path| {
107+
let vfs_file = vfs.load(path);
108+
log::debug!("vfs file {:?} -> {:?}", path, vfs_file);
109+
vfs_file.map(vfs_file_to_id)
110+
};
111+
let crate_graph = ws.to_crate_graph(&mut load);
112+
log::debug!("crate graph: {:?}", crate_graph);
113+
114+
let local_roots = roots.into_iter()
115+
.filter(|r| vfs.root2path(*r).starts_with(&root))
116+
.map(vfs_root_to_id)
117+
.collect();
118+
119+
let db = BatchDatabase::load(crate_graph, &mut vfs);
120+
let _ = vfs.shutdown();
121+
Ok((db, local_roots))
122+
}
123+
}

crates/ra_lsp_server/src/server_world.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,8 @@ impl ServerWorldState {
4747
roots.push(krate.root_dir(&ws.sysroot).to_path_buf())
4848
}
4949
}
50-
roots.sort();
51-
roots.dedup();
52-
let roots_to_scan = roots.len();
5350
let (mut vfs, roots) = Vfs::new(roots);
51+
let roots_to_scan = roots.len();
5452
for r in roots {
5553
let is_local = vfs.root2path(r).starts_with(&root);
5654
change.add_root(SourceRootId(r.0.into()), is_local);

crates/ra_vfs/src/lib.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ impl Roots {
9494
let mut roots = Arena::default();
9595
// A hack to make nesting work.
9696
paths.sort_by_key(|it| Reverse(it.as_os_str().len()));
97+
paths.dedup();
9798
for (i, path) in paths.iter().enumerate() {
9899
let nested_roots = paths[..i]
99100
.iter()
@@ -161,6 +162,13 @@ impl Vfs {
161162
self.roots[root].root.clone()
162163
}
163164

165+
pub fn path2root(&self, path: &Path) -> Option<VfsRoot> {
166+
match self.find_root(path) {
167+
Some((root, _path, _file)) => Some(root),
168+
_ => None,
169+
}
170+
}
171+
164172
pub fn path2file(&self, path: &Path) -> Option<VfsFile> {
165173
if let Some((_root, _path, Some(file))) = self.find_root(path) {
166174
return Some(file);
@@ -181,6 +189,10 @@ impl Vfs {
181189
None
182190
}
183191

192+
pub fn num_roots(&self) -> usize {
193+
self.roots.len()
194+
}
195+
184196
pub fn load(&mut self, path: &Path) -> Option<VfsFile> {
185197
if let Some((root, rel_path, file)) = self.find_root(path) {
186198
return if let Some(file) = file {

0 commit comments

Comments
 (0)