Ejemplo n.º 1
0
        private int RemoveHelper(int removeAt, int count, SortedRangeValueList <T> moveRanges)
        {
            if (removeAt >= Count)
            {
                return(rangeValues.Count);
            }
            int n = Split(removeAt);

            Split(removeAt + count);
            int total       = 0;
            int deleteCount = 0;

            while (total < count && n + deleteCount < rangeValues.Count)
            {
                RangeValuePair <T> rv = rangeValues[n + deleteCount];
                total += rv.Count;
                deleteCount++;
                if (moveRanges != null && !rv.Value.Equals(defaultValue))
                {
                    moveRanges.rangeValues.Add(new RangeValuePair <T>(rv.Start - removeAt, rv.Count, rv.Value));
                }
            }
            rangeValues.RemoveRange(n, deleteCount);
            return(n);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Compares the current range with the range of the other object. The value is
        /// ignored.
        /// </summary>
        /// <param name="obj">An object to compare with this instance.</param>
        /// <returns>
        /// A 32-bit signed integer that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than zero This instance is less than <paramref name="obj"/>. Zero This instance is equal to <paramref name="obj"/>. Greater than zero This instance is greater than <paramref name="obj"/>.
        /// </returns>
        public int CompareTo(object obj)
        {
            RangeValuePair <T> x = this;
            var y = (RangeValuePair <T>)obj;

            if (x.start >= y.start && x.start < y.start + y.count ||
                y.start >= x.start && y.start < x.start + x.count)
            {
                return(0);
            }

            return(start.CompareTo(y.start));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Gets a range that contains the specified index and also
        /// returns a count indicating the delta between the index and the
        /// end of the range.
        /// </summary>
        /// <param name="index">The index.</param>
        /// <param name="count">The count.</param>
        /// <returns></returns>
        public T GetRange(int index, out int count)
        {
            if (index >= Count)
            {
                count = int.MaxValue;
                return(defaultValue);
            }

            RangeValuePair <T> rv = GetRangeValue(index);

            count = rv.End - index + 1;
            return(rv.Value);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Inserts a range intialized with a given value at
        /// the specified index. When necessary it splits a range and creates
        /// a new range value pair.
        /// </summary>
        /// <param name="insertAt">The insertion point.</param>
        /// <param name="count">The count.</param>
        /// <param name="value">The value.</param>
        /// <param name="moveRanges">Allocate this object before a preceeding Remove call when moving ranges.
        /// Otherwise specify null.</param>
        public void Insert(int insertAt, int count, T value, SortedRangeValueList <T> moveRanges)
        {
            if (insertAt >= Count)
            {
                if (value.Equals(defaultValue) && (moveRanges == null || moveRanges.Count == 0))
                {
                    return;
                }

                EnsureCount(insertAt);
                rangeValues.Add(new RangeValuePair <T>(insertAt, count, value));
                if (rangeValues.Count >= 2)
                {
                    Merge(rangeValues.Count - 2);
                }
            }
            else
            {
                int n = rangeValues.BinarySearch(new RangeValuePair <T>(insertAt));
                RangeValuePair <T> rv = rangeValues[n];
                if (value.Equals(rv.Value))
                {
                    rv.Count += count;
                    AdjustStart(n + 1, count);
                }
                else
                {
                    n = Split(insertAt, n);
                    Split(insertAt + 1);
                    var rv2 = new RangeValuePair <T>(insertAt, count, value);
                    rangeValues.Insert(n, rv2);
                    AdjustStart(n + 1, count);
                    Merge(n);
                    if (n > 0)
                    {
                        Merge(n - 1);
                    }
                }
            }

            if (moveRanges != null)
            {
                foreach (RangeValuePair <T> rv in moveRanges)
                {
                    SetRange(rv.Start + insertAt, rv.Count, rv.Value);
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Sets the value for a range at the specified index. When necessary ranges
        /// are split or merged to make sure integrity of the list is maintained.
        /// (SortedRangeValueList ensures that ranges
        /// of the elements inside the list do not overlap and it also ensures
        /// that there are no empty gaps meaning that the subsequent range will
        /// always have the Start position be set to the End position of the previous
        /// range plus one.)
        /// </summary>
        /// <param name="index">The index for the range to be changed.</param>
        /// <param name="count">The count.</param>
        /// <param name="value">The value.</param>
        public void SetRange(int index, int count, T value)
        {
            if (index >= Count && value.Equals(defaultValue))
            {
                return;
            }

            EnsureCount(index);
            int n  = RemoveHelper(index, count, null);
            var rv = new RangeValuePair <T>(index, count, value);

            rangeValues.Insert(n, rv);
            Merge(n);
            if (n > 0)
            {
                Merge(n - 1);
            }
        }
Ejemplo n.º 6
0
        int Split(int index, int n)
        {
            RangeValuePair <T> rv = rangeValues[n];

            if (rangeValues[n].Start == index)
            {
                return(n);
            }

            int count1 = index - rangeValues[n].Start;
            int count2 = rangeValues[n].Count - count1;

            rv.Count = count1;

            var rv2 = new RangeValuePair <T>(index, count2, rv.Value);

            rangeValues.Insert(n + 1, rv2);
            return(n + 1);
        }
Ejemplo n.º 7
0
        void Merge(int n)
        {
            if (n >= rangeValues.Count)
            {
                return;
            }
            RangeValuePair <T> rv1 = rangeValues[n];

            if (n == rangeValues.Count - 1)
            {
                if (rv1.Value.Equals(defaultValue))
                {
                    rangeValues.RemoveAt(n);
                }
                return;
            }
            RangeValuePair <T> rv2 = rangeValues[n + 1];

            if (rv1.Value.Equals(rv2.Value))
            {
                rv1.Count += rv2.Count;
                rangeValues.RemoveAt(n + 1);
            }
        }