Пример #1
0
        /// <summary>Appends or prepends some other list to this list. The other
        /// list must be the same height or less tall.</summary>
        /// <param name="other">A list to append/prepend</param>
        /// <param name="heightDifference">Height difference between the trees (0 or >0)</param>
        /// <param name="splitRight">Right half in case node is split</param>
        /// <param name="tob">Observer to be notified of changes</param>
        /// <param name="move">Move semantics (avoids freezing the nodes of the other tree)</param>
        /// <param name="append">Operation to perform (true => append)</param>
        /// <returns>Normally null, or left half in case node is split</returns>
        public virtual AListInnerBase <T, T> Combine(AListInnerBase <T, T> other, int heightDifference, out AListNode <T, T> splitRight, IAListTreeObserver <T, T> tob, bool move, bool append)
        {
            Debug.Assert(!IsFrozen && heightDifference >= 0);
            if (heightDifference != 0)
            {
                int i = append ? LocalCount - 1 : 0;
                AutoClone(ref _children[i].Node, this, tob);
                var splitLeft = ((AListInner <T>)Child(i)).Combine(other, heightDifference - 1, out splitRight, tob, move, append);
                if (!append)
                {
                    Debug.Assert(LocalCount == 1 || other.TotalCount == _children[0].Node.TotalCount - _children[1].Index);
                    AdjustIndexesAfter(i, (int)other.TotalCount);
                }
                return(AutoHandleChildSplit(i, splitLeft, ref splitRight, tob));
            }

            Debug.Assert(other.GetType() == GetType());
            int otherLC = other.LocalCount;

            AutoEnlargeChildren(otherLC);
            for (int i = 0; i < otherLC; i++)
            {
                var child = other.Child(i);
                if (!move)
                {
                    child.Freeze();                     // we're sharing this node between two trees
                }
                if (append)
                {
                    uint tc = TotalCount;
                    LLInsert(_childCount, child, 0);
                    _children[_childCount - 1].Index = tc;
                }
                else
                {
                    LLInsert(i, child, child.TotalCount);
                }
            }

            return(AutoSplit(out splitRight));
        }
Пример #2
0
 internal static void HandleRootUnsplit <K, T>(this IAListTreeObserver <K, T> self, AListInnerBase <K, T> oldRoot, AListNode <K, T> newRoot)
 {
     Debug.Assert(oldRoot.LocalCount == 0 || (oldRoot.LocalCount == 1 && oldRoot.Child(0) == newRoot));
     self.NodeRemoved(newRoot, oldRoot);
     self.RootChanged(newRoot, false);
 }