Skip to content

Commit

Permalink
Don't create queue in WeakDom::insert for leaf instances (#463)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennethloeffler authored Oct 29, 2024
1 parent 942531f commit 69f3acc
Showing 1 changed file with 31 additions and 13 deletions.
44 changes: 31 additions & 13 deletions rbx_dom_weak/src/dom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,16 +109,13 @@ impl WeakDom {
/// ## Panics
/// Panics if `parent_ref` is some and does not refer to an instance in the DOM.
pub fn insert(&mut self, parent_ref: Ref, root_builder: InstanceBuilder) -> Ref {
let root_referent = root_builder.referent;

// Rather than performing this movement recursively, we instead use a
// queue that we load the children of each `InstanceBuilder` into.
// Then we can just iter through that.
let mut queue = VecDeque::with_capacity(1);
queue.push_back((parent_ref, root_builder));

while let Some((parent, builder)) = queue.pop_front() {
self.inner_insert(
fn insert(
dom: &mut WeakDom,
builder: InstanceBuilder,
parent: Ref,
queue: Option<&mut VecDeque<(Ref, InstanceBuilder)>>,
) {
dom.inner_insert(
builder.referent,
Instance {
referent: builder.referent,
Expand All @@ -131,15 +128,36 @@ impl WeakDom {
);

if parent.is_some() {
self.instances
dom.instances
.get_mut(&parent)
.unwrap_or_else(|| panic!("cannot insert into parent that does not exist"))
.children
.push(builder.referent);
}

for child in builder.children {
queue.push_back((builder.referent, child));
if let Some(queue) = queue {
for child in builder.children {
queue.push_back((builder.referent, child));
}
}
}

let root_referent = root_builder.referent;

// Fast path: if the builder does not have any children, then we don't have to
// construct a queue to keep track of descendants for insertion, avoiding a heap
// allocation.
if root_builder.children.is_empty() {
insert(self, root_builder, parent_ref, None);
} else {
// Rather than performing this movement recursively, we instead use a
// queue that we load the children of each `InstanceBuilder` into.
// Then we can just iter through that.
let mut queue = VecDeque::with_capacity(1);
queue.push_back((parent_ref, root_builder));

while let Some((parent, builder)) = queue.pop_front() {
insert(self, builder, parent, Some(&mut queue));
}
}

Expand Down

0 comments on commit 69f3acc

Please sign in to comment.