public bool TryFindString(String8 value, out Range matches) { if (value.IsEmpty()) { matches = Range.Empty; return(true); } // Binary search sorted strings for the value int min = 0; int max = _sortedExistingValues.Count - 1; int mid = 0; int cmp = 0; String8 valueHere = String8.Empty; while (min <= max) { mid = (min + max) / 2; valueHere = this[mid]; cmp = value.CompareTo(valueHere, IgnoreCase); if (cmp == 0) { // 'value' Found - look for bounds break; } else if (cmp > 0) { // 'value' is later - look after valueHere min = mid + 1; } else { // 'value' is earlier - look before valueHere max = mid - 1; } } // If no match, set both bounds to insertion position if (cmp > 0) { // If 'value' was after last comparison, we'd insert after it matches = new Range(mid + 1); return(false); } else if (cmp < 0) { // If 'value' was before last comparison, we'd insert before it matches = new Range(mid); return(false); } matches = RangeForString(mid); return(true); }
/// <summary> /// Take a case insensitive range and restrict it to the case sensitive subset. /// This can only be done for Ranges containing different casings of one value. /// [Ranges from TryFindString, but not TryGetRangeStartingWith] /// </summary> /// <param name="r">Range to restrict</param> /// <param name="value">String8 casing of value to restrict to</param> /// <returns>Range constrained to subset matching value casing</returns> private Range MakeCaseSensitive(Range r, String8 value) { if (r.IsEmpty()) { return(r); } // Verify this was called only for casing variations [there isn't a single Range for prefixes] if (this[r.End].Length != value.Length) { throw new ArgumentOutOfRangeException(); } // Exclude values from start which don't match value case-sensitive int start; for (start = r.Start; start <= r.End; ++start) { if (value.CompareTo(this[start], false) == 0) { break; } } // Exclude values from end which don't match value case-sensitive int end; for (end = r.End; end > start; --end) { if (value.CompareTo(this[end], false) == 0) { break; } } return(new Range(start, end)); }
public int CompareValues(int leftIdentifier, int rightIdentifier) { if (leftIdentifier == 0) { if (rightIdentifier == 0) { // Both empty - equal return(0); } else { // Left is before right return(-1); } } else if (rightIdentifier == 0) { // Right is before left return(1); } else if (leftIdentifier < 0 && rightIdentifier < 0) { // If both new, compare in AddedValues return(_addedValues.CompareValues(-leftIdentifier, -rightIdentifier)); } else if (leftIdentifier >= 0 && rightIdentifier >= 0) { // If both existing, compare in ExistingValues return(_existingValues.CompareValues(leftIdentifier, rightIdentifier)); } else { // Otherwise, get and compare string values for each String8 left = this[leftIdentifier]; String8 right = this[rightIdentifier]; return(left.CompareTo(right)); } }