// search for x within the index range [low, high) protected RBFinger <T> BoundedSearch(T x, int low, int high, Comparison <T> comparison) { RBFinger <T> result; int compL, compR; RBNode <T> leftChild = LeftChild, rightChild = RightChild; int left = 0, right = Size; // determine whether to search the left subtree if (high <= LeftSize) { // allowed range is entirely within left subtree compL = -1; } else { if (low >= LeftSize) { // left subtree does not intersect allowed range leftChild = null; left = low - LeftSize; } compL = (left < Size) ? comparison(x, GetItemAt(left)) : +1; } if (compL <= 0) { // x is in the left subtree, or at the leftmost position in this node if (leftChild == null) { result = new RBFinger <T>() { Node = this, Offset = left, Index = left, Found = (compL == 0) } } ; else { result = leftChild.BoundedSearch(x, low, high, comparison); if (compL == 0 && !result.Found) { result = new RBFinger <T>() { Node = this, Offset = 0, Index = LeftSize, Found = true } } ; } return(result); } // determine whether to search the right subtree if (LeftSize + Size <= low) { // allowed range is entirely within right subtree compR = +1; } else { if (LeftSize + Size >= high) { // right subtree does not intersect allowed range rightChild = null; right = high - LeftSize; } // by symmetry with the left case, we should write // compR = (right > 0) ? comparison(x, GetItemAt(right-1)) : -1; // but since we know Size>0 and high>LeftSize, we can abbreviate to compR = comparison(x, GetItemAt(right - 1)); } if (compR > 0) { // x is in the right subtree, or after the rightmost position in this node if (rightChild == null) { result = new RBFinger <T>() { Node = this, Offset = right, Index = LeftSize + right, Found = false } } ; else { int delta = LeftSize + Size; result = rightChild.BoundedSearch(x, low - delta, high - delta, comparison); result.Index += delta; } return(result); } // if we get here, x is in this node in the range [left+1, right) bool found; int offset = BinarySearch(x, left + 1, right - 1, comparison, compR, out found); result = new RBFinger <T>() { Node = this, Offset = offset, Index = LeftSize + offset, Found = found }; return(result); } int BinarySearch(T x, int low, int high, Comparison <T> comparison, int compHigh, out bool found) { while (high - low > BinarySearchThreshold) { int mid = (high + low) / 2; int c = comparison(x, GetItemAt(mid)); if (c <= 0) { compHigh = c; high = mid; } else { low = mid + 1; } } int comp = 0; for (; low < high; ++low) { comp = comparison(x, GetItemAt(low)); if (comp <= 0) { break; } } if (low == high) { comp = compHigh; } found = (comp == 0); return(low); }
// Token: 0x0600768D RID: 30349 RVA: 0x0021DB38 File Offset: 0x0021BD38 protected RBFinger <T> BoundedSearch(T x, int low, int high, Comparison <T> comparison) { RBNode <T> rbnode = this.LeftChild; RBNode <T> rbnode2 = this.RightChild; int num = 0; int num2 = this.Size; int num3; if (high <= this.LeftSize) { num3 = -1; } else { if (low >= this.LeftSize) { rbnode = null; num = low - this.LeftSize; } num3 = ((num < this.Size) ? comparison(x, this.GetItemAt(num)) : 1); } RBFinger <T> result; if (num3 <= 0) { if (rbnode == null) { result = new RBFinger <T> { Node = this, Offset = num, Index = num, Found = (num3 == 0) }; } else { result = rbnode.BoundedSearch(x, low, high, comparison); if (num3 == 0 && !result.Found) { result = new RBFinger <T> { Node = this, Offset = 0, Index = this.LeftSize, Found = true }; } } return(result); } int num4; if (this.LeftSize + this.Size <= low) { num4 = 1; } else { if (this.LeftSize + this.Size >= high) { rbnode2 = null; num2 = high - this.LeftSize; } num4 = comparison(x, this.GetItemAt(num2 - 1)); } if (num4 > 0) { if (rbnode2 == null) { result = new RBFinger <T> { Node = this, Offset = num2, Index = this.LeftSize + num2, Found = false }; } else { int num5 = this.LeftSize + this.Size; result = rbnode2.BoundedSearch(x, low - num5, high - num5, comparison); result.Index += num5; } return(result); } bool found; int num6 = this.BinarySearch(x, num + 1, num2 - 1, comparison, num4, out found); result = new RBFinger <T> { Node = this, Offset = num6, Index = this.LeftSize + num6, Found = found }; return(result); }