/// <summary> /// Add the given element to the set. /// </summary> /// <param name="element"></param> public void Add(int element) { int rangeIdx = FindIndexOfRangeFor(element); if (rangeIdx >= 0) { // Element is already there. return; } // We're going to add one, so up the count. ++count; int insertionPoint = -rangeIdx - 1; // Try to find a range we can expand to include this element. int rangeBelowIdx = FindIndexOfRangeFor(element - 1); int rangeAboveIdx = FindIndexOfRangeFor(element + 1); if (rangeBelowIdx >= 0) { IRange below = (IRange)rangeList[rangeBelowIdx]; if (rangeAboveIdx >= 0) { // We have ranges below and above, so we can merge two existing ranges. rangeList[rangeBelowIdx] = new Range(below.Low, ((IRange)rangeList[rangeAboveIdx]).High); rangeList.RemoveAt(rangeAboveIdx); } else { // We don't have a range above, so just expand the existing range below. rangeList[rangeBelowIdx] = new Range(below.Low, element); } } else if (rangeAboveIdx >= 0) { // We have an existing range above that we can expand downward. rangeList[rangeAboveIdx] = new Range(element, ((IRange)rangeList[rangeAboveIdx]).High); } else { // We need a new single-element range. IRange newRange = new SingleElementRange(element); rangeList.Insert(insertionPoint, newRange); } }
/// <summary> /// Remove the given element from the rangeset. /// </summary> /// <param name="element"></param> public void Remove(int element) { int rangeIdx = FindIndexOfRangeFor(element); if (rangeIdx < 0) { // It's not here, nothing to do. return; } // OK, we have it. There are four cases. IRange range = (IRange)rangeList[rangeIdx]; if (range.Low == element && range.High == element) { // 1. It's part of a single-element range. Remove the whole thing. rangeList.RemoveAt(rangeIdx); } else if (range.Low == element) { // 2. We have a range that we need to shrink from the bottom. if (range.High == element + 1) { rangeList[rangeIdx] = new SingleElementRange(range.High); } else { rangeList[rangeIdx] = new Range(range.Low + 1, range.High); } } else if (range.High == element) { // 3. We have a range that we need to shrink from the top. if (range.Low == element - 1) { rangeList[rangeIdx] = new SingleElementRange(range.Low); } else { rangeList[rangeIdx] = new Range(range.Low, range.High - 1); } } else { // 4. Darn, we have to split a range. if (range.Low == element - 1) { rangeList[rangeIdx] = new SingleElementRange(range.Low); } else { rangeList[rangeIdx] = new Range(range.Low, element - 1); } if (range.High == element + 1) { rangeList.Insert(rangeIdx + 1, new SingleElementRange(range.High)); } else { rangeList.Insert(rangeIdx + 1, new Range(element + 1, range.High)); } } // We also have to make sure to decrement the cached count. --count; }