use gc_lang::{Gc, Heap, Trace, Tracer};
struct Node {
label: &'static str,
next: Option<Gc<Node>>,
}
impl Trace for Node {
fn trace(&self, tracer: &mut Tracer<'_>) {
if let Some(next) = self.next {
tracer.mark(next);
}
}
}
fn main() {
let mut heap = Heap::new();
let a = heap.alloc(Node {
label: "a",
next: None,
});
let b = heap.alloc(Node {
label: "b",
next: Some(a),
});
let c = heap.alloc(Node {
label: "c",
next: Some(b),
});
heap.get_mut(a).expect("a is live").next = Some(c);
println!("built a 3-node ring, heap now holds {} objects", heap.len());
let kept = heap.collect([a]);
println!("collect([a]) -> freed {}, live {}", kept.freed, kept.live);
assert_eq!(kept.freed, 0);
let mut cursor = a;
print!("ring from a: {}", heap.get(a).expect("a is live").label);
for _ in 0..3 {
cursor = heap
.get(cursor)
.expect("node is live")
.next
.expect("ring is closed");
print!(" -> {}", heap.get(cursor).expect("node is live").label);
}
println!();
let swept = heap.collect([]);
println!("collect([]) -> freed {}, live {}", swept.freed, swept.live);
assert_eq!(swept.freed, 3);
assert!(heap.is_empty());
assert!(heap.get(a).is_none());
println!("the cycle was reclaimed; the heap is empty");
}