Esempio n. 1
0
 private InsertEnumerator(InsertEnumerator enumerator, SparseMemorySpan <T> sparseMemorySpan, int count)
 {
     BaseEnumerator   = enumerator.BaseEnumerator;
     SparseMemorySpan = sparseMemorySpan;
     ItemsCount       = count;
     List             = enumerator.List;
     Current          = enumerator.Current;
     CurrentItemIndex = enumerator.CurrentItemIndex;
     HasAny           = enumerator.HasAny;
 }
Esempio n. 2
0
        private protected void InsertRangeImpl(long index, IEnumerable <T> collection)
        {
            var enumerator = new InsertEnumerator(collection.GetEnumerator(), this);

            InsertRangeImpl(index, enumerator);
        }
Esempio n. 3
0
        private protected void InsertRangeImpl(long index, InsertEnumerator enumerator)
        {
            if (enumerator.HasAny == false)
            {
                return;
            }

            try
            {
                EnterStructureChange();

                var count  = 1;
                var cursor = FindInsertNodeCursorImpl(index);

                if (cursor.Node is RealizedNode && cursor.NodeSize == NodeCapacity && index == cursor.NodeOffset + cursor.NodeSize)
                {
                    cursor = cursor.GetNext();
                }

                var nextNode = cursor.Node.Next;

                if (cursor.Node is RealizedNode realizedNode)
                {
                    var splitIndex = (int)(index - cursor.NodeOffset);
                    var splitCount = (int)(realizedNode.Size - splitIndex);

                    if (splitCount == 0)
                    {
                        realizedNode.Span[(int)realizedNode.Size++] = enumerator.Current;
                    }
                    else
                    {
                        var splitItems = AllocateItems();
                        var sourceSpan = realizedNode.Span.Slice(splitIndex, splitCount);
                        var targetSpan = splitItems.Span.Slice(0, splitCount);

                        sourceSpan.CopyTo(targetSpan);
                        sourceSpan.Clear();

                        realizedNode.Size             = splitIndex + 1;
                        realizedNode.Span[splitIndex] = enumerator.Current;

                        enumerator = enumerator.WithItems(splitItems, splitCount);
                        count     -= splitCount;
                    }
                }
                else
                {
                    realizedNode = EnsureRealizedNode(ref cursor, index, true);
                    nextNode     = realizedNode.Next;

                    cursor = NavigateTo(index);

                    cursor.Node.SetItem(ref cursor, enumerator.Current);
                }

                while (true)
                {
                    while (realizedNode.Size < NodeCapacity && enumerator.MoveNext())
                    {
                        realizedNode.Span[(int)realizedNode.Size++] = enumerator.Current;
                        count++;
                    }

                    if (realizedNode.Size < NodeCapacity)
                    {
                        break;
                    }

                    if (enumerator.MoveNext() == false)
                    {
                        break;
                    }

                    count++;

                    var next = Manager.GetRealizedNode();

                    next.Size = 1;
                    next.Prev = realizedNode;

                    next.Span[0] = enumerator.Current;

                    realizedNode.Next = next;
                    realizedNode      = next;
                }

                enumerator.Dispose();

                realizedNode.Next = nextNode;
                nextNode.Prev     = realizedNode;

                LongCount += count;
            }
            finally
            {
                LeaveStructureChange();
            }
        }