Example #1
0
 public void NodeAdded(AListNode <K, T> child, AListInnerBase <K, T> parent)
 {
     if (_nodes == null)
     {
         _nodes = new BMultiMap <AListNode <K, T>, AListInnerBase <K, T> >(CompareNodeHashCodes, CompareInnerHashCodes);
     }
     _nodes.Add(new KeyValuePair <AListNode <K, T>, AListInnerBase <K, T> >(child, parent));
 }
Example #2
0
 public static bool AutoClone(ref AListNode <K, T> node, AListInnerBase <K, T> parent, IAListTreeObserver <K, T> tob)
 {
     if (node.IsFrozen)
     {
         node = Clone(node, parent, tob);
         return(true);
     }
     return(false);
 }
Example #3
0
        protected AListInnerBase(AListInnerBase <K, T> frozen)
        {
            _children    = InternalList.CopyToNewArray(frozen._children);
            _childCount  = frozen._childCount;
            _maxNodeSize = frozen._maxNodeSize;
            _isFrozen    = false;

            MarkChildrenFrozen();
            AssertValid();
        }
Example #4
0
        public void NodeRemoved(AListNode <K, T> child, AListInnerBase <K, T> parent)
        {
            int index = _nodes.IndexOfExact(new KeyValuePair <AListNode <K, T>, AListInnerBase <K, T> >(child, parent));

            if (index <= -1)
            {
                BadState();
            }
            _nodes.RemoveAt(index);
        }
Example #5
0
        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);
        }
Example #6
0
        protected AListInnerBase(AListInnerBase <K, T> original, int localIndex, int localCount, uint baseIndex, int maxNodeSize)
        {
            // round up size to the nearest 4.
            _children = new Entry[(localCount + 3) & ~3];

            int i;

            for (i = 0; i < localCount; i++)
            {
                _children[i]        = original._children[localIndex + i];
                _children[i].Index -= baseIndex;
            }
            _childCount = (byte)localCount;
            Debug.Assert(maxNodeSize <= MaxMaxNodeSize);
            MaxNodeSize = maxNodeSize;

            InitEmpties(i);
            AssertValid();
        }
Example #7
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 <int, T> Combine(AListInnerBase <int, T> other, int heightDifference, out AListNode <int, T> splitRight, IAListTreeObserver <int, 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));
        }
Example #8
0
        protected AListInnerBase(AListInnerBase <K, T> original, uint index, uint count, AListBase <K, T> list)
        {
            // This constructor is called by CopySection
            Debug.Assert(count > 0 && count <= original.TotalCount);
            int   i0         = original.BinarySearchI(index);
            int   iN         = original.BinarySearchI(index + count - 1);
            Entry e0         = original._children[i0];
            Entry eN         = original._children[iN];
            int   localCount = iN - i0 + 1;

            // round up size to the nearest 4.
            _children    = new Entry[(localCount + 3) & ~3];
            _isFrozen    = false;
            _maxNodeSize = original._maxNodeSize;
            //_userByte = original._userByte;
            _childCount = (byte)localCount;
            InitEmpties(iN - i0 + 1);

            if (i0 == iN)
            {
                _children[0].Node = e0.Node.CopySection(index - e0.Index, count, list);
            }
            else
            {
                uint adjusted0 = index - e0.Index;
                uint adjustedN = index + count - eN.Index;
                Debug.Assert(adjusted0 <= index && adjustedN < count);
                AListNode <K, T> child0 = e0.Node.CopySection(adjusted0, e0.Node.TotalCount - adjusted0, list);
                AListNode <K, T> childN = eN.Node.CopySection(0, adjustedN, list);

                _children[0].Node       = child0;
                _children[iN - i0].Node = childN;
                uint offset = child0.TotalCount;
                for (int i = i0 + 1; i < iN; i++)
                {
                    AListNode <K, T> childI = original._children[i].Node;
                    // Freeze child because it will be shared between the original
                    // list and the section being copied
                    childI.Freeze();
                    _children[i - i0] = new Entry {
                        Node = childI, Index = offset
                    };
                    offset += childI.TotalCount;
                }
                _children[iN - i0].Index = offset;

                // Finally, if the first/last node is undersized, redistribute items.
                // Note: we can set the 'tob' parameter to null because this
                // constructor is called by CopySection, which creates an
                // independent AList that does not have an indexer.
                while (_childCount > 1 && _children[0].Node.IsUndersized)
                {
                    HandleUndersized(0, null);
                }
                while (_childCount > 1 && _children[_childCount - 1].Node.IsUndersized)
                {
                    HandleUndersized(_childCount - 1, null);
                }
            }

            AssertValid();
        }
Example #9
0
 internal static void HandleChildReplaced <K, T>(this IAListTreeObserver <K, T> self, AListNode <K, T> oldNode, AListNode <K, T> newLeft, AListNode <K, T> newRight, AListInnerBase <K, T> parent)
 {
     self.HandleNodeReplaced(oldNode, newLeft, newRight);
     if (parent != null)
     {
         self.NodeRemoved(oldNode, parent);
         self.NodeAdded(newLeft, parent);
         if (newRight != null)
         {
             self.NodeAdded(newRight, parent);
         }
     }
 }
Example #10
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);
 }
Example #11
0
 internal static void HandleRootSplit <K, T>(this IAListTreeObserver <K, T> self, AListNode <K, T> oldRoot, AListNode <K, T> newLeft, AListNode <K, T> newRight, AListInnerBase <K, T> newRoot)
 {
     self.HandleNodeReplaced(oldRoot, newLeft, newRight);
     self.NodeAdded(newLeft, newRoot);
     self.NodeAdded(newRight, newRoot);
     self.RootChanged(newRoot, false);
 }
Example #12
0
 internal static void NodeMoved <K, T>(this IAListTreeObserver <K, T> self, AListNode <K, T> child, AListInnerBase <K, T> oldParent, AListInnerBase <K, T> newParent)
 {
     self.NodeRemoved(child, oldParent);
     self.NodeAdded(child, newParent);
 }