export class PendingNumericCellValues {
    values = [];
    assigned = [];
    get(cellIndex) {
        return this.assigned[cellIndex] === true ? this.values[cellIndex] : undefined;
    }
    has(cellIndex) {
        return this.assigned[cellIndex] === true;
    }
    set(cellIndex, value) {
        this.assigned[cellIndex] = true;
        this.values[cellIndex] = value;
    }
}
export class DirectFormulaIndexCollection {
    cellIndices = [];
    sharedCellIndices;
    indexByCell;
    deltas;
    deltaAssigned;
    scalarDeltaAssigned;
    currentResults;
    currentResultAssigned;
    directFormulaCoveredInputCellIndices;
    directFormulaCoveredInputCellSet;
    directRangeCoveredInputCellIndices;
    directRangeCoveredInputCellSet;
    deltaCount = 0;
    scalarDeltaCount = 0;
    constantDelta;
    validatedScalarDeltaSize = -1;
    cleanScalarDeltaSize = -1;
    trustedDirectScalarDeltaSize = -1;
    cycleIndependentScalarDeltaSize = -1;
    linearHasProbeCount = 0;
    sortedCellIndexMin;
    sortedCellIndexMax;
    get size() {
        return this.sharedCellIndices?.length ?? this.cellIndices.length;
    }
    add(cellIndex) {
        this.validatedScalarDeltaSize = -1;
        this.cleanScalarDeltaSize = -1;
        this.trustedDirectScalarDeltaSize = -1;
        this.cycleIndependentScalarDeltaSize = -1;
        this.clearSortedCellIndexBounds();
        this.materializeConstantDeltas();
        if (this.indexByCell) {
            if (this.indexByCell.has(cellIndex)) {
                return;
            }
            this.materializeSharedCellIndices();
            this.indexByCell.set(cellIndex, this.cellIndices.length);
            this.cellIndices.push(cellIndex);
            return;
        }
        for (let index = 0; index < this.size; index += 1) {
            if (this.getCellIndexAt(index) === cellIndex) {
                return;
            }
        }
        this.materializeSharedCellIndices();
        this.cellIndices.push(cellIndex);
        if (this.size > 16) {
            this.materializeIndexByCell();
        }
    }
    has(cellIndex) {
        if (!this.indexByCell && this.size > 16) {
            if (this.sharedCellIndices !== undefined && this.linearHasProbeCount < 4) {
                this.linearHasProbeCount += 1;
                for (let index = 0; index < this.sharedCellIndices.length; index += 1) {
                    if (this.sharedCellIndices[index] === cellIndex) {
                        return true;
                    }
                }
                return false;
            }
            this.materializeIndexByCell();
        }
        if (this.indexByCell) {
            return this.indexByCell.has(cellIndex);
        }
        for (let index = 0; index < this.size; index += 1) {
            if (this.getCellIndexAt(index) === cellIndex) {
                return true;
            }
        }
        return false;
    }
    hasAny(cellIndices, count = cellIndices.length) {
        const length = Math.min(count, cellIndices.length);
        const size = this.size;
        if (length <= 0 || size === 0) {
            return false;
        }
        if (this.sortedCellIndexMin !== undefined && this.sortedCellIndexMax !== undefined) {
            let mayOverlap = false;
            for (let inputIndex = 0; inputIndex < length; inputIndex += 1) {
                const cellIndex = cellIndices[inputIndex];
                if (cellIndex >= this.sortedCellIndexMin && cellIndex <= this.sortedCellIndexMax) {
                    mayOverlap = true;
                    break;
                }
            }
            if (!mayOverlap) {
                return false;
            }
        }
        if (!this.indexByCell && (length <= 4 || size <= 16)) {
            for (let inputIndex = 0; inputIndex < length; inputIndex += 1) {
                const cellIndex = cellIndices[inputIndex];
                for (let collectionIndex = 0; collectionIndex < size; collectionIndex += 1) {
                    if (this.getCellIndexAt(collectionIndex) === cellIndex) {
                        return true;
                    }
                }
            }
            return false;
        }
        for (let index = 0; index < length; index += 1) {
            if (this.has(cellIndices[index])) {
                return true;
            }
        }
        return false;
    }
    addDelta(cellIndex, delta) {
        this.addDeltaWithKind(cellIndex, delta, undefined);
    }
    addScalarDelta(cellIndex, delta) {
        this.addDeltaWithKind(cellIndex, delta, 'scalar');
    }
    addDeltaWithKind(cellIndex, delta, kind) {
        this.validatedScalarDeltaSize = -1;
        this.cleanScalarDeltaSize = -1;
        this.trustedDirectScalarDeltaSize = -1;
        this.cycleIndependentScalarDeltaSize = -1;
        this.clearSortedCellIndexBounds();
        if (this.constantDelta !== undefined) {
            const existingIndex = this.findIndex(cellIndex);
            if (existingIndex === -1 && Object.is(this.constantDelta, delta)) {
                this.materializeSharedCellIndices();
                if (this.indexByCell) {
                    this.indexByCell.set(cellIndex, this.cellIndices.length);
                }
                this.cellIndices.push(cellIndex);
                this.deltaCount += 1;
                if (kind === 'scalar') {
                    this.scalarDeltaCount += 1;
                }
                return;
            }
        }
        this.materializeConstantDeltas();
        const index = this.ensureIndex(cellIndex);
        this.deltas ??= [];
        this.deltaAssigned ??= [];
        this.scalarDeltaAssigned ??= [];
        if (!this.deltaAssigned[index]) {
            this.deltaAssigned[index] = true;
            this.deltaCount += 1;
            this.deltas[index] = delta;
            if (kind === 'scalar') {
                this.scalarDeltaAssigned[index] = true;
                this.scalarDeltaCount += 1;
            }
            return;
        }
        this.deltas[index] = (this.deltas[index] ?? 0) + delta;
        if (kind !== 'scalar' && this.scalarDeltaAssigned[index]) {
            this.scalarDeltaAssigned[index] = false;
            this.scalarDeltaCount -= 1;
        }
    }
    appendDeltas(cellIndices, deltas, kind) {
        this.appendDeltasWithOptions(cellIndices, deltas, kind, false);
    }
    appendSortedDeltas(cellIndices, deltas, kind) {
        this.appendDeltasWithOptions(cellIndices, deltas, kind, true);
    }
    appendDeltasWithOptions(cellIndices, deltas, kind, sortedAscending) {
        if (cellIndices.length === 0) {
            return;
        }
        this.validatedScalarDeltaSize = -1;
        this.cleanScalarDeltaSize = -1;
        this.trustedDirectScalarDeltaSize = -1;
        this.cycleIndependentScalarDeltaSize = -1;
        this.updateSortedCellIndexBoundsForAppend(cellIndices, sortedAscending);
        if (this.size !== 0) {
            this.clearSortedCellIndexBounds();
            if (cellIndices.length > 16 || this.size > 16) {
                this.appendPreparedDeltas(cellIndices, deltas, kind);
                return;
            }
            for (let index = 0; index < cellIndices.length; index += 1) {
                this.addDeltaWithKind(cellIndices[index], deltas[index], kind);
            }
            return;
        }
        this.sharedCellIndices = cellIndices;
        this.deltas = [];
        this.deltaAssigned = [];
        this.scalarDeltaAssigned = kind === 'scalar' ? [] : undefined;
        for (let index = 0; index < cellIndices.length; index += 1) {
            this.deltas[index] = deltas[index];
            this.deltaAssigned[index] = true;
            if (kind === 'scalar') {
                this.scalarDeltaAssigned[index] = true;
            }
        }
        this.deltaCount = cellIndices.length;
        this.scalarDeltaCount = kind === 'scalar' ? cellIndices.length : 0;
    }
    appendConstantDelta(cellIndices, delta, kind) {
        this.appendConstantDeltaWithOptions(cellIndices, delta, kind, false);
    }
    appendSortedConstantDelta(cellIndices, delta, kind) {
        this.appendConstantDeltaWithOptions(cellIndices, delta, kind, true);
    }
    appendConstantDeltaWithOptions(cellIndices, delta, kind, sortedAscending) {
        if (cellIndices.length === 0) {
            return;
        }
        this.validatedScalarDeltaSize = -1;
        this.cleanScalarDeltaSize = -1;
        this.trustedDirectScalarDeltaSize = -1;
        this.cycleIndependentScalarDeltaSize = -1;
        this.updateSortedCellIndexBoundsForAppend(cellIndices, sortedAscending);
        if (this.size !== 0) {
            this.clearSortedCellIndexBounds();
            if (cellIndices.length > 16 || this.size > 16) {
                this.appendPreparedConstantDelta(cellIndices, delta, kind);
                return;
            }
            for (let index = 0; index < cellIndices.length; index += 1) {
                this.addDeltaWithKind(cellIndices[index], delta, kind);
            }
            return;
        }
        this.sharedCellIndices = cellIndices;
        this.constantDelta = delta;
        this.deltaCount = cellIndices.length;
        this.scalarDeltaCount = kind === 'scalar' ? cellIndices.length : 0;
    }
    hasDelta(cellIndex) {
        const index = this.findIndex(cellIndex);
        if (index !== -1 && this.constantDelta !== undefined) {
            return true;
        }
        return index !== -1 && this.deltaAssigned?.[index] === true;
    }
    getDelta(cellIndex) {
        const index = this.findIndex(cellIndex);
        if (index !== -1 && this.constantDelta !== undefined) {
            return this.constantDelta;
        }
        if (index === -1 || this.deltaAssigned?.[index] !== true) {
            return undefined;
        }
        return this.deltas?.[index];
    }
    getDeltaAt(index) {
        if (this.constantDelta !== undefined && index >= 0 && index < this.size) {
            return this.constantDelta;
        }
        if (this.deltaAssigned?.[index] !== true) {
            return undefined;
        }
        return this.deltas?.[index];
    }
    addCurrentResult(cellIndex, result) {
        this.validatedScalarDeltaSize = -1;
        this.cleanScalarDeltaSize = -1;
        this.trustedDirectScalarDeltaSize = -1;
        this.cycleIndependentScalarDeltaSize = -1;
        this.materializeConstantDeltas();
        const index = this.ensureIndex(cellIndex);
        this.currentResults ??= [];
        this.currentResultAssigned ??= [];
        this.currentResultAssigned[index] = true;
        this.currentResults[index] = result;
    }
    getCurrentResult(cellIndex) {
        const index = this.findIndex(cellIndex);
        if (index === -1 || this.currentResultAssigned?.[index] !== true) {
            return undefined;
        }
        return this.currentResults?.[index];
    }
    getCurrentResultAt(index) {
        if (this.currentResultAssigned?.[index] !== true) {
            return undefined;
        }
        return this.currentResults?.[index];
    }
    hasCompleteDeltas() {
        return this.size > 0 && this.deltaCount === this.size;
    }
    getConstantScalarDelta() {
        return this.constantDelta !== undefined &&
            this.scalarDeltaCount === this.size &&
            this.deltaCount === this.size &&
            this.currentResultAssigned === undefined
            ? this.constantDelta
            : undefined;
    }
    getConstantDelta() {
        return this.constantDelta !== undefined && this.deltaCount === this.size && this.currentResultAssigned === undefined
            ? this.constantDelta
            : undefined;
    }
    hasCompleteScalarDeltas() {
        return this.size > 0 && this.deltaCount === this.size && this.scalarDeltaCount === this.size && this.currentResultAssigned === undefined;
    }
    markScalarDeltaCellsValidated() {
        this.validatedScalarDeltaSize = this.size;
    }
    markScalarDeltaCellsCleanNumber() {
        this.cleanScalarDeltaSize = this.size;
    }
    markScalarDeltaCellsTrustedDirectScalarFormulas() {
        this.trustedDirectScalarDeltaSize = this.size;
    }
    markScalarDeltaCellsCycleIndependent() {
        this.cycleIndependentScalarDeltaSize = this.size;
    }
    hasValidatedScalarDeltaCells() {
        return this.validatedScalarDeltaSize === this.size && this.hasCompleteScalarDeltas();
    }
    hasCleanScalarDeltaCells() {
        return this.cleanScalarDeltaSize === this.size && this.validatedScalarDeltaSize === this.size && this.hasCompleteScalarDeltas();
    }
    hasTrustedDirectScalarDeltaCells() {
        return this.trustedDirectScalarDeltaSize === this.size && this.hasCompleteScalarDeltas();
    }
    hasCycleIndependentScalarDeltaCells() {
        return this.cycleIndependentScalarDeltaSize === this.size && this.hasCompleteScalarDeltas();
    }
    getScalarDeltaAt(index) {
        if (this.constantDelta !== undefined && this.scalarDeltaCount === this.size && index >= 0 && index < this.size) {
            return this.constantDelta;
        }
        if (this.scalarDeltaAssigned?.[index] !== true) {
            return undefined;
        }
        return this.deltas?.[index];
    }
    getCellIndexAt(index) {
        return (this.sharedCellIndices ?? this.cellIndices)[index];
    }
    getCellIndicesForRead() {
        return this.sharedCellIndices ?? this.cellIndices;
    }
    markDirectRangeInputCovered(cellIndex) {
        if (this.directRangeCoveredInputCellSet) {
            this.directRangeCoveredInputCellSet.add(cellIndex);
            return;
        }
        const covered = (this.directRangeCoveredInputCellIndices ??= []);
        for (let index = 0; index < covered.length; index += 1) {
            if (covered[index] === cellIndex) {
                return;
            }
        }
        covered.push(cellIndex);
        if (covered.length > 16) {
            this.directRangeCoveredInputCellSet = new Set(covered);
        }
    }
    hasCoveredDirectRangeInput(cellIndex) {
        if (this.directRangeCoveredInputCellSet) {
            return this.directRangeCoveredInputCellSet.has(cellIndex);
        }
        const covered = this.directRangeCoveredInputCellIndices;
        if (!covered) {
            return false;
        }
        for (let index = 0; index < covered.length; index += 1) {
            if (covered[index] === cellIndex) {
                return true;
            }
        }
        return false;
    }
    markDirectFormulaInputCovered(cellIndex) {
        if (this.directFormulaCoveredInputCellSet) {
            this.directFormulaCoveredInputCellSet.add(cellIndex);
            return;
        }
        const covered = (this.directFormulaCoveredInputCellIndices ??= []);
        for (let index = 0; index < covered.length; index += 1) {
            if (covered[index] === cellIndex) {
                return;
            }
        }
        covered.push(cellIndex);
        if (covered.length > 16) {
            this.directFormulaCoveredInputCellSet = new Set(covered);
        }
    }
    hasCoveredDirectFormulaInput(cellIndex) {
        if (this.directFormulaCoveredInputCellSet) {
            return this.directFormulaCoveredInputCellSet.has(cellIndex);
        }
        const covered = this.directFormulaCoveredInputCellIndices;
        if (!covered) {
            return false;
        }
        for (let index = 0; index < covered.length; index += 1) {
            if (covered[index] === cellIndex) {
                return true;
            }
        }
        return false;
    }
    forEach(fn) {
        for (let index = 0; index < this.size; index += 1) {
            fn(this.getCellIndexAt(index));
        }
    }
    forEachIndexed(fn) {
        for (let index = 0; index < this.size; index += 1) {
            fn(this.getCellIndexAt(index), index);
        }
    }
    findIndex(cellIndex) {
        if (!this.indexByCell && this.size > 16) {
            this.materializeIndexByCell();
        }
        const mappedIndex = this.indexByCell?.get(cellIndex);
        if (mappedIndex !== undefined) {
            return mappedIndex;
        }
        for (let index = 0; index < this.size; index += 1) {
            if (this.getCellIndexAt(index) === cellIndex) {
                return index;
            }
        }
        return -1;
    }
    ensureIndex(cellIndex) {
        if (!this.indexByCell && this.size > 16) {
            this.materializeIndexByCell();
        }
        if (this.indexByCell) {
            const mappedIndex = this.indexByCell.get(cellIndex);
            if (mappedIndex !== undefined) {
                return mappedIndex;
            }
            this.materializeSharedCellIndices();
            const index = this.cellIndices.length;
            this.indexByCell.set(cellIndex, index);
            this.cellIndices.push(cellIndex);
            return index;
        }
        for (let index = 0; index < this.size; index += 1) {
            if (this.getCellIndexAt(index) === cellIndex) {
                return index;
            }
        }
        this.materializeSharedCellIndices();
        const index = this.cellIndices.length;
        this.cellIndices.push(cellIndex);
        if (this.size > 16) {
            this.materializeIndexByCell();
        }
        return index;
    }
    materializeIndexByCell() {
        this.indexByCell = new Map();
        for (let index = 0; index < this.size; index += 1) {
            this.indexByCell.set(this.getCellIndexAt(index), index);
        }
    }
    appendPreparedDeltas(cellIndices, deltas, kind) {
        this.prepareForBulkDeltaAppend();
        for (let index = 0; index < cellIndices.length; index += 1) {
            this.addPreparedDelta(cellIndices[index], deltas[index], kind);
        }
    }
    appendPreparedConstantDelta(cellIndices, delta, kind) {
        if (this.tryAppendMatchingConstantDelta(cellIndices, delta, kind)) {
            return;
        }
        this.prepareForBulkDeltaAppend();
        for (let index = 0; index < cellIndices.length; index += 1) {
            this.addPreparedDelta(cellIndices[index], delta, kind);
        }
    }
    tryAppendMatchingConstantDelta(cellIndices, delta, kind) {
        if (this.constantDelta === undefined || !Object.is(this.constantDelta, delta)) {
            return false;
        }
        if (!this.indexByCell && this.size > 16) {
            this.materializeIndexByCell();
        }
        const seen = new Set();
        for (let index = 0; index < cellIndices.length; index += 1) {
            const cellIndex = cellIndices[index];
            if (seen.has(cellIndex) || this.indexByCell?.has(cellIndex) === true) {
                return false;
            }
            if (!this.indexByCell) {
                for (let existingIndex = 0; existingIndex < this.size; existingIndex += 1) {
                    if (this.getCellIndexAt(existingIndex) === cellIndex) {
                        return false;
                    }
                }
            }
            seen.add(cellIndex);
        }
        this.materializeSharedCellIndices();
        if (this.indexByCell) {
            for (let index = 0; index < cellIndices.length; index += 1) {
                const cellIndex = cellIndices[index];
                this.indexByCell.set(cellIndex, this.cellIndices.length);
                this.cellIndices.push(cellIndex);
            }
        }
        else {
            for (let index = 0; index < cellIndices.length; index += 1) {
                this.cellIndices.push(cellIndices[index]);
            }
        }
        this.deltaCount += cellIndices.length;
        if (kind === 'scalar') {
            this.scalarDeltaCount += cellIndices.length;
        }
        return true;
    }
    prepareForBulkDeltaAppend() {
        this.materializeConstantDeltas();
        this.materializeSharedCellIndices();
        this.materializeIndexByCell();
        this.deltas ??= [];
        this.deltaAssigned ??= [];
        this.scalarDeltaAssigned ??= [];
    }
    addPreparedDelta(cellIndex, delta, kind) {
        const mappedIndex = this.indexByCell?.get(cellIndex);
        if (mappedIndex === undefined) {
            const index = this.cellIndices.length;
            this.indexByCell.set(cellIndex, index);
            this.cellIndices.push(cellIndex);
            this.deltas[index] = delta;
            this.deltaAssigned[index] = true;
            this.deltaCount += 1;
            if (kind === 'scalar') {
                this.scalarDeltaAssigned[index] = true;
                this.scalarDeltaCount += 1;
            }
            return;
        }
        if (!this.deltaAssigned[mappedIndex]) {
            this.deltaAssigned[mappedIndex] = true;
            this.deltaCount += 1;
            this.deltas[mappedIndex] = delta;
            if (kind === 'scalar') {
                this.scalarDeltaAssigned[mappedIndex] = true;
                this.scalarDeltaCount += 1;
            }
            return;
        }
        this.deltas[mappedIndex] = (this.deltas[mappedIndex] ?? 0) + delta;
        if (kind !== 'scalar' && this.scalarDeltaAssigned[mappedIndex]) {
            this.scalarDeltaAssigned[mappedIndex] = false;
            this.scalarDeltaCount -= 1;
        }
    }
    materializeSharedCellIndices() {
        const sharedCellIndices = this.sharedCellIndices;
        if (!sharedCellIndices) {
            return;
        }
        this.clearSortedCellIndexBounds();
        this.cellIndices.length = sharedCellIndices.length;
        for (let index = 0; index < sharedCellIndices.length; index += 1) {
            this.cellIndices[index] = sharedCellIndices[index];
        }
        this.sharedCellIndices = undefined;
    }
    materializeConstantDeltas() {
        if (this.constantDelta === undefined) {
            return;
        }
        const delta = this.constantDelta;
        const scalarDeltaCount = this.scalarDeltaCount;
        const size = this.size;
        this.constantDelta = undefined;
        this.deltas = [];
        this.deltaAssigned = [];
        this.scalarDeltaAssigned = scalarDeltaCount === size ? [] : undefined;
        for (let index = 0; index < size; index += 1) {
            this.deltas[index] = delta;
            this.deltaAssigned[index] = true;
            if (this.scalarDeltaAssigned) {
                this.scalarDeltaAssigned[index] = true;
            }
        }
        this.deltaCount = size;
        this.scalarDeltaCount = this.scalarDeltaAssigned ? size : 0;
    }
    updateSortedCellIndexBoundsForAppend(cellIndices, sortedAscending) {
        if (!sortedAscending || this.size !== 0 || cellIndices.length === 0) {
            this.clearSortedCellIndexBounds();
            return;
        }
        this.sortedCellIndexMin = cellIndices[0];
        this.sortedCellIndexMax = cellIndices[cellIndices.length - 1];
    }
    clearSortedCellIndexBounds() {
        this.sortedCellIndexMin = undefined;
        this.sortedCellIndexMax = undefined;
    }
}
//# sourceMappingURL=direct-formula-index-collection.js.map