Beispiel #1
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);
                    }
                }
            }
        }
Beispiel #2
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);
            }
        }
 // 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++;
         }
     }
 }
Beispiel #4
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;
                }
            }
        }
Beispiel #5
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(")");
     }
 }
Beispiel #6
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);
        }
Beispiel #7
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
                       }
            };
        }
Beispiel #8
0
        // Token: 0x0600768F RID: 30351 RVA: 0x0021DD90 File Offset: 0x0021BF90
        protected RBFinger <T> LocateItem(RBFinger <T> finger, Comparison <T> comparison)
        {
            RBNode <T> rbnode = finger.Node;
            int        num    = finger.Index - finger.Offset;
            T          itemAt = rbnode.GetItemAt(finger.Offset);

            for (int i = finger.Offset - 1; i >= 0; i--)
            {
                if (comparison(itemAt, rbnode.GetItemAt(i)) >= 0)
                {
                    return(new RBFinger <T>
                    {
                        Node = rbnode,
                        Offset = i + 1,
                        Index = num + i + 1
                    });
                }
            }
            RBNode <T> rbnode2 = rbnode;

            for (RBNode <T> parent = rbnode2.Parent; parent != null; parent = rbnode2.Parent)
            {
                while (parent != null && rbnode2 == parent.LeftChild)
                {
                    rbnode2 = parent;
                    parent  = rbnode2.Parent;
                }
                if (parent == null || comparison(itemAt, parent.GetItemAt(parent.Size - 1)) >= 0)
                {
                    break;
                }
                num = num - rbnode.LeftSize - parent.Size;
                if (comparison(itemAt, parent.GetItemAt(0)) >= 0)
                {
                    bool flag;
                    int  num2 = parent.BinarySearch(itemAt, 1, parent.Size - 1, comparison, -1, out flag);
                    return(new RBFinger <T>
                    {
                        Node = parent,
                        Offset = num2,
                        Index = num + num2
                    });
                }
                rbnode2 = (rbnode = parent);
            }
            if (rbnode.LeftChild != null)
            {
                RBFinger <T> result = rbnode.LeftChild.Find(itemAt, comparison);
                if (result.Offset == result.Node.Size)
                {
                    result = new RBFinger <T>
                    {
                        Node   = result.Node.GetSuccessor(),
                        Offset = 0,
                        Index  = result.Index
                    };
                }
                return(result);
            }
            return(new RBFinger <T>
            {
                Node = rbnode,
                Offset = 0,
                Index = num
            });
        }