export const MULTIPLE_DIRECT_SCALAR_OUTPUTS = -2;
export class FormulaTable {
    store;
    directScalarDeltaIndex;
    records = [];
    freeSlots = [];
    activeCount = 0;
    mutationVersion = 0;
    constructor(store, directScalarDeltaIndex) {
        this.store = store;
        this.directScalarDeltaIndex = directScalarDeltaIndex;
    }
    get size() {
        return this.activeCount;
    }
    get version() {
        return this.mutationVersion;
    }
    get(cellIndex) {
        const formulaId = this.store.formulaIds[cellIndex] ?? 0;
        return formulaId === 0 ? undefined : this.records[formulaId - 1];
    }
    has(cellIndex) {
        return this.get(cellIndex) !== undefined;
    }
    set(cellIndex, record) {
        const existingId = this.store.formulaIds[cellIndex] ?? 0;
        if (existingId !== 0) {
            this.clearDirectScalarDeltaInputCellIndex(cellIndex);
            this.records[existingId - 1] = record;
            this.trackDirectScalarDeltaInputCellIndex(cellIndex, record);
            this.mutationVersion += 1;
            return existingId;
        }
        const slot = this.freeSlots.pop() ?? this.records.length;
        this.records[slot] = record;
        this.store.formulaIds[cellIndex] = slot + 1;
        this.trackDirectScalarDeltaInputCellIndex(cellIndex, record);
        this.activeCount += 1;
        this.mutationVersion += 1;
        return slot + 1;
    }
    refreshTrackedMetadata(cellIndex) {
        const record = this.get(cellIndex);
        if (record === undefined) {
            this.clearDirectScalarDeltaInputCellIndex(cellIndex);
            return;
        }
        this.trackDirectScalarDeltaInputCellIndex(cellIndex, record);
    }
    delete(cellIndex) {
        const formulaId = this.store.formulaIds[cellIndex] ?? 0;
        if (formulaId === 0) {
            return undefined;
        }
        const slot = formulaId - 1;
        const existing = this.records[slot];
        if (existing !== undefined) {
            this.records[slot] = undefined;
            this.freeSlots.push(slot);
            this.activeCount -= 1;
            this.mutationVersion += 1;
        }
        this.store.formulaIds[cellIndex] = 0;
        this.clearDirectScalarDeltaInputCellIndex(cellIndex);
        return existing;
    }
    clear() {
        for (let index = 0; index < this.records.length; index += 1) {
            const record = this.records[index];
            if (record !== undefined) {
                this.store.formulaIds[record.cellIndex] = 0;
            }
        }
        this.records.length = 0;
        this.freeSlots.length = 0;
        if (this.directScalarDeltaIndex) {
            this.directScalarDeltaIndex.deltaInputCellIndices.length = 0;
            if (this.directScalarDeltaIndex.singleOutputCellIndicesByInput) {
                this.directScalarDeltaIndex.singleOutputCellIndicesByInput.length = 0;
            }
        }
        this.activeCount = 0;
        this.mutationVersion += 1;
    }
    forEach(callback) {
        for (let index = 0; index < this.records.length; index += 1) {
            const record = this.records[index];
            if (record !== undefined) {
                callback(record, record.cellIndex);
            }
        }
    }
    *keys() {
        for (let index = 0; index < this.records.length; index += 1) {
            const record = this.records[index];
            if (record !== undefined) {
                yield record.cellIndex;
            }
        }
    }
    *values() {
        for (let index = 0; index < this.records.length; index += 1) {
            const record = this.records[index];
            if (record !== undefined) {
                yield record;
            }
        }
    }
    *entries() {
        for (let index = 0; index < this.records.length; index += 1) {
            const record = this.records[index];
            if (record !== undefined) {
                yield [record.cellIndex, record];
            }
        }
    }
    trackDirectScalarDeltaInputCellIndex(cellIndex, record) {
        if (!this.directScalarDeltaIndex) {
            return;
        }
        const inputCellIndex = this.directScalarDeltaIndex.readDeltaInputCellIndex(record);
        this.directScalarDeltaIndex.deltaInputCellIndices[cellIndex] = inputCellIndex;
        const outputCellIndicesByInput = this.directScalarDeltaIndex.singleOutputCellIndicesByInput;
        if (outputCellIndicesByInput === undefined || inputCellIndex === undefined) {
            return;
        }
        const currentOutputCellIndex = outputCellIndicesByInput[inputCellIndex];
        if (currentOutputCellIndex === undefined || currentOutputCellIndex === cellIndex) {
            outputCellIndicesByInput[inputCellIndex] = cellIndex;
            return;
        }
        outputCellIndicesByInput[inputCellIndex] = MULTIPLE_DIRECT_SCALAR_OUTPUTS;
    }
    clearDirectScalarDeltaInputCellIndex(cellIndex) {
        if (this.directScalarDeltaIndex) {
            const inputCellIndex = this.directScalarDeltaIndex.deltaInputCellIndices[cellIndex];
            const outputCellIndicesByInput = this.directScalarDeltaIndex.singleOutputCellIndicesByInput;
            if (outputCellIndicesByInput !== undefined &&
                inputCellIndex !== undefined &&
                outputCellIndicesByInput[inputCellIndex] === cellIndex) {
                outputCellIndicesByInput[inputCellIndex] = undefined;
            }
            this.directScalarDeltaIndex.deltaInputCellIndices[cellIndex] = undefined;
        }
    }
}
//# sourceMappingURL=formula-table.js.map