internal IndexNode(ImmutableTreeList <Node> .Node children, out ImmutableTreeList <Node> .Node?lastNode) { if (children.Count > _offsets.Length) { lastNode = ImmutableTreeList <Node> .Node.Empty; } else { lastNode = null; } for (int pageIndex = 0; pageIndex < children.Count; pageIndex += _offsets.Length) { IndexNode current = pageIndex == 0 ? this : new IndexNode(); if (lastNode != null) { lastNode = ImmutableTreeList <Node> .Node.Insert(lastNode, lastNode.Count, current); } int pageSize = Math.Min(children.Count - pageIndex, _offsets.Length); for (int i = 0; i < pageSize; i++) { current._offsets[i] = current._count; current._nodes[i] = children[pageIndex + i]; current._count += current._nodes[i].Count; } current._nodeCount = pageSize; } }
internal override ImmutableTreeList <Node> .Node InsertRange(bool isAppend, int index, IEnumerable <T> collection) { Node insertionNode = AsMutable(); int insertionNodeIndex = 0; ImmutableTreeList <Node> .Node lastLeaf = ImmutableTreeList <Node> .Node.Insert(ImmutableTreeList <Node> .Node.Empty, 0, insertionNode); foreach (T item in collection) { Debug.Assert(index >= 0 && index <= ((LeafNode)insertionNode)._data.Length, "Assertion failed: index >= 0 && index <= ((LeafNode)insertionNode)._data.Length"); (_, Node? newLastLeaf) = insertionNode.Insert(isAppend, index, item); if (newLastLeaf != null) { // this insertion resulted in a split, so at minimum 'index' must be updated if (insertionNodeIndex != lastLeaf.Count - 1) { lastLeaf = ImmutableTreeList <Node> .Node.Insert(lastLeaf, insertionNodeIndex + 1, newLastLeaf); // We were not inserting into the last leaf (an earlier split in the InsertRange operation // resulted in insertions prior to the last leaf) if (index < insertionNode.Count) { // The split does not change the insertion node. index++; } else { index = index + 1 - insertionNode.Count; insertionNode = newLastLeaf; insertionNodeIndex++; } } else if (index < insertionNode.Count) { // The split resulted in a new last leaf, but no change in the insertion node. index++; lastLeaf = ImmutableTreeList <Node> .Node.Insert(lastLeaf, insertionNodeIndex + 1, newLastLeaf); } else { // The split resulted in a new last leaf which becomes the new insertion node. index = index + 1 - insertionNode.Count; lastLeaf = ImmutableTreeList <Node> .Node.Insert(lastLeaf, insertionNodeIndex + 1, newLastLeaf); insertionNode = newLastLeaf; insertionNodeIndex++; } } else { index++; } } return(lastLeaf); }
internal Enumerator(ImmutableTreeList <T> list, TreeSpan span, Builder?builder) { _root = list._root; _span = span; _builder = builder; _version = builder?.Version ?? 0; _index = -1; _leafNode = null; _leafIndex = -1; _current = default !;
internal override ImmutableTreeList <TOutput> .Node ConvertAll <TOutput>(Func <T, TOutput> converter, ImmutableTreeList <TOutput> .Node?convertedNextNode) { var result = new ImmutableTreeList <TOutput> .LeafNode(); for (int i = _count - 1; i >= 0; i--) { result._data[i] = converter(_data[i]); } result._count = _count; return(result); }
internal static Node InsertRange(Node root, int index, IEnumerable <T> collection) { if (collection == null) { throw new ArgumentNullException(nameof(collection)); } if (index < 0) { throw new ArgumentOutOfRangeException(nameof(index)); } if (index > root.Count) { throw new ArgumentOutOfRangeException(); } // We can't insert a range into the empty node if (root == Empty) { root = new LeafNode(); } ImmutableTreeList <Node> .Node?splitNode = root.InsertRange(index == root.Count, index, collection); while (splitNode != null) { if (splitNode.Count == 1) { root = splitNode[0]; break; } else { // Make a new level, walking nodes on the previous root level from 'node' to 'splitNode' IndexNode newRoot = new IndexNode(splitNode, out splitNode); root = newRoot; } } if (root.Count == 0) { return(Empty); } return(root); }
internal Enumerator(ImmutableTreeList <T> .Enumerator enumerator) { _enumerator = enumerator; }
internal Builder(ImmutableTreeList <T> list) { _root = list._root; }
public ImmutableTreeList <TOutput> ConvertAll <TOutput>(Func <T, TOutput> converter) { ImmutableTreeList <TOutput> .Node newRoot = _root.ConvertAll(converter); newRoot.Freeze(); return(new ImmutableTreeList <TOutput>(newRoot)); }
private ImmutableTreeQueue(ImmutableTreeList <T> treeList) { _treeList = treeList; }
internal override ImmutableTreeList <TOutput> .Node ConvertAll <TOutput>(Func <T, TOutput> converter, ImmutableTreeList <TOutput> .Node?convertedNextNode) { return(ImmutableTreeList <TOutput> .Node.Empty); }
internal abstract ImmutableTreeList <TOutput> .Node ConvertAll <TOutput>(Func <T, TOutput> converter, ImmutableTreeList <TOutput> .Node?convertedNextNode);
internal Enumerator(ImmutableTreeList <T> list, Builder?builder) : this(list, list._root.Span, builder) { }
internal Enumerator(ImmutableTreeList <T> list) : this(list, list._root.Span, builder : null) { }
private ImmutableSortedTreeList(ImmutableTreeList <T> treeList, IComparer <T> comparer) { _treeList = treeList; _comparer = comparer; }
private ImmutableTreeStack(ImmutableTreeList <T> treeList) { _treeList = treeList; }
internal Builder(ImmutableSortedTreeList <T> immutableList) { _immutableList = immutableList; _treeList = immutableList._treeList.ToBuilder(); }