// 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); }
RBNode <T> MoveRedRight(RBNode <T> node) { node.ColorFlip(); if (IsNodeRed(node.LeftChild.LeftChild)) { node = node.RotateRight(); node.ColorFlip(); } return(node); }
// 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); }
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); }
// 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); } } } }
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); }
// 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: 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++; } } }
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); }
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); }
// 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); }
// 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); }
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)); }
// 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); }
// 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)); }
// 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--; }
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; } } }
// 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); }
// 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)); }
// 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; } }
// 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); }
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 }
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(")"); } }
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); }
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); }
// 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 } }; }
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); }
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); } } }
bool IsNodeRed(RBNode <T> node) { return(node != null && node.IsRed); }