コード例 #1
0
        // check the allegedly restored item against its neighbors
        internal bool VerifyPosition(LiveShapingItem lsi)
        {
            bool result = true;

            RBFinger <LiveShapingItem> finger = lsi.GetFinger();

            // we deliberately test the comparison *before* checking IsSortDirty
            // to handle the case where a second thread changes a sort property
            // during the check.

            if (finger.Index > 0)
            {
                --finger;
                result = result &&
                         !(Comparison(finger.Item, lsi) > 0 &&
                           !lsi.IsSortDirty && !finger.Item.IsSortDirty);
                ++finger;
            }

            if (finger.Index < Count - 1)
            {
                ++finger;
                result = result &&
                         !(Comparison(lsi, finger.Item) > 0 &&
                           !lsi.IsSortDirty && !finger.Item.IsSortDirty);
            }

            return(result);
        }
コード例 #2
0
        void Exchange(RBFinger <T> f1, RBFinger <T> f2)
        {
            T x = f1.Item;

            f1.SetItem(f2.Item);
            f2.SetItem(x);
        }
コード例 #3
0
        public void Insert(int index, T item)
        {
            VerifyIndex(index, 1);
            RBFinger <T> finger = FindIndex(index, false);

            Insert(finger, item);
        }
コード例 #4
0
        internal int IndexOf(T item, Func <T, T, bool> AreEqual)
        {
            if (Comparison != null)
            {
                RBFinger <T> finger = Find(item, Comparison);
                while (finger.Found && !AreEqual(finger.Item, item))
                {
                    ++finger;
                    finger.Found = (finger.IsValid && Comparison(finger.Item, item) == 0);
                }

                return(finger.Found ? finger.Index : -1);
            }
            else
            {
                int result = 0;
                ForEachUntil((x) =>
                {
                    if (AreEqual(x, item))
                    {
                        return(true);
                    }
                    ++result;
                    return(false);
                });
                return((result < Count) ? result : -1);
            }
        }
コード例 #5
0
        // re-implementation of RBTree.InsertionSort, with a little extra work
        internal void RestoreLiveSortingByInsertionSort(Action <NotifyCollectionChangedEventArgs, int, int> RaiseMoveEvent)
        {
            RBFinger <LiveShapingItem> finger = FindIndex(0);

            while (finger.Node != this)
            {
                LiveShapingItem lsi = finger.Item;
                lsi.IsSortDirty        = false;
                lsi.IsSortPendingClean = false;

                int oldIndex, newIndex;

                RBFinger <LiveShapingItem> fingerL = LocateItem(finger, Comparison);

                oldIndex = finger.Index;
                newIndex = fingerL.Index;

                if (oldIndex != newIndex)
                {
                    ReInsert(ref finger, fingerL);

                    RaiseMoveEvent(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move,
                                                                        lsi.Item, oldIndex, newIndex),
                                   oldIndex, newIndex);
                }

                ++finger;
            }
        }
コード例 #6
0
        // Token: 0x060075E8 RID: 30184 RVA: 0x0021A2C8 File Offset: 0x002184C8
        internal void ReplaceAt(int index, object item)
        {
            RBFinger <LiveShapingItem> rbfinger = base.FindIndex(index, true);
            LiveShapingItem            item2    = rbfinger.Item;

            item2.Clear();
            rbfinger.Node.SetItemAt(rbfinger.Offset, new LiveShapingItem(item, this.List, false, null, false));
        }
コード例 #7
0
        internal void ReplaceAt(int index, object item)
        {
            RBFinger <LiveShapingItem> finger = FindIndex(index);
            LiveShapingItem            lsi    = finger.Item;

            lsi.Clear();
            finger.Node.SetItemAt(finger.Offset, new LiveShapingItem(item, List));
        }
コード例 #8
0
ファイル: RBNode.cs プロジェクト: beda2280/wpf-1
        protected RBFinger <T> Find(T x, Comparison <T> comparison)
        {
            RBFinger <T> result;
            int          compL = (_data != null) ? comparison(x, GetItemAt(0)) : -1;
            int          compR;

            if (compL <= 0)
            {
                if (LeftChild == null)
                {
                    result = new RBFinger <T>()
                    {
                        Node = this, Offset = 0, Index = 0, Found = (compL == 0)
                    }
                }
                ;
                else
                {
                    result = LeftChild.Find(x, comparison);
                    if (compL == 0 && !result.Found)
                    {
                        result = new RBFinger <T>()
                        {
                            Node = this, Offset = 0, Index = LeftSize, Found = true
                        }
                    }
                    ;
                }
            }
            else if ((compR = comparison(x, GetItemAt(Size - 1))) <= 0)
            {
                bool found;
                int  offset = BinarySearch(x, 1, Size - 1, comparison, compR, out found);
                result = new RBFinger <T>()
                {
                    Node = this, Offset = offset, Index = LeftSize + offset, Found = found
                };
            }
            else
            {
                if (RightChild == null)
                {
                    result = new RBFinger <T>()
                    {
                        Node = this, Offset = Size, Index = LeftSize + Size
                    }
                }
                ;
                else
                {
                    result        = RightChild.Find(x, comparison);
                    result.Index += LeftSize + Size;
                }
            }

            return(result);
        }
コード例 #9
0
        // Search for value in the slice of the list starting at index with length count,
        // using the given comparer.  The list is assumed to be sorted w.r.t. the
        // comparer.  Return the index if found, or the bit-complement
        // of the index where it would belong.
        internal int Search(int index, int count, object value)
        {
            LiveShapingItem            temp   = new LiveShapingItem(value, this, true, null, true);
            RBFinger <LiveShapingItem> finger = _root.BoundedSearch(temp, index, index + count);

            ClearItem(temp);

            return(finger.Found ? finger.Index : ~finger.Index);
        }
コード例 #10
0
        // Token: 0x060075EA RID: 30186 RVA: 0x0021A358 File Offset: 0x00218558
        public override int IndexOf(LiveShapingItem lsi)
        {
            RBFinger <LiveShapingItem> finger = lsi.GetFinger();

            if (!finger.Found)
            {
                return(-1);
            }
            return(finger.Index);
        }
コード例 #11
0
        IEnumerator IEnumerable.GetEnumerator()
        {
            RBFinger <T> finger = FindIndex(0);

            while (finger.Node != this)
            {
                yield return(finger.Node.GetItemAt(finger.Offset));

                ++finger;
            }
        }
コード例 #12
0
        // Input: two regions [left, mid) and [mid, right), each of a single color
        // Output: swap so that the color on the left is now on the right, and vice-versa
        void Trade(RBFinger <T> left, RBFinger <T> mid, RBFinger <T> right)
        {
            int n = Math.Min(mid - left, right - mid);

            for (int k = 0; k < n; ++k)
            {
                --right;
                Exchange(left, right);
                ++left;
            }
        }
コード例 #13
0
        void InsertionSortImpl()
        {
            RBFinger <T> finger = FindIndex(1);

            while (finger.Node != this)
            {
                RBFinger <T> fingerL = LocateItem(finger, Comparison);
                ReInsert(ref finger, fingerL);
                ++finger;
            }
        }
コード例 #14
0
        // Token: 0x060075B1 RID: 30129 RVA: 0x00219A18 File Offset: 0x00217C18
        internal int Search(int index, int count, object value)
        {
            LiveShapingItem            liveShapingItem = new LiveShapingItem(value, this, true, null, true);
            RBFinger <LiveShapingItem> rbfinger        = this._root.BoundedSearch(liveShapingItem, index, index + count);

            this.ClearItem(liveShapingItem);
            if (!rbfinger.Found)
            {
                return(~rbfinger.Index);
            }
            return(rbfinger.Index);
        }
コード例 #15
0
ファイル: RBNode.cs プロジェクト: beda2280/wpf-1
        // 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);
                    }
                }
            }
        }
コード例 #16
0
        public bool Remove(T item)
        {
            RBFinger <T> finger = Find(item, Comparison);

            if (finger.Found)
            {
                RemoveAt(ref finger);
            }
            if (LeftChild != null)
            {
                LeftChild.IsRed = false;
            }
            return(finger.Found);
        }
コード例 #17
0
        // Token: 0x060075E9 RID: 30185 RVA: 0x0021A310 File Offset: 0x00218510
        internal LiveShapingItem FindItem(object item)
        {
            RBFinger <LiveShapingItem> finger = base.FindIndex(0, true);

            while (finger.Node != this)
            {
                if (ItemsControl.EqualsEx(finger.Item.Item, item))
                {
                    return(finger.Item);
                }
                finger = ++finger;
            }
            return(null);
        }
コード例 #18
0
        // linear search - only called when removing a filtered item
        internal LiveShapingItem FindItem(object item)
        {
            RBFinger <LiveShapingItem> finger = FindIndex(0);

            while (finger.Node != this)
            {
                if (Object.Equals(finger.Item.Item, item))
                {
                    return(finger.Item);
                }
                ++finger;
            }
            return(null);
        }
コード例 #19
0
        // linear search - only called when removing a filtered item
        internal LiveShapingItem FindItem(object item)
        {
            RBFinger <LiveShapingItem> finger = FindIndex(0);

            while (finger.Node != this)
            {
                if (System.Windows.Controls.ItemsControl.EqualsEx(finger.Item.Item, item))
                {
                    return(finger.Item);
                }
                ++finger;
            }
            return(null);
        }
コード例 #20
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);
            }
        }
コード例 #21
0
        // Token: 0x0600768B RID: 30347 RVA: 0x0021D880 File Offset: 0x0021BA80
        protected RBFinger <T> FindIndex(int index, bool exists = true)
        {
            int          num = exists ? 1 : 0;
            RBFinger <T> result;

            if (index + num <= this.LeftSize)
            {
                if (this.LeftChild == null)
                {
                    result = new RBFinger <T>
                    {
                        Node   = this,
                        Offset = 0,
                        Index  = 0,
                        Found  = false
                    };
                }
                else
                {
                    result = this.LeftChild.FindIndex(index, exists);
                }
            }
            else if (index < this.LeftSize + this.Size)
            {
                result = new RBFinger <T>
                {
                    Node   = this,
                    Offset = index - this.LeftSize,
                    Index  = index,
                    Found  = true
                };
            }
            else if (this.RightChild == null)
            {
                result = new RBFinger <T>
                {
                    Node   = this,
                    Offset = this.Size,
                    Index  = this.LeftSize + this.Size,
                    Found  = false
                };
            }
            else
            {
                result        = this.RightChild.FindIndex(index - this.LeftSize - this.Size, exists);
                result.Index += this.LeftSize + this.Size;
            }
            return(result);
        }
コード例 #22
0
 public T this[int index]
 {
     get
     {
         VerifyIndex(index);
         RBFinger <T> finger = FindIndex(index);
         return(finger.Node.GetItemAt(finger.Offset));
     }
     set
     {
         VerifyIndex(index);
         RBFinger <T> finger = FindIndex(index);
         finger.Node.SetItemAt(finger.Offset, value);
     }
 }
コード例 #23
0
        public void RemoveAt(int index)
        {
            VerifyIndex(index);

            SaveTree();
            int size = LeftSize;

            RBFinger <T> finger = FindIndex(index, true);

            RemoveAt(ref finger);
            if (LeftChild != null)
            {
                LeftChild.IsRed = false;
            }

            Verify(size - 1);
        }
コード例 #24
0
ファイル: RBNode.cs プロジェクト: beda2280/wpf-1
        protected RBFinger <T> FindIndex(int index, bool exists = true)
        {
            RBFinger <T> result;
            int          delta = exists ? 1 : 0;

            if (index + delta <= LeftSize)
            {
                if (LeftChild == null)
                {
                    result = new RBFinger <T>()
                    {
                        Node = this, Offset = 0, Index = 0, Found = false
                    }
                }
                ;
                else
                {
                    result = LeftChild.FindIndex(index, exists);
                }
            }
            else if (index < LeftSize + Size)
            {
                result = new RBFinger <T>()
                {
                    Node = this, Offset = index - LeftSize, Index = index, Found = true
                };
            }
            else
            {
                if (RightChild == null)
                {
                    result = new RBFinger <T>()
                    {
                        Node = this, Offset = Size, Index = LeftSize + Size, Found = false
                    }
                }
                ;
                else
                {
                    result        = RightChild.FindIndex(index - LeftSize - Size, exists);
                    result.Index += LeftSize + Size;
                }
            }
            return(result);
        }
コード例 #25
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--;
        }
コード例 #26
0
        // Token: 0x060075E6 RID: 30182 RVA: 0x0021A214 File Offset: 0x00218414
        internal void RestoreLiveSortingByInsertionSort(Action <NotifyCollectionChangedEventArgs, int, int> RaiseMoveEvent)
        {
            RBFinger <LiveShapingItem> finger = base.FindIndex(0, true);

            while (finger.Node != this)
            {
                LiveShapingItem item = finger.Item;
                item.IsSortDirty        = false;
                item.IsSortPendingClean = false;
                RBFinger <LiveShapingItem> newFinger = base.LocateItem(finger, base.Comparison);
                int index  = finger.Index;
                int index2 = newFinger.Index;
                if (index != index2)
                {
                    base.ReInsert(ref finger, newFinger);
                    RaiseMoveEvent(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, item.Item, index, index2), index, index2);
                }
                finger = ++finger;
            }
        }
コード例 #27
0
        public void QuickSort()
        {
#if RBTreeFlightRecorder
            SaveTree();
            int size = Count;
#endif

            if (Count > 1)
            {
                RBFinger <T> low  = FindIndex(0, false);
                RBFinger <T> high = FindIndex(Count, false);

                QuickSort3(low, high);
                InsertionSortImpl();
            }

#if RBTreeFlightRecorder
            Verify(size);
#endif
        }
コード例 #28
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
        }
コード例 #29
0
        public void Insert(T x)
        {
            RBFinger <T> finger = Find(x, Comparison);

            Insert(finger, x, true);
        }
コード例 #30
0
        public bool Contains(T item)
        {
            RBFinger <T> finger = Find(item, Comparison);

            return(finger.Found);
        }