package org.dbsp.sqlCompiler.compiler.visitors.outer;

import org.dbsp.sqlCompiler.circuit.operator.DBSPControlledKeyFilterOperator;
import org.dbsp.sqlCompiler.circuit.operator.DBSPOperator;
import org.dbsp.sqlCompiler.circuit.operator.DBSPSourceMultisetOperator;
import org.dbsp.sqlCompiler.compiler.DBSPCompiler;
import org.dbsp.util.Bijection;

/**
 * Discover input nodes that immediately feed the left input of a controlled_key_filter operator.
 * This pattern is generated by inputs with LATENESS annotations.
 * If the input table is materialized, the materialized stream has
 * to be the output of the controlled_key_filter operator. */
public class LateMaterializations extends CircuitVisitor {
    // Keeps track of tables that have to be materialized at a different point in the circuit.
    final Bijection<DBSPSourceMultisetOperator, DBSPControlledKeyFilterOperator> materialization = new Bijection<>();

    public LateMaterializations(DBSPCompiler compiler) {
        super(compiler);
    }

    @Override
    public void postorder(DBSPControlledKeyFilterOperator operator) {
        DBSPOperator left = operator.left().operator;
        if (!left.is(DBSPSourceMultisetOperator.class)) return;
        DBSPSourceMultisetOperator source = left.to(DBSPSourceMultisetOperator.class);
        if (source.metadata.materialized)
            this.materialization.map(source, operator);
    }

    public boolean has(DBSPSourceMultisetOperator source) {
        return this.materialization.has(source);
    }

    public boolean hasRight(DBSPControlledKeyFilterOperator dest) {
        return this.materialization.hasRight(dest);
    }

    public DBSPSourceMultisetOperator getLeft(DBSPControlledKeyFilterOperator dest) {
        return this.materialization.getLeft(dest);
    }
}
