public void Add(T item) { SaveTree(); int size = LeftSize; RBNode <T> node = LeftChild; if (node == null) { node = InsertNode(0); node.InsertAt(0, item); } else { while (node.RightChild != null) { node = node.RightChild; } if (node.Size < MaxSize) { node.InsertAt(node.Size, item); } else { node = InsertNode(this.LeftSize); node.InsertAt(0, item); } } LeftChild.IsRed = false; Verify(size + 1, false); }
// 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); } }
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 }
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); } } }
// Token: 0x06007696 RID: 30358 RVA: 0x0021E1A8 File Offset: 0x0021C3A8 internal void InsertAt(int offset, T x, RBNode <T> successor = null, RBNode <T> succsucc = null) { if (this.Size < 64) { this.Copy(this, offset, this, offset + 1, this.Size - offset); this.SetItemAt(offset, x); this.ChangeSize(1); return; } if (successor.Size != 0) { int num = (this.Size + successor.Size + 1) / 2; if (offset < num) { this.Copy(successor, 0, successor, 64 - num + 1, successor.Size); this.Copy(this, num - 1, successor, 0, 64 - num + 1); this.Copy(this, offset, this, offset + 1, num - 1 - offset); this.SetItemAt(offset, x); } else { this.Copy(successor, 0, successor, 64 - num, successor.Size); this.Copy(this, num, successor, 0, 64 - num); this.Copy(successor, offset - num, successor, offset - num + 1, successor.Size + 64 - offset); successor.SetItemAt(offset - num, x); } this.ChangeSize(num - 64); successor.ChangeSize(64 - num + 1); return; } if (succsucc != null) { int num2 = 21; this.Copy(successor, 0, successor, num2, successor.Size); this.Copy(this, 64 - num2, successor, 0, num2); this.Copy(succsucc, 0, successor, num2 + successor.Size, num2); this.Copy(succsucc, num2, succsucc, 0, 64 - num2); if (offset <= 64 - num2) { this.Copy(this, offset, this, offset + 1, 64 - num2 - offset); this.SetItemAt(offset, x); this.ChangeSize(1 - num2); successor.ChangeSize(num2 + num2); } else { this.Copy(successor, offset - (64 - num2), successor, offset - (64 - num2) + 1, successor.Size + num2 + num2 - (offset - (64 - num2))); successor.SetItemAt(offset - (64 - num2), x); this.ChangeSize(-num2); successor.ChangeSize(num2 + num2 + 1); } succsucc.ChangeSize(-num2); return; } if (offset < 64) { successor.InsertAt(0, this.GetItemAt(63), null, null); this.Copy(this, offset, this, offset + 1, 64 - offset - 1); this.SetItemAt(offset, x); return; } successor.InsertAt(0, x, null, null); }