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; }
private protected void InsertRangeImpl(long index, IEnumerable <T> collection) { var enumerator = new InsertEnumerator(collection.GetEnumerator(), this); InsertRangeImpl(index, enumerator); }
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(); } }