Esempio n. 1
0
        /// <summary>
        /// Removes items from the instance.
        /// </summary>
        /// <param name="itemCount">Number of items to remove</param>
        /// <returns></returns>
        /// <remarks>DO NOT dispose the original and then slice. Either the original or the sliced instance can be disposed, but not both.</remarks>
        public Multispan <T> Slice(int itemCount)
        {
            var result = new Multispan <T>();
            var first  = GetAt(0);

            // if the only thing needing slicing is the head
            if (first.Count > itemCount)
            {
                result._head  = _head.Slice(itemCount);
                result._count = _count;
                if (Count > 1)
                {
                    EnsureTailCapacity(ref result, _count - 1);
                    Array.Copy(_tail, result._tail, _count - 1);
                }
                return(result);
            }

            // head will be removed; this computes how many tail segments need to be removed
            // and how many items from the first segment that is not removed
            var itemsLeftToRemove    = itemCount - first.Count;
            int tailSegmentsToRemove = 1; // one is moved to the head

            for (int tailIndex = 0; tailIndex < _count - 1; tailIndex++)
            {
                if (itemsLeftToRemove == 0)
                {
                    break;
                }
                var segment = _tail[tailIndex];
                if (segment.Count >= itemsLeftToRemove)
                {
                    break;
                }
                else
                {
                    tailSegmentsToRemove++;
                    itemsLeftToRemove -= segment.Count;
                }
            }

            result._head  = _tail[tailSegmentsToRemove - 1].Slice(itemsLeftToRemove);
            result._count = _count - tailSegmentsToRemove;
            if (result._count == 1)
            {
                return(result);                    // we don't need tail; this multispan has just head
            }
            EnsureTailCapacity(ref result, result._count - 1);
            Array.Copy(_tail, tailSegmentsToRemove, result._tail, 0, result._count - 1);
            return(result);
        }
Esempio n. 2
0
        private static void EnsureTailCapacity(ref Multispan <T> ms, int count)
        {
            int desired = (ms._tail == null) ? 4 : ms._tail.Length * 2;

            while (desired < count)
            {
                desired = desired * 2;
            }
            var newSegments = ArrayPool <ArraySegment <T> > .Shared.Rent(desired);

            if (ms._tail != null)
            {
                ms._tail.CopyTo(newSegments, 0);
                ArrayPool <ArraySegment <T> > .Shared.Return(ms._tail);
            }
            ms._tail = newSegments;
        }
Esempio n. 3
0
 internal Enumerator(Multispan <T> buffer)
 {
     _buffer = buffer;
     _index  = -1;
 }