const DENSE_MEMBERSHIP_SMALL_CAPACITY = 256;
const DENSE_MEMBERSHIP_MAX_SPARSE_FACTOR = 8;
const SMALL_LIST_MEMBERSHIP_MAX_CELLS = 32;
export function createInitialFormulaCellMembership(args) {
    const cellCount = Math.min(args.cellCount ?? args.cellIndices?.length ?? 0, args.cellIndices?.length ?? 0);
    const expectedCellCount = Math.max(args.expectedCellCount ?? cellCount, cellCount);
    const maxCellIndex = args.maxCellIndex ?? findMaxCellIndex(args.cellIndices, cellCount);
    if (expectedCellCount <= SMALL_LIST_MEMBERSHIP_MAX_CELLS) {
        return new SmallInitialFormulaCellMembership(args.cellIndices, cellCount, expectedCellCount);
    }
    if (shouldUseDenseMembership(maxCellIndex, expectedCellCount)) {
        return new DenseInitialFormulaCellMembership(args.cellIndices, cellCount, maxCellIndex + 1);
    }
    return new SetInitialFormulaCellMembership(args.cellIndices, cellCount);
}
class SmallInitialFormulaCellMembership {
    cells;
    length = 0;
    constructor(cellIndices, cellCount, expectedCellCount) {
        this.cells = new Int32Array(Math.max(expectedCellCount, 1));
        if (cellIndices === undefined || cellCount === 0) {
            return;
        }
        for (let index = 0; index < cellCount; index += 1) {
            this.add(cellIndices[index]);
        }
    }
    has(cellIndex) {
        for (let index = 0; index < this.length; index += 1) {
            if (this.cells[index] === cellIndex) {
                return true;
            }
        }
        return false;
    }
    add(cellIndex) {
        if (this.has(cellIndex)) {
            return;
        }
        for (let index = 0; index < this.length; index += 1) {
            if (this.cells[index] === -1) {
                this.cells[index] = cellIndex;
                return;
            }
        }
        if (this.length === this.cells.length) {
            const next = new Int32Array(this.cells.length * 2);
            next.set(this.cells);
            this.cells = next;
        }
        this.cells[this.length] = cellIndex;
        this.length += 1;
    }
    delete(cellIndex) {
        for (let index = 0; index < this.length; index += 1) {
            if (this.cells[index] === cellIndex) {
                this.cells[index] = -1;
                return;
            }
        }
    }
}
class DenseInitialFormulaCellMembership {
    cells;
    constructor(cellIndices, cellCount, capacity) {
        this.cells = new Uint8Array(capacity);
        if (cellIndices === undefined) {
            return;
        }
        for (let index = 0; index < cellCount; index += 1) {
            this.cells[cellIndices[index]] = 1;
        }
    }
    has(cellIndex) {
        return (this.cells[cellIndex] ?? 0) !== 0;
    }
    add(cellIndex) {
        if (cellIndex >= this.cells.length) {
            const next = new Uint8Array(cellIndex + 1);
            next.set(this.cells);
            this.cells = next;
        }
        this.cells[cellIndex] = 1;
    }
    delete(cellIndex) {
        this.cells[cellIndex] = 0;
    }
}
class SetInitialFormulaCellMembership {
    cells = new Set();
    constructor(cellIndices, cellCount) {
        if (cellIndices === undefined) {
            return;
        }
        for (let index = 0; index < cellCount; index += 1) {
            this.cells.add(cellIndices[index]);
        }
    }
    has(cellIndex) {
        return this.cells.has(cellIndex);
    }
    add(cellIndex) {
        this.cells.add(cellIndex);
    }
    delete(cellIndex) {
        this.cells.delete(cellIndex);
    }
}
function shouldUseDenseMembership(maxCellIndex, expectedCellCount) {
    if (maxCellIndex < 0) {
        return false;
    }
    const capacity = maxCellIndex + 1;
    return capacity <= DENSE_MEMBERSHIP_SMALL_CAPACITY || capacity <= expectedCellCount * DENSE_MEMBERSHIP_MAX_SPARSE_FACTOR;
}
function findMaxCellIndex(cellIndices, cellCount) {
    let maxCellIndex = -1;
    if (cellIndices === undefined) {
        return maxCellIndex;
    }
    for (let index = 0; index < cellCount; index += 1) {
        const cellIndex = cellIndices[index];
        if (cellIndex > maxCellIndex) {
            maxCellIndex = cellIndex;
        }
    }
    return maxCellIndex;
}
//# sourceMappingURL=formula-initialization-membership.js.map