function partitionNode()

in packages/core/micro/src/adjust-tree/delete.ts [97:206]


function partitionNode<T>(ctx: TreeContext<T>, node: InteriorNode<T>, startOffset: number, startIndex: number, endOffset: number, endIndex: number): Deletion<T> {
    assert("startIndex < endIndex", startIndex < endIndex);
    const { lengths, segments, size } = node;

    let leftSplitState = startOffset === 0 ? undefined : startIndex;
    let rightSplitState = endOffset === 0 ? undefined : endIndex;

    const firstSplit: Deletion<T> = startOffset === 0 ?
        { orphan: undefined, deleted: leftmostLeaf(segments[startIndex]) }
        : splitChildL(ctx, node, startIndex, startOffset);

    if (startOffset !== 0) {
        lengths[startIndex] = startOffset;
    }

    const secondSplit: Deletion<T> | undefined = endOffset === 0 ?
        endIndex === size
            ? undefined
            : { orphan: undefined, deleted: leftmostLeaf(segments[endIndex]).prev! }
        : splitChildR(ctx, node, endIndex, endOffset);

    if (endOffset !== 0) {
        lengths[endIndex] -= endOffset;
    }

    const firstDeletedLeaf = firstSplit.deleted;
    const firstRetainedLeaf = firstDeletedLeaf.prev;
    const lastDeletedLeaf = secondSplit ? secondSplit.deleted : undefined;
    const lastRetainedLeaf = lastDeletedLeaf ? lastDeletedLeaf.next : undefined;

    if (firstRetainedLeaf) {
        firstRetainedLeaf.next = lastRetainedLeaf;
    }
    if (lastRetainedLeaf) {
        lastRetainedLeaf.prev = firstRetainedLeaf;
    }
    if (lastDeletedLeaf) {
        lastDeletedLeaf.next = undefined;
    }
    firstDeletedLeaf.prev = undefined;

    const wholeStartIndex = startOffset === 0 ? startIndex : startIndex + 1;
    const toRemove = endIndex - wholeStartIndex;

    if (toRemove > 0) {
        deleteNodeRange(node, wholeStartIndex, toRemove, undefined!)
        rightSplitState = rightSplitState === undefined ? undefined : rightSplitState - toRemove;
        endIndex -= toRemove;
    }

    let remainingOrphan: Orphan<T> | undefined;
    let remainingOrphanIndex: number | undefined;

    if (firstSplit.orphan && secondSplit && secondSplit.orphan) {
        leftSplitState = undefined;
        rightSplitState = undefined;
        [remainingOrphanIndex, remainingOrphan] =
            mergeOrphans(ctx, node, startIndex, firstSplit.orphan, endIndex, secondSplit.orphan);
    }
    else if (firstSplit.orphan) {
        remainingOrphan = firstSplit.orphan;
        remainingOrphanIndex = startIndex;
        leftSplitState = undefined;
    }
    else if (secondSplit && secondSplit.orphan) {
        remainingOrphan = secondSplit.orphan;
        remainingOrphanIndex = endIndex;
        rightSplitState = undefined;
    }

    if (remainingOrphan) {
        assert("remainingOrphanIndex is defined when orphan is", remainingOrphanIndex !== undefined);
        if (node.size === 1) {
            return remainingOrphan.heightDelta++, { orphan: remainingOrphan, deleted: firstDeletedLeaf };
        }

        deleteNodeRange(node, remainingOrphanIndex, 1, undefined!);
        if (leftSplitState !== undefined && leftSplitState > remainingOrphanIndex) { leftSplitState--; }
        if (rightSplitState !== undefined && rightSplitState > remainingOrphanIndex) { rightSplitState--; }

        const size = node.size;
        if (remainingOrphanIndex === 0) {
            applyInsertion(ctx, node, 0, remainingOrphan.length, reparent(ctx, node.segments[0], remainingOrphan, /* before */ true));
            const adjustment = node.size - size;
            if (leftSplitState !== undefined) { leftSplitState + adjustment; }
            if (rightSplitState !== undefined) { rightSplitState + adjustment; }
        }
        else {
            const idx = remainingOrphanIndex - 1;
            applyInsertion(ctx, node, idx, remainingOrphan.length, reparent(ctx, node.segments[idx], remainingOrphan, /* before */ false));
            const adjustment = node.size - size;
            if (leftSplitState !== undefined && leftSplitState > idx) { leftSplitState + adjustment; }
            if (rightSplitState !== undefined && rightSplitState > idx) { rightSplitState + adjustment; }
        }
    }

    let o1: Orphan<T> | undefined;
    let o2: Orphan<T> | undefined;
    if (leftSplitState !== undefined) {
        const size = node.size;
        o1 = ensureBalancedChildInNode(ctx, node, leftSplitState);
        if (size !== node.size) {
            rightSplitState = rightSplitState === undefined ? undefined : rightSplitState - 1;
        }
    }
    if (rightSplitState !== undefined) {
        o2 = ensureBalancedChildInNode(ctx, node, rightSplitState);
    }
    return { orphan: o1 || o2, deleted: firstDeletedLeaf };
}