예제 #1
0
        /// <summary>
        /// Returns the competeCollection - thisCollection
        /// </summary>
        /// <returns></returns>
        public RangeCollection Complement(long fullRangeBegin, long fullRangeEnd)
        {
            RangeCollection result = new RangeCollection();

            long rangeLeftToCoverBegin = fullRangeBegin;

            foreach (KeyValuePair <long, long> range in Ranges)
            {
                long start = range.Key;
                long last  = range.Value;
                if (start > rangeLeftToCoverBegin)
                {
                    result.AddRange(rangeLeftToCoverBegin, Math.Min(start - 1, fullRangeEnd));
                }
                rangeLeftToCoverBegin = Math.Max(rangeLeftToCoverBegin, last + 1);
                if (rangeLeftToCoverBegin > fullRangeEnd)
                {
                    break;
                }
            }
            if (rangeLeftToCoverBegin <= fullRangeEnd)
            {
                result.AddRange(rangeLeftToCoverBegin, fullRangeEnd);
            }
            return(result);
        }
예제 #2
0
        /// <summary>
        /// Returns a collection of elements at what would be the i'th element for i \in [startIdx,lastIdx]. startIdx and lastIdx are 0-based.
        /// </summary>
        private RangeCollection ElementsAt(long startIndex, long lastIndex)
        {
            if (lastIndex < startIndex || startIndex < 0 || lastIndex >= Count())
            {
                throw new ArgumentOutOfRangeException(string.Format("{0}-{1} must be a non-empty range that falls between 0 and {2}", startIndex, lastIndex, Count() - 1));
            }

            RangeCollection result = new RangeCollection();

            long countSoFar = 0;

            foreach (KeyValuePair <long, long> range in Ranges)
            {
                long rangeLength = range.Value - range.Key + 1;
                if (startIndex - countSoFar < rangeLength)
                {
                    long start = range.Key + startIndex - countSoFar;
                    long lastIfContinuousRange = range.Key + lastIndex - countSoFar;
                    long last = Math.Min(range.Value, lastIfContinuousRange);   // if startIdx-lastIdx falls completely in range, then take 2nd entry.
                    result.AddRange(start, last);

                    if (lastIfContinuousRange <= range.Value) // if this range covers the remaining indeces, we're done.
                    {
                        return(result);
                    }
                    else
                    {
                        startIndex = countSoFar + rangeLength;
                    }
                }

                countSoFar += rangeLength;
            }
            throw new NotImplementedException("If we get here, then there's a bug in the implementation.");
        }