/// <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.");
        }
        /// <summary>
        /// Returns the competeCollection - thisCollection
        /// </summary>
        /// <returns></returns>
        public RangeCollection Complement(long fullRangeBegin, long fullRangeLast)
        {
            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, fullRangeLast));
                }
                rangeLeftToCoverBegin = Math.Max(rangeLeftToCoverBegin, last + 1);
                if (rangeLeftToCoverBegin > fullRangeLast)
                {
                    break;
                }
            }
            if (rangeLeftToCoverBegin <= fullRangeLast)
            {
                result.AddRange(rangeLeftToCoverBegin, fullRangeLast);
            }
            return(result);
        }
        /// <summary>
        /// Parses strings of the form -10--5,-2-10,12-12 . Spaces are allowed, no other characters are.
        /// If mergeOverlappingRanges, then, for example, 2-3,4-5 is represented
        /// as 2-5. Otherwise, they're maintained as separate ranges. The only difference is in the behavior of the ToString() call.
        /// By extension, this will change how a RangeCollection is parsed into a RangeCollectionCollection using the latter's
        /// GetInstance(RangeCollection) initializer.
        /// </summary>
        /// <param name="ranges">A range or the string empty. \"empty\" will return an empty range.</param>
        /// <returns>a new RangeCollection</returns>
        public static RangeCollection Parse(string ranges)
        {
            ranges = ranges.Trim();
            RangeCollection aRangeCollection = new RangeCollection();

            aRangeCollection.InternalParse(ranges);

            return(aRangeCollection);
        }
        /// <summary>
        /// Add the longs of one RangeCollection to this RangeCollection.
        /// </summary>
        /// <param name="rangeCollection">The RangeCollection to add</param>
        /// <returns>true of all the elements added are new; otherwise, false</returns>
        public bool TryAddRangeCollection(RangeCollection rangeCollection)
        {
            bool allNew = true;

            foreach (KeyValuePair <long, long> startAndLast in rangeCollection.Ranges)
            {
                allNew &= TryAdd(startAndLast.Key, startAndLast.Value - startAndLast.Key + 1);
            }
            return(allNew);
        }
        /// <summary>
        /// Returns a collection of elements at what would be the nth element for i \in rangeCollectionOfIndeces.
        /// </summary>
        /// <param name="rangeCollectionOfIndeces">0-based indices.</param>
        public RangeCollection ElementsAt(RangeCollection rangeCollectionOfIndeces)
        {
            RangeCollection result = new RangeCollection();

            foreach (KeyValuePair <long, long> range in rangeCollectionOfIndeces.Ranges)
            {
                result.AddRangeCollection(ElementsAt(range.Key, range.Value));
            }
            return(result);
        }
 /// <summary>
 /// Tells if this RangeCollection is a superset of another. An an equal RangeCollection is a superset.
 /// </summary>
 /// <param name="rangeCollection">The RangeCollection that may be the subset</param>
 /// <returns>true, if this RangeCollection is a superset; otherwise, false</returns>
 public bool Contains(RangeCollection rangeCollection)
 {
     foreach (KeyValuePair <long, long> range in this.Ranges)
     {
         if (!Contains(range.Key, range.Value))
         {
             return(false);
         }
     }
     return(true);
 }
Beispiel #7
0
        static public void Test()
        {
            RangeCollection aRangeCollection = new RangeCollection();

            aRangeCollection.Add(0);
            Helper.CheckCondition("0" == aRangeCollection.ToString());
            aRangeCollection.Add(1);
            Helper.CheckCondition("0-1" == aRangeCollection.ToString());
            aRangeCollection.Add(4);
            Helper.CheckCondition("0-1,4" == aRangeCollection.ToString());
            aRangeCollection.Add(5);
            Helper.CheckCondition("0-1,4-5" == aRangeCollection.ToString());
            aRangeCollection.Add(7);
            Helper.CheckCondition("0-1,4-5,7" == aRangeCollection.ToString());
            aRangeCollection.Add(2);
            Helper.CheckCondition("0-2,4-5,7" == aRangeCollection.ToString());
            aRangeCollection.Add(3);
            Helper.CheckCondition("0-5,7" == aRangeCollection.ToString());
            aRangeCollection.Add(6);
            Helper.CheckCondition("0-7" == aRangeCollection.ToString());
            aRangeCollection.Add(-10);
            Helper.CheckCondition("-10,0-7" == aRangeCollection.ToString());
            aRangeCollection.Add(-5);
            Helper.CheckCondition("-10,-5,0-7" == aRangeCollection.ToString());

            string range = "-10--5,-3,-2-1,1-5,7-12,13-15,14-16,20-25,22-23";

            aRangeCollection = RangeCollection.Parse(range);
            Console.WriteLine(range);
            Console.WriteLine(aRangeCollection);


            range            = "1-5,0,4-10,-10--5,-12--3,15-20,12-21,-13";
            aRangeCollection = RangeCollection.Parse(range);

            Console.WriteLine(range);
            Console.WriteLine(aRangeCollection);

            Console.WriteLine("Count: " + aRangeCollection.Count());
            Console.WriteLine("Count -5 to 2: " + aRangeCollection.Count(-5, 2));

            //RangeCollectionCollection rcc = RangeCollectionCollection.GetInstance(aRangeCollection);
            //Console.WriteLine(rcc);
            //Console.WriteLine(rcc.GetContainingRangeCollection(-12));
            //Console.WriteLine(rcc.GetContainingRangeCollection(-10));
            //Console.WriteLine(rcc.GetContainingRangeCollection(-5));
            //Console.WriteLine(rcc.GetContainingRangeCollection(3));
            //Console.WriteLine(rcc.GetContainingRangeCollection(15));
        }
        /// <summary>
        /// Tests equality between two range collections
        /// </summary>
        /// <param name="rangeCollection">The range collection we're testing against</param>
        /// <returns>True if and only if the ranges are identical</returns>
        public bool Equals(RangeCollection rangeCollection)
        {
            if (null == rangeCollection)
            {
                return(false);
            }

            if (!this.startItems.SequenceEqual(rangeCollection.startItems))
            {
                return(false);
            }

            if (!this.itemToLength.Keys.SequenceEqual(rangeCollection.itemToLength.Keys))
            {
                return(false);
            }

            if (!this.itemToLength.Values.SequenceEqual(rangeCollection.itemToLength.Values))
            {
                return(false);
            }

            return(true);
        }
 /// <summary>
 /// Create a RangeCollection by doing a deep copy of a RangeCollection
 /// </summary>
 /// <param name="rangeCollection">A new RangeCollection</param>
 public RangeCollection(RangeCollection rangeCollection)
     : this()
 {
     this.startItems   = new List <long>(rangeCollection.startItems);
     this.itemToLength = new SortedDictionary <long, long>(rangeCollection.itemToLength);
 }
 /// <summary>
 /// Add the longs of one RangeCollection to this RangeCollection.
 /// </summary>
 /// <param name="rangeCollection">The RangeCollection to add</param>
 public void AddRangeCollection(RangeCollection rangeCollection)
 {
     TryAddRangeCollection(rangeCollection);
 }
Beispiel #11
0
        private static IEnumerable <KeyValuePair <T, long> > UseSkipList <T>(IEnumerable <T> enumerable, RangeCollection skipListOrNull)
        {
            long rowIndex = -1;

            foreach (T t in enumerable)
            {
                ++rowIndex;
                if (null != skipListOrNull && skipListOrNull.Contains(rowIndex))
                {
                    continue;
                }
                yield return(new KeyValuePair <T, long>(t, rowIndex));
            }
        }
Beispiel #12
0
        /// <summary>
        /// This method will spread out the work items--like dealing cards around the table, you only get every other K'th card,
        /// where K is the number of people, when batchCount=1. (Or else you get sets of batchCount-contiguous cards).
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="enumerable"></param>
        /// <param name="pieceIndexRangeCollection"></param>
        /// <param name="pieceCount"></param>
        /// <param name="batchCount"></param>
        /// <param name="skipListOrNull"></param>
        /// <returns>The item and it's original index in the enumerable.</returns>
        public static IEnumerable <KeyValuePair <T, long> > DivideWork <T>(IEnumerable <T> enumerable, RangeCollection pieceIndexRangeCollection,
                                                                           long pieceCount, long batchCount, RangeCollection skipListOrNull)
        {
            if (pieceIndexRangeCollection == null)
            {
                throw new ArgumentNullException("pieceIndexRangeCollection");
            }

            Helper.CheckCondition(batchCount > 0, string.Format(CultureInfo.CurrentCulture, Properties.Resource.BatchCountCondition));
            long pieceIndex = 0;
            long batchIndex = 0;
            bool inRange    = pieceIndexRangeCollection.Contains(pieceIndex);

            foreach (var tAndRowIndex in UseSkipList(enumerable, skipListOrNull))
            {
                if (inRange)
                {
                    yield return(tAndRowIndex);
                }

                ++batchIndex;
                if (batchIndex == batchCount)
                {
                    batchIndex = 0;
                    pieceIndex = (pieceIndex + 1) % pieceCount;
                    inRange    = pieceIndexRangeCollection.Contains(pieceIndex);
                }
            }
        }
Beispiel #13
0
 public void RunTasks(Bio.Util.RangeCollection tasksToRun, long taskCount)
 {
     throw new NotImplementedException();
 }