public void AddSegment(T[] array, int offset, int length, bool toBeCopied)
        {
            if (length <= 0)
            {
                return;
            }

            var currentTotal = m_Count;

            ArraySegmentEx <T> segment = null;

            if (!toBeCopied)
            {
                segment = new ArraySegmentEx <T>(array, offset, length);
            }
            else
            {
                segment = new ArraySegmentEx <T>(array.CloneRange(offset, length), 0, length);
            }

            segment.From = currentTotal;
            m_Count      = currentTotal + segment.Count;
            segment.To   = m_Count - 1;

            m_Segments.Add(segment);
        }
        public void RemoveSegmentAt(int index)
        {
            var removedSegment = m_Segments[index];
            int removedLen     = removedSegment.To - removedSegment.From + 1;

            m_Segments.RemoveAt(index);

            m_PrevSegment = null;

            //the removed item is not the the last item
            if (index != m_Segments.Count)
            {
                for (int i = index; i < m_Segments.Count; i++)
                {
                    m_Segments[i].From -= removedLen;
                    m_Segments[i].To   -= removedLen;
                }
            }

            m_Count -= removedLen;
        }
 public void ClearSegements()
 {
     m_Segments.Clear();
     m_PrevSegment = null;
     m_Count       = 0;
 }
        private int GetElementInternalIndex(int index, out ArraySegmentEx <T> segment)
        {
            segment = null;

            if (index < 0 || index > Count - 1)
            {
                return(-1);
            }

            if (index == 0)
            {
                m_PrevSegment      = m_Segments[0];
                m_PrevSegmentIndex = 0;
                segment            = m_PrevSegment;
                return(m_PrevSegment.Offset);
            }

            int compareValue = 0;

            if (m_PrevSegment != null)
            {
                if (index >= m_PrevSegment.From)
                {
                    if (index <= m_PrevSegment.To)
                    {
                        segment = m_PrevSegment;
                        return(m_PrevSegment.Offset + index - m_PrevSegment.From);
                    }
                    else
                    {
                        compareValue = 1;
                    }
                }
                else
                {
                    compareValue = -1;
                }
            }

            int from, to;

            if (compareValue != 0)
            {
                from = m_PrevSegmentIndex + compareValue;

                var trySegment = m_Segments[from];

                if (index >= trySegment.From && index <= trySegment.To)
                {
                    segment = trySegment;
                    return(trySegment.Offset + index - trySegment.From);
                }

                from += compareValue;

                var currentSegment = m_Segments[from];
                if (index >= currentSegment.From && index <= currentSegment.To)
                {
                    m_PrevSegment      = currentSegment;
                    m_PrevSegmentIndex = from;
                    segment            = currentSegment;
                    return(currentSegment.Offset + index - currentSegment.From);
                }

                if (compareValue > 0)
                {
                    from++;
                    to = m_Segments.Count - 1;
                }
                else
                {
                    var tmp = from - 1;
                    from = 0;
                    to   = tmp;
                }
            }
            else
            {
                from = 0;
                to   = m_Segments.Count - 1;
            }

            int segmentIndex = -1;

            var result = QuickSearchSegment(from, to, index, out segmentIndex);

            if (result != null)
            {
                m_PrevSegment      = result;
                m_PrevSegmentIndex = segmentIndex;
                segment            = m_PrevSegment;
                return(result.Offset + index - result.From);
            }

            m_PrevSegment = null;

            return(-1);
        }