[][src]Function bacon_rajan_cc::collect::number_of_roots_buffered

pub fn number_of_roots_buffered() -> usize

Return the number of potential cycle roots currently buffered for cycle collection.

Whenever a Cc<T>'s reference count is decremented, it has the possibility of becoming the root of some cycle that is no longer live and can now be reclaimed. These possible roots are buffered for cycle detection and collection at a later point in time. This enables library users to avoid frequent tracing and perform that tracing at a convenient time. Part of choosing a convenient time might be when the number of potential cycle roots reaches some critical threshold. This method allows you to check the current number of possible roots buffered.

use bacon_rajan_cc::{Cc, Trace, Tracer, number_of_roots_buffered};
use std::cell::RefCell;

struct Gadget {
    parent: Option<Cc<RefCell<Gadget>>>,
    children: Vec<Cc<RefCell<Gadget>>>,
    // ...
}

impl Trace for Gadget {
    fn trace(&self, _tracer: &mut Tracer) { /* ... */ }
}

fn add_child(parent: &mut Cc<RefCell<Gadget>>) -> Cc<RefCell<Gadget>> {
    let child = Cc::new(RefCell::new(Gadget { parent: None, children: vec!() }));
    child.borrow_mut().parent = Some(parent.clone());
    parent.borrow_mut().children.push(child.clone());
    child
}

pub fn main() {
    // No possible roots, as we haven't created any `Cc<T>`s yet.
    assert_eq!(number_of_roots_buffered(), 0);

    {
        let mut parent = Cc::new(RefCell::new(Gadget { parent: None, children: vec!() }));
        let mut children = vec!();
        for _ in 0..10 {
            children.push(add_child(&mut parent));
        }

        // No possible roots, we have only incremented reference counts and
        // created new `Cc<T>`s. We have not decremented any reference
        // counts or created any dead cycles.
        assert_eq!(number_of_roots_buffered(), 0);
    }

    // None of the Gadgets are reachable anymore, but they had cyclic
    // references between parents and children. However, because their
    // reference counts were decremented when we left the block, they should
    // be buffered for cycle collection.
    assert_eq!(number_of_roots_buffered(),
               1 /* parent */ + 10 /* children */);

    // If we had actually implemented `Trace` for `Gadget` rather than just
    // stubbing it out, we could call `collect_cycles` here to reclaim the
    // cycle.
}