Ejemplo n.º 1
0
 // Token: 0x06007694 RID: 30356 RVA: 0x0021E130 File Offset: 0x0021C330
 protected RBTree <T> GetRoot(RBNode <T> node)
 {
     for (RBNode <T> parent = node.Parent; parent != null; parent = node.Parent)
     {
         node = parent;
     }
     return((RBTree <T>)node);
 }
Ejemplo n.º 2
0
 RBNode <T> MoveRedRight(RBNode <T> node)
 {
     node.ColorFlip();
     if (IsNodeRed(node.LeftChild.LeftChild))
     {
         node = node.RotateRight();
         node.ColorFlip();
     }
     return(node);
 }
Ejemplo n.º 3
0
 // Token: 0x060076A2 RID: 30370 RVA: 0x0021E8B7 File Offset: 0x0021CAB7
 private RBNode <T> MoveRedLeft(RBNode <T> node)
 {
     node.ColorFlip();
     if (this.IsNodeRed(node.RightChild.LeftChild))
     {
         node.RightChild = node.RightChild.RotateRight();
         node            = node.RotateLeft();
         node.ColorFlip();
     }
     return(node);
 }
Ejemplo n.º 4
0
 protected RBTree <T> GetRootAndIndex(RBNode <T> node, out int index)
 {
     index = node.LeftSize;
     for (RBNode <T> parent = node.Parent; parent != null; node = parent, parent = node.Parent)
     {
         if (node == parent.RightChild)
         {
             index += parent.LeftSize + parent.Size;
         }
     }
     return((RBTree <T>)node);
 }
Ejemplo n.º 5
0
        // move the item under oldFinger to newFinger (assumed to be left of oldFinger)
        protected void ReInsert(ref RBFinger <T> oldFinger, RBFinger <T> newFinger)
        {
            RBNode <T> oldNode = oldFinger.Node, newNode = newFinger.Node;
            int        oldOffset = oldFinger.Offset, newOffset = newFinger.Offset;
            T          x = oldNode.GetItemAt(oldFinger.Offset);

            if (oldNode == newNode)
            {   // move within a single node
                int s = oldOffset - newOffset;

                if (s != 0)
                {
                    Copy(oldNode, newOffset, oldNode, newOffset + 1, s);
                    oldNode.SetItemAt(newOffset, x);
                }
            }
            else
            {     // move from one node to an earlier node
                if (newNode.Size < MaxSize)
                { // easy case - new node has room
                    newNode.InsertAt(newOffset, x);
                    oldNode.RemoveAt(ref oldFinger);
                }
                else
                {   // hard case - new node is full
                    RBNode <T> successor = newNode.GetSuccessor();
                    if (successor == oldNode)
                    {   // easy subcase - oldNode is next to newNode
                        T y = newNode.GetItemAt(MaxSize - 1);
                        Copy(newNode, newOffset, newNode, newOffset + 1, MaxSize - newOffset - 1);
                        newNode.SetItemAt(newOffset, x);
                        Copy(oldNode, 0, oldNode, 1, oldOffset);
                        oldNode.SetItemAt(0, y);
                    }
                    else
                    {
                        if (successor.Size < MaxSize)
                        {   // medium subcase - need to move items into successor
                            newNode.InsertAt(newOffset, x, successor);
                        }
                        else
                        {   // hard subcase - need a new node after newNode
                            RBNode <T> succsucc = successor;
                            successor = InsertNodeAfter(newNode);
                            newNode.InsertAt(newOffset, x, successor, succsucc);
                        }

                        oldNode.RemoveAt(ref oldFinger);
                    }
                }
            }
        }
Ejemplo n.º 6
0
        protected RBNode <T> LoadTree(ref string s)
        {
            if (s.StartsWith("()", StringComparison.Ordinal))
            {
                s = s.Substring(2);
                return(null);
            }

            int index;

            RBNode <T> node = new RBNode <T>();

            s = s.Substring(1);             // skip '('

            node.IsRed = (s[0] == 'T');     // read IsRed
            s          = s.Substring(1);

            index         = s.IndexOf(','); // read LeftSize
            node.LeftSize = Int32.Parse(s.Substring(0, index), TypeConverterHelper.InvariantEnglishUS);
            s             = s.Substring(index + 1);

            index     = s.IndexOf(',');     // read Size
            node.Size = Int32.Parse(s.Substring(0, index), TypeConverterHelper.InvariantEnglishUS);
            s         = s.Substring(index + 1);

            for (int k = 0; k < node.Size - 1; ++k) // read data
            {
                index = s.IndexOf(',');
                node.SetItemAt(k, AsT(Int32.Parse(s.Substring(0, index), TypeConverterHelper.InvariantEnglishUS)));
                s = s.Substring(index + 1);
            }
            index = s.IndexOf('(');
            node.SetItemAt(node.Size - 1, AsT(Int32.Parse(s.Substring(0, index), TypeConverterHelper.InvariantEnglishUS)));
            s = s.Substring(index);

            node.LeftChild  = LoadTree(ref s);  // read subtrees
            node.RightChild = LoadTree(ref s);
            if (node.LeftChild != null)
            {
                node.LeftChild.Parent = node;
            }
            if (node.RightChild != null)
            {
                node.RightChild.Parent = node;
            }

            s = s.Substring(1);             // skip ')'

            return(node);
        }
Ejemplo n.º 7
0
        // Token: 0x06007691 RID: 30353 RVA: 0x0021DF78 File Offset: 0x0021C178
        protected void ReInsert(ref RBFinger <T> oldFinger, RBFinger <T> newFinger)
        {
            RBNode <T> node    = oldFinger.Node;
            RBNode <T> node2   = newFinger.Node;
            int        offset  = oldFinger.Offset;
            int        offset2 = newFinger.Offset;
            T          itemAt  = node.GetItemAt(oldFinger.Offset);

            if (node == node2)
            {
                int num = offset - offset2;
                if (num != 0)
                {
                    this.Copy(node, offset2, node, offset2 + 1, num);
                    node.SetItemAt(offset2, itemAt);
                    return;
                }
            }
            else
            {
                if (node2.Size < 64)
                {
                    node2.InsertAt(offset2, itemAt, null, null);
                    node.RemoveAt(ref oldFinger);
                    return;
                }
                RBNode <T> rbnode = node2.GetSuccessor();
                if (rbnode == node)
                {
                    T itemAt2 = node2.GetItemAt(63);
                    this.Copy(node2, offset2, node2, offset2 + 1, 64 - offset2 - 1);
                    node2.SetItemAt(offset2, itemAt);
                    this.Copy(node, 0, node, 1, offset);
                    node.SetItemAt(0, itemAt2);
                    return;
                }
                if (rbnode.Size < 64)
                {
                    node2.InsertAt(offset2, itemAt, rbnode, null);
                }
                else
                {
                    RBNode <T> succsucc = rbnode;
                    rbnode = this.InsertNodeAfter(node2);
                    node2.InsertAt(offset2, itemAt, rbnode, succsucc);
                }
                node.RemoveAt(ref oldFinger);
            }
        }
Ejemplo n.º 8
0
 // Token: 0x0600769B RID: 30363 RVA: 0x0021E648 File Offset: 0x0021C848
 private RBNode <T> DeleteLeftmost(RBNode <T> node, out RBNode <T> leftmost)
 {
     if (node.LeftChild == null)
     {
         leftmost = node;
         return(null);
     }
     if (!this.IsNodeRed(node.LeftChild) && !this.IsNodeRed(node.LeftChild.LeftChild))
     {
         node = this.MoveRedLeft(node);
     }
     node.LeftChild = this.DeleteLeftmost(node.LeftChild, out leftmost);
     node.LeftSize -= leftmost.Size;
     return(this.Fixup(node));
 }
 // Token: 0x0600757C RID: 30076 RVA: 0x00218C28 File Offset: 0x00216E28
 protected override void Copy(RBNode <LiveShapingItem> sourceNode, int sourceOffset, RBNode <LiveShapingItem> destNode, int destOffset, int count)
 {
     base.Copy(sourceNode, sourceOffset, destNode, destOffset, count);
     if (sourceNode != destNode)
     {
         LiveShapingBlock block = (LiveShapingBlock)destNode;
         int i = 0;
         while (i < count)
         {
             destNode.GetItemAt(destOffset).Block = block;
             i++;
             destOffset++;
         }
     }
 }
Ejemplo n.º 10
0
 RBNode <T> Fixup(RBNode <T> node)
 {
     if (!IsNodeRed(node.LeftChild) && IsNodeRed(node.RightChild))
     {
         node = node.RotateLeft();
     }
     if (IsNodeRed(node.LeftChild) && IsNodeRed(node.LeftChild.LeftChild))
     {
         node = node.RotateRight();
     }
     if (IsNodeRed(node.LeftChild) && IsNodeRed(node.RightChild))
     {
         node.ColorFlip();
     }
     return(node);
 }
Ejemplo n.º 11
0
        RBNode <T> RotateRight()
        {
            RBNode <T> node = this.LeftChild;

            this.LeftSize -= node.LeftSize + node.Size;
            node.IsRed     = this.IsRed;
            node.Parent    = this.Parent;
            this.LeftChild = node.RightChild;
            if (this.LeftChild != null)
            {
                this.LeftChild.Parent = this;
            }
            node.RightChild = this;
            this.IsRed      = true;
            this.Parent     = node;
            return(node);
        }
Ejemplo n.º 12
0
        // Token: 0x0600769D RID: 30365 RVA: 0x0021E6C8 File Offset: 0x0021C8C8
        private RBNode <T> RotateLeft()
        {
            RBNode <T> rightChild = this.RightChild;

            rightChild.LeftSize += this.LeftSize + this.Size;
            rightChild.IsRed     = this.IsRed;
            rightChild.Parent    = this.Parent;
            this.RightChild      = rightChild.LeftChild;
            if (this.RightChild != null)
            {
                this.RightChild.Parent = this;
            }
            rightChild.LeftChild = this;
            this.IsRed           = true;
            this.Parent          = rightChild;
            return(rightChild);
        }
Ejemplo n.º 13
0
 // Token: 0x06007699 RID: 30361 RVA: 0x0021E4B4 File Offset: 0x0021C6B4
 private RBNode <T> Substitute(RBNode <T> node, RBNode <T> sub, RBNode <T> parent)
 {
     sub.LeftChild  = node.LeftChild;
     sub.RightChild = node.RightChild;
     sub.LeftSize   = node.LeftSize;
     sub.Parent     = node.Parent;
     sub.IsRed      = node.IsRed;
     if (sub.LeftChild != null)
     {
         sub.LeftChild.Parent = sub;
     }
     if (sub.RightChild != null)
     {
         sub.RightChild.Parent = sub;
     }
     return(sub);
 }
Ejemplo n.º 14
0
        RBNode <T> DeleteLeftmost(RBNode <T> node, out RBNode <T> leftmost)
        {
            if (node.LeftChild == null)
            {
                leftmost = node;
                return(null);
            }

            if (!IsNodeRed(node.LeftChild) && !IsNodeRed(node.LeftChild.LeftChild))
            {
                node = MoveRedLeft(node);
            }

            node.LeftChild = DeleteLeftmost(node.LeftChild, out leftmost);
            node.LeftSize -= leftmost.Size;
            return(Fixup(node));
        }
Ejemplo n.º 15
0
        // Token: 0x0600769E RID: 30366 RVA: 0x0021E744 File Offset: 0x0021C944
        private RBNode <T> RotateRight()
        {
            RBNode <T> leftChild = this.LeftChild;

            this.LeftSize   -= leftChild.LeftSize + leftChild.Size;
            leftChild.IsRed  = this.IsRed;
            leftChild.Parent = this.Parent;
            this.LeftChild   = leftChild.RightChild;
            if (this.LeftChild != null)
            {
                this.LeftChild.Parent = this;
            }
            leftChild.RightChild = this;
            this.IsRed           = true;
            this.Parent          = leftChild;
            return(leftChild);
        }
Ejemplo n.º 16
0
        // invariant:  node is red, or one if its children is red
        // As we move down the tree this is preserved by calling MoveRedLeft or
        // MoveRedRight, to "borrow red-ness" from a sibling.
        protected RBNode <T> DeleteNode(RBNode <T> parent, RBNode <T> node, int index)
        {
            if (index < node.LeftSize || (index == node.LeftSize && node.Size > 0))
            {
                if (!IsNodeRed(node.LeftChild) && !IsNodeRed(node.LeftChild.LeftChild))
                {
                    node = MoveRedLeft(node);
                }
                node.LeftChild = DeleteNode(node, node.LeftChild, index);
            }
            else
            {
                bool deleteHere = (index == node.LeftSize);
                Debug.Assert(!deleteHere || node.Size == 0, "DeleteNode: Deleted node should be empty");

                if (IsNodeRed(node.LeftChild))
                {
                    node       = node.RotateRight();
                    deleteHere = false;
                }
                if (deleteHere && node.RightChild == null)
                {
                    return(null);
                }
                if (!IsNodeRed(node.RightChild) && !IsNodeRed(node.RightChild.LeftChild))
                {
                    RBNode <T> temp = node;
                    node       = MoveRedRight(node);
                    deleteHere = deleteHere && (temp == node);
                }

                if (deleteHere)
                {
                    RBNode <T> sub;
                    node.RightChild = DeleteLeftmost(node.RightChild, out sub);
                    node            = Substitute(node, sub, parent);
                }
                else
                {
                    node.RightChild = DeleteNode(node, node.RightChild, index - node.LeftSize - node.Size);
                }
            }

            return(Fixup(node));
        }
Ejemplo n.º 17
0
        // Token: 0x06007692 RID: 30354 RVA: 0x0021E07C File Offset: 0x0021C27C
        protected void RemoveAt(ref RBFinger <T> finger)
        {
            RBNode <T> node   = finger.Node;
            int        offset = finger.Offset;

            this.Copy(node, offset + 1, node, offset, node.Size - offset - 1);
            node.ChangeSize(-1);
            node.SetItemAt(node.Size, default(T));
            if (node.Size == 0)
            {
                finger.Node   = node.GetSuccessor();
                finger.Offset = 0;
                int        index;
                RBTree <T> rootAndIndex = node.GetRootAndIndex(node, out index);
                rootAndIndex.RemoveNode(index);
            }
            finger.Offset--;
        }
Ejemplo n.º 18
0
        protected override void Copy(RBNode <LiveShapingItem> sourceNode, int sourceOffset, RBNode <LiveShapingItem> destNode, int destOffset, int count)
        {
            #if LiveShapingInstrumentation
            ++_copies;
            _totalCopySize += count;
            #endif

            base.Copy(sourceNode, sourceOffset, destNode, destOffset, count);

            if (sourceNode != destNode)
            {
                LiveShapingBlock destBlock = (LiveShapingBlock)destNode;

                for (int k = 0; k < count; ++k, ++destOffset)
                {
                    destNode.GetItemAt(destOffset).Block = destBlock;
                }
            }
        }
Ejemplo n.º 19
0
 // Token: 0x06007697 RID: 30359 RVA: 0x0021E3B4 File Offset: 0x0021C5B4
 protected RBNode <T> InsertNode(RBTree <T> root, RBNode <T> parent, RBNode <T> node, int index, out RBNode <T> newNode)
 {
     if (node == null)
     {
         newNode        = root.NewNode();
         newNode.Parent = parent;
         newNode.IsRed  = true;
         return(newNode);
     }
     if (index <= node.LeftSize)
     {
         node.LeftChild = this.InsertNode(root, node, node.LeftChild, index, out newNode);
     }
     else
     {
         node.RightChild = this.InsertNode(root, node, node.RightChild, index - node.LeftSize - node.Size, out newNode);
     }
     node = this.Fixup(node);
     return(node);
 }
Ejemplo n.º 20
0
 // Token: 0x0600769A RID: 30362 RVA: 0x0021E528 File Offset: 0x0021C728
 protected RBNode <T> DeleteNode(RBNode <T> parent, RBNode <T> node, int index)
 {
     if (index < node.LeftSize || (index == node.LeftSize && node.Size > 0))
     {
         if (!this.IsNodeRed(node.LeftChild) && !this.IsNodeRed(node.LeftChild.LeftChild))
         {
             node = this.MoveRedLeft(node);
         }
         node.LeftChild = this.DeleteNode(node, node.LeftChild, index);
     }
     else
     {
         bool flag = index == node.LeftSize;
         if (this.IsNodeRed(node.LeftChild))
         {
             node = node.RotateRight();
             flag = false;
         }
         if (flag && node.RightChild == null)
         {
             return(null);
         }
         if (!this.IsNodeRed(node.RightChild) && !this.IsNodeRed(node.RightChild.LeftChild))
         {
             RBNode <T> rbnode = node;
             node = this.MoveRedRight(node);
             flag = (flag && rbnode == node);
         }
         if (flag)
         {
             RBNode <T> sub;
             node.RightChild = this.DeleteLeftmost(node.RightChild, out sub);
             node            = this.Substitute(node, sub, parent);
         }
         else
         {
             node.RightChild = this.DeleteNode(node, node.RightChild, index - node.LeftSize - node.Size);
         }
     }
     return(this.Fixup(node));
 }
Ejemplo n.º 21
0
        // Token: 0x06007698 RID: 30360 RVA: 0x0021E438 File Offset: 0x0021C638
        protected void ChangeSize(int delta)
        {
            if (delta == 0)
            {
                return;
            }
            for (int i = this.Size + delta; i < this.Size; i++)
            {
                this._data[i] = default(T);
            }
            this.Size += delta;
            RBNode <T> rbnode = this;

            for (RBNode <T> parent = rbnode.Parent; parent != null; parent = rbnode.Parent)
            {
                if (parent.LeftChild == rbnode)
                {
                    parent.LeftSize += delta;
                }
                rbnode = parent;
            }
        }
Ejemplo n.º 22
0
        // Token: 0x0600768A RID: 30346 RVA: 0x0021D82C File Offset: 0x0021BA2C
        internal RBNode <T> GetPredecessor()
        {
            RBNode <T> rbnode2;

            if (this.LeftChild == null)
            {
                RBNode <T> rbnode = this;
                rbnode2 = rbnode.Parent;
                while (rbnode2 != null && rbnode2.LeftChild == rbnode)
                {
                    rbnode  = rbnode2;
                    rbnode2 = rbnode.Parent;
                }
                return(rbnode2);
            }
            rbnode2 = this.LeftChild;
            for (RBNode <T> rbnode = rbnode2.RightChild; rbnode != null; rbnode = rbnode2.RightChild)
            {
                rbnode2 = rbnode;
            }
            return(rbnode2);
        }
Ejemplo n.º 23
0
        void Insert(RBFinger <T> finger, T x, bool checkSort = false)
        {
#if RBTreeFlightRecorder
            SaveTree();
            int size = LeftSize;
#endif

            RBNode <T> node = finger.Node;

            if (node == this)
            {
                node = InsertNode(0);
                node.InsertAt(0, x);
            }
            else if (node.Size < MaxSize)
            {
                node.InsertAt(finger.Offset, x);
            }
            else
            {
                RBNode <T> successor = node.GetSuccessor();
                RBNode <T> succsucc  = null;
                if (successor.Size >= MaxSize)
                {
                    if (successor != this)
                    {
                        succsucc = successor;
                    }
                    successor = InsertNode(finger.Index + node.Size - finger.Offset);
                }
                node.InsertAt(finger.Offset, x, successor, succsucc);
            }

            LeftChild.IsRed = false;

#if RBTreeFlightRecorder
            Verify(size + 1, checkSort);
#endif
        }
Ejemplo n.º 24
0
 protected void SaveTree(RBNode <T> node, StringBuilder sb)
 {
     if (node == null)
     {
         sb.Append("()");
     }
     else
     {
         sb.Append("(");
         sb.Append(node.IsRed ? 'T' : 'F');
         sb.Append(node.LeftSize);
         sb.Append(",");
         sb.Append(node.Size);
         for (int k = 0; k < node.Size; ++k)
         {
             sb.Append(",");
             sb.Append(AsInt(node.GetItemAt(k)));
         }
         SaveTree(node.LeftChild, sb);
         SaveTree(node.RightChild, sb);
         sb.Append(")");
     }
 }
Ejemplo n.º 25
0
        protected RBNode <T> InsertNode(RBTree <T> root, RBNode <T> parent, RBNode <T> node, int index, out RBNode <T> newNode)
        {
            if (node == null)
            {
                newNode        = root.NewNode();
                newNode.Parent = parent;
                newNode.IsRed  = true;
                return(newNode);
            }

            if (index <= node.LeftSize)
            {
                node.LeftChild = InsertNode(root, node, node.LeftChild, index, out newNode);
            }
            else
            {
                Debug.Assert(index >= node.LeftSize + node.Size, "InsertNode: index should fall between nodes");
                node.RightChild = InsertNode(root, node, node.RightChild, index - node.LeftSize - node.Size, out newNode);
            }

            node = Fixup(node);

            return(node);
        }
Ejemplo n.º 26
0
 protected virtual void Copy(RBNode <T> sourceNode, int sourceOffset, RBNode <T> destNode, int destOffset, int count)
 {
     Array.Copy(sourceNode._data, sourceOffset, destNode._data, destOffset, count);
 }
Ejemplo n.º 27
0
        // Find the new position of the item under the given finger.  Used in InsertionSort.
        protected RBFinger <T> LocateItem(RBFinger <T> finger, Comparison <T> comparison)
        {
            RBNode <T> startingNode = finger.Node;
            int        nodeIndex    = finger.Index - finger.Offset;
            T          x            = startingNode.GetItemAt(finger.Offset);

            // first look within the node, using standard InsertionSort loop
            for (int k = finger.Offset - 1; k >= 0; --k)
            {
                if (comparison(x, startingNode.GetItemAt(k)) >= 0)
                {
                    return new RBFinger <T>()
                           {
                               Node = startingNode, Offset = k + 1, Index = nodeIndex + k + 1
                           }
                }
                ;
            }

            // next locate x between a node and its left-parent
            RBNode <T> node = startingNode, parent = node.Parent;

            while (parent != null)
            {
                while (parent != null && node == parent.LeftChild)
                {
                    node = parent; parent = node.Parent;
                }                                           // find left-parent

                if (parent == null || comparison(x, parent.GetItemAt(parent.Size - 1)) >= 0)
                {
                    break;      // x belongs in startingNode's left subtree
                }
                nodeIndex = nodeIndex - startingNode.LeftSize - parent.Size;
                if (comparison(x, parent.GetItemAt(0)) >= 0)
                {   // x belongs in the parent
                    bool found;
                    int  offset = parent.BinarySearch(x, 1, parent.Size - 1, comparison, -1, out found);
                    return(new RBFinger <T>()
                    {
                        Node = parent, Offset = offset, Index = nodeIndex + offset
                    });
                }

                // advance up the tree
                startingNode = node = parent;
                parent       = node.Parent;
            }

            // now we know x belongs in startingNode's left subtree, if any
            if (startingNode.LeftChild != null)
            {
                RBFinger <T> newFinger = startingNode.LeftChild.Find(x, comparison);
                if (newFinger.Offset == newFinger.Node.Size)
                {
                    newFinger = new RBFinger <T>()
                    {
                        Node = newFinger.Node.GetSuccessor(), Offset = 0, Index = newFinger.Index
                    }
                }
                ;
                return(newFinger);
            }
            else
            {
                return new RBFinger <T>()
                       {
                           Node = startingNode, Offset = 0, Index = nodeIndex
                       }
            };
        }
Ejemplo n.º 28
0
        protected bool Verify(RBNode <T> node, Comparison <T> comparison, int blackDepth, ref int index, ref T maxItem, out int size)
        {
            bool result = true;

            if (node == null)
            {
                if (BlackHeight < 0)
                {
                    BlackHeight = blackDepth;
                }
                size = 0;

                if (blackDepth != BlackHeight)
                {
                    result = false;   // not black-balanced
                }
                return(result);
            }

            if (!node.IsRed)
            {
                ++blackDepth;
            }

            result = Verify(node.LeftChild, comparison, blackDepth, ref index, ref maxItem, out size);

            if (node.Size <= 0)
            {
                result = false;     // too few items
            }
            if (node.Size > MaxSize)
            {
                result = false;     // too many items
            }
            if (!IsNodeRed(node.LeftChild) && IsNodeRed(node.RightChild))
            {
                result = false;     // not left-leaning
            }
            if (node.IsRed && (IsNodeRed(node.LeftChild) || IsNodeRed(node.RightChild)))
            {
                result = false;     // consecutive reds
            }
            if (size != node.LeftSize)
            {
                result = false;     // LeftSize is wrong
            }
            if (node.Parent.LeftChild != node && node != node.Parent.RightChild)
            {
                result = false;     // Parent is wrong
            }
            if (comparison != null)
            {
                if (index > 0 && comparison(maxItem, node.GetItemAt(0)) > 0)
                {
                    result = false;     // first item is out of order
                }
                for (int k = 1; k < node.Size; ++k)
                {
                    if (comparison(node.GetItemAt(k - 1), node.GetItemAt(k)) > 0)
                    {
                        result = false; // k-th item is out of order
                    }
                }
            }

            for (int j = node.Size; j < MaxSize; ++j)
            {
                if (!System.Windows.Controls.ItemsControl.EqualsEx(node.GetItemAt(j), default(T)))
                {
                    result = false;     // someone didn't clean up the array
                }
            }

            size += node.Size;
            ++index;
            maxItem = node.GetItemAt(node.Size - 1);

            int rightSize;

            result = Verify(node.RightChild, comparison, blackDepth, ref index, ref maxItem, out rightSize) && result;

            size += rightSize;

            return(result);
        }
Ejemplo n.º 29
0
        internal void InsertAt(int offset, T x, RBNode <T> successor = null, RBNode <T> succsucc = null)
        {
            if (Size < MaxSize)
            {
                // insert x into this.Array at offset
                Copy(this, offset, this, offset + 1, Size - offset);
                SetItemAt(offset, x);
                ChangeSize(1);
            }
            else
            {
                Debug.Assert(successor != null && successor.Size < MaxSize, "InsertAt: successor should have room");
                if (successor.Size == 0)
                {
                    if (succsucc == null)
                    {   // special case for insertion at the right - keep this node full
                        if (offset < MaxSize)
                        {
                            // move last item to successor
                            successor.InsertAt(0, GetItemAt(MaxSize - 1));
                            // insert x into this.Array at offset
                            Copy(this, offset, this, offset + 1, MaxSize - offset - 1);
                            SetItemAt(offset, x);
                        }
                        else
                        {
                            // insert x into successor
                            successor.InsertAt(0, x);
                        }
                    }
                    else
                    {   // split two full nodes into three
                        Debug.Assert(succsucc.Size == MaxSize, "InsertAt: outer nodes should be full");
                        int s = MaxSize / 3;

                        // move s items from this node into successor
                        Copy(successor, 0, successor, s, successor.Size);
                        Copy(this, MaxSize - s, successor, 0, s);

                        // move s items from succsucc into successor
                        Copy(succsucc, 0, successor, s + successor.Size, s);
                        Copy(succsucc, s, succsucc, 0, MaxSize - s);

                        if (offset <= MaxSize - s)
                        {
                            // insert into this.Array at offset
                            Copy(this, offset, this, offset + 1, MaxSize - s - offset);
                            SetItemAt(offset, x);

                            this.ChangeSize(1 - s);
                            successor.ChangeSize(s + s);
                        }
                        else
                        {
                            // insert into successor.Array at offset-(MaxSize-s)
                            Copy(successor, offset - (MaxSize - s), successor, offset - (MaxSize - s) + 1, successor.Size + s + s - (offset - (MaxSize - s)));
                            successor.SetItemAt(offset - (MaxSize - s), x);

                            this.ChangeSize(-s);
                            successor.ChangeSize(s + s + 1);
                        }
                        succsucc.ChangeSize(-s);
                    }
                }
                else
                {   // split a full node and its not-full successor into two pieces
                    int s = (Size + successor.Size + 1) / 2;

                    if (offset < s)
                    {
                        // move MaxSize-s+1 items from this node into successor
                        Copy(successor, 0, successor, MaxSize - s + 1, successor.Size);
                        Copy(this, s - 1, successor, 0, MaxSize - s + 1);

                        // insert into this.Array at offset
                        Copy(this, offset, this, offset + 1, s - 1 - offset);
                        SetItemAt(offset, x);
                    }
                    else
                    {
                        // move MaxSize-s items from this node into successor
                        Copy(successor, 0, successor, MaxSize - s, successor.Size);
                        Copy(this, s, successor, 0, MaxSize - s);

                        // insert into successor.Array at offset-s
                        Copy(successor, offset - s, successor, offset - s + 1, successor.Size + MaxSize - offset);
                        successor.SetItemAt(offset - s, x);
                    }
                    this.ChangeSize(s - MaxSize);
                    successor.ChangeSize(MaxSize - s + 1);
                }
            }
        }
Ejemplo n.º 30
0
 bool IsNodeRed(RBNode <T> node)
 {
     return(node != null && node.IsRed);
 }