Exemple #1
0
            internal override (Node currentNode, Node?splitNode) Insert(bool isAppend, int index, T item)
            {
                if (_count < _data.Length)
                {
                    LeafNode mutableNode = AsMutable();
                    if (index < _count)
                    {
                        mutableNode._data.Copy(index, ref mutableNode._data, index + 1, _count - index);
                    }

                    mutableNode._data[index] = item;
                    mutableNode._count++;
                    return(currentNode : mutableNode, splitNode : null);
                }

                if (isAppend)
                {
                    // optimize the case of adding at the end of the overall list
                    var(splitNode, _) = Empty.Insert(isAppend, 0, item);
                    return(currentNode : this, splitNode);
                }
                else
                {
                    return(AsMutable().InsertWithSplit(isAppend, index, item));
                }
            }
Exemple #2
0
            internal override Node Insert(int branchingFactor, bool isAppend, int index, T item)
            {
                if (_count < _data.Length)
                {
                    if (index < _count)
                    {
                        Array.Copy(_data, index, _data, index + 1, _count - index);
                    }

                    _data[index] = item;
                    _count++;
                    return(null);
                }

                if (isAppend)
                {
                    // optimize the case of adding at the end of the overall list
                    var result = (LeafNode)Empty.Insert(branchingFactor, isAppend, 0, item);
                    _next = result;
                    return(result);
                }
                else
                {
                    // split the node
                    LeafNode splitNode  = new LeafNode(branchingFactor);
                    int      splitPoint = _count / 2;

                    bool forceNext = false;
                    if ((_count + 1) / 2 > splitPoint && index > splitPoint)
                    {
                        // When splitting a node with an odd branching factor, prior to insertion one split node will
                        // have (b-1)/2 nodes and the other will have (b+1)/2 nodes. Since the minimum number of nodes
                        // after insertion is (b+1)/2, the split point uniquely determines the insertion point. This
                        // block handles the case where the insertion point is index (b+1)/2 by forcing it to the first
                        // node of the next page instead of adding it (where it fits) at the end of the first page.
                        splitPoint++;
                        forceNext = true;
                    }

                    Array.Copy(_data, splitPoint, splitNode._data, 0, _count - splitPoint);
                    Array.Clear(_data, splitPoint, _count - splitPoint);

                    splitNode._count = _count - splitPoint;
                    _count           = splitPoint;

                    // insert the new element into the correct half
                    if (!forceNext && index <= splitPoint)
                    {
                        Insert(branchingFactor, false, index, item);
                    }
                    else
                    {
                        splitNode.Insert(branchingFactor, false, index - splitPoint, item);
                    }

                    splitNode._next = _next;
                    _next           = splitNode;
                    return(splitNode);
                }
            }