/// <summary> /// Clone clones the btree, lazily. Clone should not be called concurrently, /// but the original tree (t) and the new tree (t2) can be used concurrently /// once the Clone call completes. /// /// The internal tree structure of b is marked read-only and shared between t and /// t2. Writes to both t and t2 use copy-on-write logic, creating new nodes /// whenever one of b's original nodes would have been modified. Read operations /// should have no performance degredation. Write operations for both t and t2 /// will initially experience minor slow-downs caused by additional allocs and /// copies due to the aforementioned copy-on-write logic, but should converge to /// the original performance characteristics of the original tree. /// </summary> public BTree <T> Clone() { // Create two entirely new copy-on-write contexts. // This operation effectively creates three trees: // the original, shared nodes (old b.cow) // the new b.cow nodes // the new out.cow nodes CopyOnWriteContext <T> cow1 = new CopyOnWriteContext <T> { FreeList = Cow.FreeList }; CopyOnWriteContext <T> cow2 = new CopyOnWriteContext <T> { FreeList = Cow.FreeList }; BTree <T> tree = new BTree <T> { Degree = Degree, Length = Length, Root = Root, Cow = Cow }; Cow = cow1; tree.Cow = cow2; return(tree); }
// Reset returns a subtree to the freelist. It breaks out immediately if the // freelist is full, since the only benefit of iterating is to fill that // freelist up. Returns true if parent reset call should continue. public bool Reset(CopyOnWriteContext <T> c) { foreach (Node <T> child in Children) { if (!child.Reset(c)) { return(false); } } return(c.FreeNode(this) != FreeType.ftFreeListFull); }
/// <summary> /// Creates a new B-Tree that uses the given node free list. /// </summary> /// <param name="degree"></param> /// <param name="f"></param> public BTree(int degree, FreeList <T> f) { if (degree <= 1) { Environment.FailFast("bad degree"); } Degree = degree; Cow = new CopyOnWriteContext <T> { FreeList = f }; }
public Node <T> MutableFor(CopyOnWriteContext <T> cow) { if (ReferenceEquals(Cow, cow)) { return(this); } Node <T> node = Cow.NewNode(); node.Items.Append(Items); node.Children.Append(Children); return(node); }