// 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); } } } }
// 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++; } } }
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; } } }
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 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); }
// 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 } }; }
// 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 }); }