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;
                }
            }
Beispiel #2
0
            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 !;
Beispiel #4
0
            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);
            }
Beispiel #6
0
 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));
 }
Beispiel #9
0
 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();
 }