on master help sign in
Use a hash set for cached roots
97d6f40Nick Fitzgerald
src/cached_set.rs+13−9
@@ -38,27 +38,31 @@ pub(crate) struct CacheEntry {
38}
38}
39
39
40impl CachedSet {
40impl CachedSet {
41+ pub(crate) fn new_roots_set(&self) -> FxHashSet<CacheId> {
42+ let mut roots = FxHashSet::default();
43+ roots.reserve(self.items.len());
44+ roots
45+ }
46+
41− pub(crate) fn gc(&mut self, registry: &mut EventsRegistry, roots: &[CacheId]) {
47+ pub(crate) fn gc(&mut self, registry: &mut EventsRegistry, roots: FxHashSet<CacheId>) {
42− // TODO: We need to port a hash set over in `bumpalo::collections` so
43− // that we can use a temporary bump arena for this set.
44− let mut mark_bits = FxHashSet::default();
48+ let mut marked = FxHashSet::default();
45− mark_bits.reserve(self.items.len());
49+ marked.reserve(self.items.len());
46
50
47 for root in roots {
51 for root in roots {
48− if mark_bits.insert(*root) {
52+ if marked.insert(root) {
49 let entry = self
53 let entry = self
50 .items
54 .items
51− .get(root)
55+ .get(&root)
52 .expect_throw("CachedSet::gc: should have root in cached set");
56 .expect_throw("CachedSet::gc: should have root in cached set");
53
57
54 // NB: no need to recurse here because `edges` already contains
58 // NB: no need to recurse here because `edges` already contains
55 // transitive edges!
59 // transitive edges!
56− mark_bits.extend(entry.edges.iter().cloned());
60+ marked.extend(entry.edges.iter().cloned());
57 }
61 }
58 }
62 }
59
63
60 self.items.retain(|id, entry| {
64 self.items.retain(|id, entry| {
61− let keep = mark_bits.contains(id);
65+ let keep = marked.contains(id);
62 if !keep {
66 if !keep {
63 debug!("CachedSet::gc: removing {:?}", id);
67 debug!("CachedSet::gc: removing {:?}", id);
64 let node: &Node = unsafe { &*entry.node };
68 let node: &Node = unsafe { &*entry.node };
src/change_list/mod.rs+1−3
@@ -43,9 +43,7 @@ impl ChangeListPersistentState {
43 }
43 }
44
44
45 pub(crate) fn builder<'a>(&'a mut self) -> ChangeListBuilder<'a> {
45 pub(crate) fn builder<'a>(&'a mut self) -> ChangeListBuilder<'a> {
46− ChangeListBuilder {
46+ ChangeListBuilder { state: self }
47− state: self,
48− }
49 }
47 }
50}
48}
51
49
src/diff.rs+7−6
@@ -4,6 +4,7 @@ use crate::{
4 events::EventsRegistry,
4 events::EventsRegistry,
5 node::{Attribute, ElementNode, Listener, Node, NodeKind, TextNode},
5 node::{Attribute, ElementNode, Listener, Node, NodeKind, TextNode},
6};
6};
7+use fxhash::FxHashSet;
7use std::cmp;
8use std::cmp;
8
9
9pub(crate) fn diff(
10pub(crate) fn diff(
@@ -12,7 +13,7 @@ pub(crate) fn diff(
12 registry: &mut EventsRegistry,
13 registry: &mut EventsRegistry,
13 old: Node,
14 old: Node,
14 new: Node,
15 new: Node,
15− cached_roots: &mut bumpalo::collections::Vec<CacheId>,
16+ cached_roots: &mut FxHashSet<CacheId>,
16) {
17) {
17 match (&new.kind, &old.kind) {
18 match (&new.kind, &old.kind) {
18 (
19 (
@@ -79,7 +80,7 @@ pub(crate) fn diff(
79
80
80 // Both the new and old nodes are cached.
81 // Both the new and old nodes are cached.
81 (&NodeKind::Cached(ref new), &NodeKind::Cached(ref old)) => {
82 (&NodeKind::Cached(ref new), &NodeKind::Cached(ref old)) => {
82− cached_roots.push(new.id);
83+ cached_roots.insert(new.id);
83
84
84 if new.id == old.id {
85 if new.id == old.id {
85 // This is the same cached node, so nothing has changed!
86 // This is the same cached node, so nothing has changed!
@@ -95,7 +96,7 @@ pub(crate) fn diff(
95 // we assume that they are pretty different, and it isn't worth diffing
96 // we assume that they are pretty different, and it isn't worth diffing
96 // the subtrees, so we just create the new cached node afresh.
97 // the subtrees, so we just create the new cached node afresh.
97 (&NodeKind::Cached(ref c), _) => {
98 (&NodeKind::Cached(ref c), _) => {
98− cached_roots.push(c.id);
99+ cached_roots.insert(c.id);
99 let new = cached_set.get(c.id);
100 let new = cached_set.get(c.id);
100 create(cached_set, change_list, registry, new, cached_roots);
101 create(cached_set, change_list, registry, new, cached_roots);
101 registry.remove_subtree(&old);
102 registry.remove_subtree(&old);
@@ -187,7 +188,7 @@ fn diff_children(
187 registry: &mut EventsRegistry,
188 registry: &mut EventsRegistry,
188 old: &[Node],
189 old: &[Node],
189 new: &[Node],
190 new: &[Node],
190− cached_roots: &mut bumpalo::collections::Vec<CacheId>,
191+ cached_roots: &mut FxHashSet<CacheId>,
191) {
192) {
192 debug!(" updating children shared by old and new");
193 debug!(" updating children shared by old and new");
193
194
@@ -259,7 +260,7 @@ fn create(
259 change_list: &mut ChangeListBuilder,
260 change_list: &mut ChangeListBuilder,
260 registry: &mut EventsRegistry,
261 registry: &mut EventsRegistry,
261 node: Node,
262 node: Node,
262− cached_roots: &mut bumpalo::collections::Vec<CacheId>,
263+ cached_roots: &mut FxHashSet<CacheId>,
263) {
264) {
264 match node.kind {
265 match node.kind {
265 NodeKind::Text(TextNode { text }) => {
266 NodeKind::Text(TextNode { text }) => {
@@ -298,7 +299,7 @@ fn create(
298 }
299 }
299 }
300 }
300 NodeKind::Cached(c) => {
301 NodeKind::Cached(c) => {
301− cached_roots.push(c.id);
302+ cached_roots.insert(c.id);
302 let node = cached_set.get(c.id);
303 let node = cached_set.get(c.id);
303 create(cached_set, change_list, registry, node, cached_roots)
304 create(cached_set, change_list, registry, node, cached_roots)
304 }
305 }
src/vdom.rs+3−2
@@ -268,9 +268,10 @@ impl VdomInnerExclusive {
268
268
269 // Diff the old contents with the new contents.
269 // Diff the old contents with the new contents.
270 let old_contents = self.current_root.take().unwrap();
270 let old_contents = self.current_root.take().unwrap();
271− let mut cache_roots = bumpalo::collections::Vec::new_in(&dom_buffers[1]);
271+ let mut cache_roots;
272 {
272 {
273 let cached_set = self.cached_set.borrow();
273 let cached_set = self.cached_set.borrow();
274+ cache_roots = cached_set.new_roots_set();
274 let mut change_list = self.change_list.builder();
275 let mut change_list = self.change_list.builder();
275 crate::diff::diff(
276 crate::diff::diff(
276 &cached_set,
277 &cached_set,
@@ -288,7 +289,7 @@ impl VdomInnerExclusive {
288 {
289 {
289 // Clean up unused cached renders.
290 // Clean up unused cached renders.
290 let mut cached_set = self.cached_set.borrow_mut();
291 let mut cached_set = self.cached_set.borrow_mut();
291− cached_set.gc(&mut registry, &cache_roots);
292+ cached_set.gc(&mut registry, cache_roots);
292 }
293 }
293
294
294 // Swap the buffers to make the bump arena with the new contents the
295 // Swap the buffers to make the bump arena with the new contents the