"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MasterToTupleConverter = exports.TupleAllocator = exports.TupleStorage = void 0;
const tslib_1 = require("tslib");
const ImpLib = tslib_1.__importStar(require("@ot-builder/common-impl"));
const primitive_1 = require("@ot-builder/primitive");
class TupleStorage {
    constructor(index, tuple) {
        this.index = index;
        this.tuple = tuple;
    }
}
exports.TupleStorage = TupleStorage;
class TupleAllocator {
    constructor() {
        this.store = new ImpLib.PathMapImpl();
        this.size = 0;
    }
    allocate(tuple) {
        const existing = this.store.get(tuple);
        if (existing) {
            return existing;
        }
        else {
            const ts = new TupleStorage(this.size++, tuple);
            this.store.set(tuple, ts);
            return ts;
        }
    }
    *storage() {
        const a = [];
        for (const ts of this.store.values()) {
            a[ts.index] = ts.tuple;
        }
        yield* a;
    }
}
exports.TupleAllocator = TupleAllocator;
class MasterToTupleConverter {
    constructor(designSpace, forceKeepMinMax) {
        this.designSpace = designSpace;
        this.forceKeepMinMax = forceKeepMinMax;
        this.cache = new Map();
    }
    getTuplesImpl(master) {
        const start = [], peak = [], end = [];
        let isIntermediate = false;
        for (const dim of this.designSpace) {
            let md = null;
            for (const masterDim of master.regions)
                if (masterDim.dim === dim)
                    md = masterDim;
            if (md) {
                start.push(primitive_1.F2D14.from(md.min));
                peak.push(primitive_1.F2D14.from(md.peak));
                end.push(primitive_1.F2D14.from(md.max));
                isIntermediate = isIntermediate || !this.masterDimIsSimple(md);
            }
            else {
                start.push(0);
                peak.push(0);
                end.push(0);
            }
        }
        if (this.forceKeepMinMax || isIntermediate) {
            return { min: start, peak, max: end };
        }
        else {
            return { peak };
        }
    }
    masterDimIsSimple(dim) {
        if (dim.peak > 0)
            return dim.min === 0 && dim.max === dim.peak;
        else if (dim.peak < 0)
            return dim.min === dim.peak && dim.max === 0;
        else
            return true;
    }
    getTuples(master) {
        const existing = this.cache.get(master);
        if (existing)
            return existing;
        const tuples = this.getTuplesImpl(master);
        this.cache.set(master, tuples);
        return tuples;
    }
}
exports.MasterToTupleConverter = MasterToTupleConverter;
//# sourceMappingURL=tuple-allocator.js.map