Skip to content

Commit

Permalink
Add test of GC
Browse files Browse the repository at this point in the history
  • Loading branch information
CAD97 committed Jun 17, 2020
1 parent 0b410b6 commit bf8ca74
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 6 deletions.
21 changes: 15 additions & 6 deletions src/green/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,24 +83,31 @@ impl Builder {
Self::default()
}

/// The number of cached elements.
pub fn size(&self) -> usize {
self.nodes.len() + self.tokens.len()
}
}

impl Builder {
/// Create a new node or clone a new Arc to an existing equivalent one.
///
/// This checks children for identity equivalence, not structural,
/// so it is `O(children.len())` and only caches higher-level nodes
/// if the lower-level nodes have also been cached.
pub fn node<I>(&mut self, kind: Kind, children: I) -> Arc<Node>
where
I: IntoIterator,
I::Item: Into<NodeOrToken<Arc<Node>, Arc<Token>>>,
I::IntoIter: ExactSizeIterator,
where
I: IntoIterator,
I::Item: Into<NodeOrToken<Arc<Node>, Arc<Token>>>,
I::IntoIter: ExactSizeIterator,
{
self.node_packed(kind, children.into_iter().map(Into::into).map(pack_node_or_token))
}

/// Version of `Builder::node` taking a pre-packed child element iterator.
pub(super) fn node_packed<I>(&mut self, kind: Kind, children: I) -> Arc<Node>
where
I: Iterator<Item = PackedNodeOrToken> + ExactSizeIterator,
where
I: Iterator<Item=PackedNodeOrToken> + ExactSizeIterator,
{
let node = Node::new(kind, children);
self.cache_node(node)
Expand Down Expand Up @@ -149,7 +156,9 @@ impl Builder {
};
Arc::clone(token)
}
}

impl Builder {
fn turn_node_gc(&mut self) -> bool {
// NB: `drain_filter` is `retain` but with an iterator of the removed elements.
// i.e.: elements where the predicate is FALSE are removed and iterated over.
Expand Down
33 changes: 33 additions & 0 deletions tests/gc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use sorbus::*;

#[test]
fn works_properly() {
let kind0 = Kind(0);
let kind1 = Kind(1);
let kind2 = Kind(2);
let mut builder = green::TreeBuilder::new();

#[rustfmt::skip]
let inner = builder
.start_node(kind1)
.token(kind0, "kind")
.finish_node()
.finish();

#[rustfmt::skip]
let outer = builder
.start_node(kind2)
.add(inner.clone())
.finish_node()
.finish();

assert_eq!(builder.builder().size(), 3);

drop(outer);
builder.builder().gc();
assert_eq!(builder.builder().size(), 2);

drop(inner);
builder.builder().gc();
assert_eq!(builder.builder().size(), 0);
}

0 comments on commit bf8ca74

Please sign in to comment.