// 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); }
void Exchange(RBFinger <T> f1, RBFinger <T> f2) { T x = f1.Item; f1.SetItem(f2.Item); f2.SetItem(x); }
public void Insert(int index, T item) { VerifyIndex(index, 1); RBFinger <T> finger = FindIndex(index, false); Insert(finger, item); }
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); } }
// 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; } }
// 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)); }
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)); }
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); }
// 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); }
// 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); }
IEnumerator IEnumerable.GetEnumerator() { RBFinger <T> finger = FindIndex(0); while (finger.Node != this) { yield return(finger.Node.GetItemAt(finger.Offset)); ++finger; } }
// 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; } }
void InsertionSortImpl() { RBFinger <T> finger = FindIndex(1); while (finger.Node != this) { RBFinger <T> fingerL = LocateItem(finger, Comparison); ReInsert(ref finger, fingerL); ++finger; } }
// 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); }
// 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); } } } }
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); }
// 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); }
// 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); }
// 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); }
// 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: 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); }
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); } }
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); }
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); }
// 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--; }
// 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; } }
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 }
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 }
public void Insert(T x) { RBFinger <T> finger = Find(x, Comparison); Insert(finger, x, true); }
public bool Contains(T item) { RBFinger <T> finger = Find(item, Comparison); return(finger.Found); }