static AListNode <K, T> Clone(AListNode <K, T> node, AListInnerBase <K, T> parent, IAListTreeObserver <K, T> tob) { var clone = node.DetachedClone(); if (tob != null) { tob.HandleChildReplaced(node, clone, null, parent); } Debug.Assert(!clone.IsFrozen); return(clone); }
/// <summary>Checks whether 'node' is frozen and if so, replaces it with an unfrozen copy.</summary> /// <param name="node">A node that the caller needs to be unfrozen</param> /// <param name="parent">Parent node (used by tob)</param> /// <param name="tob">Tree observer (null if none)</param> /// <returns>True if the node was unfrozen</returns> public static bool AutoClone(ref AListNode <K, T> node, AListInnerBase <K, T> parent, IAListTreeObserver <K, T> tob) { bool result = node.IsFrozen; if (result) { var old = node; node = node.DetachedClone(); if (tob != null) { tob.HandleChildReplaced(old, node, null, parent); } Debug.Assert(!node.IsFrozen); } return(result); }
internal AListInnerBase <K, T> HandleChildCloned(int i, AListNode <K, T> childClone, IAListTreeObserver <K, T> tob) { Debug.Assert(childClone.LocalCount == _children[i].Node.LocalCount); Debug.Assert(childClone.TotalCount == _children[i].Node.TotalCount); if (tob != null) { tob.HandleChildReplaced(_children[i].Node, childClone, null, this); } var self = this; if (IsFrozen) { self = (AListInnerBase <K, T>)DetachedClone(); } self._children[i].Node = childClone; return(self != this ? self : null); }
/// <summary>Inserts a slot after _children[i], increasing _childCount and /// replacing [i] and [i+1] with splitLeft and splitRight. Notifies 'tob' /// of the replacement, and checks whether this node itself needs to split.</summary> /// <returns>Value of splitLeft to be returned to parent (non-null if splitting)</returns> protected AListInnerBase <K, T> HandleChildSplit(int i, AListNode <K, T> splitLeft, ref AListNode <K, T> splitRight, IAListTreeObserver <K, T> tob) { Debug.Assert(splitLeft != null && splitRight != null); if (tob != null) { tob.HandleChildReplaced(_children[i].Node, splitLeft, splitRight, this); } _children[i].Node = splitLeft; LLInsert(i + 1, splitRight, 0); _children[i + 1].Index = _children[i].Index + splitLeft.TotalCount; AssertValid(); // Does this node need to split too? return(AutoSplit(out splitRight)); }