7300: When building an item-tree, keep fewer nodes in memory r=matklad a=matklad

bors r+
🤖

Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2021-01-16 20:08:10 +00:00 committed by GitHub
commit 0976a1ec8a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 9 deletions

4
Cargo.lock generated
View file

@ -1325,9 +1325,9 @@ checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
[[package]]
name = "rowan"
version = "0.10.2"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5093b337dccf58ace6c6d1fe7e28a0b8229c1e72579ae66bae258fbe53df3e0e"
checksum = "d55d358c5fda3d5c4484f71a4808f5eeb39a0aff93bf3acebc680a6d15376f3c"
dependencies = [
"rustc-hash",
"smol_str",

View file

@ -72,10 +72,12 @@ impl AstIdMap {
// get lower ids then children. That is, adding a new child does not
// change parent's id. This means that, say, adding a new function to a
// trait does not change ids of top-level items, which helps caching.
bfs(node, |it| {
if let Some(module_item) = ast::Item::cast(it) {
bdfs(node, |it| match ast::Item::cast(it) {
Some(module_item) => {
res.alloc(module_item.syntax());
true
}
None => false,
});
res
}
@ -105,14 +107,30 @@ impl AstIdMap {
}
}
/// Walks the subtree in bfs order, calling `f` for each node.
fn bfs(node: &SyntaxNode, mut f: impl FnMut(SyntaxNode)) {
/// Walks the subtree in bdfs order, calling `f` for each node. What is bdfs
/// order? It is a mix of breadth-first and depth first orders. Nodes for which
/// `f` returns true are visited breadth-first, all the other nodes are explored
/// depth-first.
///
/// In other words, the size of the bfs queue is bound by the number of "true"
/// nodes.
fn bdfs(node: &SyntaxNode, mut f: impl FnMut(SyntaxNode) -> bool) {
let mut curr_layer = vec![node.clone()];
let mut next_layer = vec![];
while !curr_layer.is_empty() {
curr_layer.drain(..).for_each(|node| {
next_layer.extend(node.children());
f(node);
let mut preorder = node.preorder();
while let Some(event) = preorder.next() {
match event {
syntax::WalkEvent::Enter(node) => {
if f(node.clone()) {
next_layer.extend(node.children());
preorder.skip_subtree();
}
}
syntax::WalkEvent::Leave(_) => {}
}
}
});
std::mem::swap(&mut curr_layer, &mut next_layer);
}

View file

@ -12,7 +12,7 @@ doctest = false
[dependencies]
itertools = "0.10.0"
rowan = "0.10.1"
rowan = "0.10.3"
rustc_lexer = { version = "697.0.0", package = "rustc-ap-rustc_lexer" }
rustc-hash = "1.1.0"
arrayvec = "0.5.1"