All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.optaplanner.constraint.streams.bavet.bi.BavetAbstractBiConstraintStream Maven / Gradle / Ivy

Go to download

OptaPlanner solves planning problems. This lightweight, embeddable planning engine implements powerful and scalable algorithms to optimize business resource scheduling and planning. This module contains implementation of Constraint streams (Bavet).

There is a newer version: 10.0.0
Show newest version
package org.optaplanner.constraint.streams.bavet.bi;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.ToIntBiFunction;
import java.util.function.ToLongBiFunction;

import org.optaplanner.constraint.streams.bavet.BavetConstraintFactory;
import org.optaplanner.constraint.streams.bavet.common.BavetAbstractConstraintStream;
import org.optaplanner.constraint.streams.bavet.quad.BavetGroupQuadConstraintStream;
import org.optaplanner.constraint.streams.bavet.quad.QuadTuple;
import org.optaplanner.constraint.streams.bavet.tri.BavetGroupTriConstraintStream;
import org.optaplanner.constraint.streams.bavet.tri.BavetJoinTriConstraintStream;
import org.optaplanner.constraint.streams.bavet.tri.TriTuple;
import org.optaplanner.constraint.streams.bavet.uni.BavetAbstractUniConstraintStream;
import org.optaplanner.constraint.streams.bavet.uni.BavetGroupUniConstraintStream;
import org.optaplanner.constraint.streams.bavet.uni.BavetIfExistsBridgeUniConstraintStream;
import org.optaplanner.constraint.streams.bavet.uni.BavetJoinBridgeUniConstraintStream;
import org.optaplanner.constraint.streams.bavet.uni.UniTuple;
import org.optaplanner.constraint.streams.common.RetrievalSemantics;
import org.optaplanner.constraint.streams.common.ScoreImpactType;
import org.optaplanner.constraint.streams.common.bi.InnerBiConstraintStream;
import org.optaplanner.constraint.streams.common.tri.TriJoinerComber;
import org.optaplanner.core.api.score.Score;
import org.optaplanner.core.api.score.stream.Constraint;
import org.optaplanner.core.api.score.stream.bi.BiConstraintCollector;
import org.optaplanner.core.api.score.stream.bi.BiConstraintStream;
import org.optaplanner.core.api.score.stream.quad.QuadConstraintStream;
import org.optaplanner.core.api.score.stream.tri.TriConstraintStream;
import org.optaplanner.core.api.score.stream.tri.TriJoiner;
import org.optaplanner.core.api.score.stream.uni.UniConstraintStream;

public abstract class BavetAbstractBiConstraintStream extends BavetAbstractConstraintStream
        implements InnerBiConstraintStream {

    protected final List> childStreamList = new ArrayList<>(2);

    public BavetAbstractBiConstraintStream(BavetConstraintFactory constraintFactory,
            RetrievalSemantics retrievalSemantics) {
        super(constraintFactory, retrievalSemantics);
    }

    public List> getChildStreamList() {
        return childStreamList;
    }

    // ************************************************************************
    // Stream builder methods
    // ************************************************************************

    public > Stream_ shareAndAddChild(
            Stream_ stream) {
        return constraintFactory.share(stream, childStreamList::add);
    }

    // ************************************************************************
    // Filter
    // ************************************************************************

    @Override
    public BavetAbstractBiConstraintStream filter(BiPredicate predicate) {
        return shareAndAddChild(
                new BavetFilterBiConstraintStream<>(constraintFactory, this, predicate));
    }

    // ************************************************************************
    // Join
    // ************************************************************************

    @Override
    @SafeVarargs
    public final  TriConstraintStream join(UniConstraintStream otherStream,
            TriJoiner... joiners) {
        BavetAbstractUniConstraintStream other = assertBavetUniConstraintStream(otherStream);
        TriJoinerComber joinerComber = TriJoinerComber.comb(joiners);

        BavetJoinBridgeBiConstraintStream leftBridge =
                new BavetJoinBridgeBiConstraintStream<>(constraintFactory, this, true);
        BavetJoinBridgeUniConstraintStream rightBridge =
                new BavetJoinBridgeUniConstraintStream<>(constraintFactory, other, false);
        BavetJoinTriConstraintStream joinStream =
                new BavetJoinTriConstraintStream<>(constraintFactory, leftBridge, rightBridge,
                        joinerComber.getMergedJoiner());
        leftBridge.setJoinStream(joinStream);
        rightBridge.setJoinStream(joinStream);

        joinStream = constraintFactory.share(joinStream, joinStream_ -> {
            // Connect the bridges upstream, as it is an actual new join.
            getChildStreamList().add(leftBridge);
            other.getChildStreamList().add(rightBridge);
        });
        if (joinerComber.getMergedFiltering() == null) {
            return joinStream;
        } else {
            return joinStream.filter(joinerComber.getMergedFiltering());
        }
    }

    // ************************************************************************
    // If (not) exists
    // ************************************************************************

    @SafeVarargs
    @Override
    public final  BiConstraintStream ifExists(Class otherClass, TriJoiner... joiners) {
        if (getRetrievalSemantics() == RetrievalSemantics.STANDARD) {
            return ifExists(constraintFactory.forEach(otherClass), joiners);
        } else {
            // Calls fromUnfiltered() for backward compatibility only
            return ifExists(constraintFactory.fromUnfiltered(otherClass), joiners);
        }
    }

    @SafeVarargs
    @Override
    public final  BiConstraintStream ifExistsIncludingNullVars(Class otherClass, TriJoiner... joiners) {
        if (getRetrievalSemantics() == RetrievalSemantics.STANDARD) {
            return ifExists(constraintFactory.forEachIncludingNullVars(otherClass), joiners);
        } else {
            return ifExists(constraintFactory.fromUnfiltered(otherClass), joiners);
        }
    }

    @SafeVarargs
    public final  BiConstraintStream ifExists(UniConstraintStream otherStream, TriJoiner... joiners) {
        return ifExistsOrNot(true, otherStream, joiners);
    }

    @SafeVarargs
    @Override
    public final  BiConstraintStream ifNotExists(Class otherClass, TriJoiner... joiners) {
        if (getRetrievalSemantics() == RetrievalSemantics.STANDARD) {
            return ifNotExists(constraintFactory.forEach(otherClass), joiners);
        } else {
            // Calls fromUnfiltered() for backward compatibility only
            return ifNotExists(constraintFactory.fromUnfiltered(otherClass), joiners);
        }
    }

    @SafeVarargs
    @Override
    public final  BiConstraintStream ifNotExistsIncludingNullVars(Class otherClass, TriJoiner... joiners) {
        if (getRetrievalSemantics() == RetrievalSemantics.STANDARD) {
            return ifNotExists(constraintFactory.forEachIncludingNullVars(otherClass), joiners);
        } else {
            return ifNotExists(constraintFactory.fromUnfiltered(otherClass), joiners);
        }
    }

    @SafeVarargs
    public final  BiConstraintStream ifNotExists(UniConstraintStream otherStream, TriJoiner... joiners) {
        return ifExistsOrNot(false, otherStream, joiners);
    }

    private  BiConstraintStream ifExistsOrNot(boolean shouldExist, UniConstraintStream otherStream,
            TriJoiner[] joiners) {
        BavetAbstractUniConstraintStream other = assertBavetUniConstraintStream(otherStream);
        TriJoinerComber joinerComber = TriJoinerComber.comb(joiners);
        BavetIfExistsBridgeUniConstraintStream parentBridgeC = other.shareAndAddChild(
                new BavetIfExistsBridgeUniConstraintStream<>(constraintFactory, other));
        return constraintFactory.share(
                new BavetIfExistsBiConstraintStream<>(constraintFactory, this, parentBridgeC,
                        shouldExist, joinerComber.getMergedJoiner(), joinerComber.getMergedFiltering()),
                childStreamList::add);
    }

    // ************************************************************************
    // Group by
    // ************************************************************************

    @Override
    public  UniConstraintStream groupBy(
            BiConstraintCollector collector) {
        BiGroupNodeConstructor> nodeConstructor =
                (inputStoreIndex, tupleLifecycle, outputStoreSize) -> new Group0Mapping1CollectorBiNode<>(inputStoreIndex,
                        collector, tupleLifecycle, outputStoreSize);
        return buildUniGroupBy(nodeConstructor);
    }

    private  UniConstraintStream buildUniGroupBy(BiGroupNodeConstructor> nodeConstructor) {
        BavetUniGroupBridgeBiConstraintStream bridge = shareAndAddChild(
                new BavetUniGroupBridgeBiConstraintStream<>(constraintFactory, this, nodeConstructor));
        return constraintFactory.share(
                new BavetGroupUniConstraintStream<>(constraintFactory, bridge),
                bridge::setGroupStream);
    }

    @Override
    public  BiConstraintStream groupBy(
            BiConstraintCollector collectorA,
            BiConstraintCollector collectorB) {
        BiGroupNodeConstructor> nodeConstructor =
                (inputStoreIndex, tupleLifecycle, outputStoreSize) -> new Group0Mapping2CollectorBiNode<>(inputStoreIndex,
                        collectorA, collectorB, tupleLifecycle, outputStoreSize);
        return buildBiGroupBy(nodeConstructor);
    }

    private  BiConstraintStream
            buildBiGroupBy(BiGroupNodeConstructor> nodeConstructor) {
        BavetBiGroupBridgeBiConstraintStream bridge = shareAndAddChild(
                new BavetBiGroupBridgeBiConstraintStream<>(constraintFactory, this, nodeConstructor));
        return constraintFactory.share(
                new BavetGroupBiConstraintStream<>(constraintFactory, bridge),
                bridge::setGroupStream);
    }

    @Override
    public 
            TriConstraintStream
            groupBy(BiConstraintCollector collectorA,
                    BiConstraintCollector collectorB,
                    BiConstraintCollector collectorC) {
        BiGroupNodeConstructor> nodeConstructor =
                (inputStoreIndex, tupleLifecycle, outputStoreSize) -> new Group0Mapping3CollectorBiNode<>(inputStoreIndex,
                        collectorA, collectorB, collectorC, tupleLifecycle, outputStoreSize);
        return buildTriGroupBy(nodeConstructor);
    }

    private  TriConstraintStream
            buildTriGroupBy(BiGroupNodeConstructor> nodeConstructor) {
        BavetTriGroupBridgeBiConstraintStream bridge = shareAndAddChild(
                new BavetTriGroupBridgeBiConstraintStream<>(constraintFactory, this, nodeConstructor));
        return constraintFactory.share(
                new BavetGroupTriConstraintStream<>(constraintFactory, bridge),
                bridge::setGroupStream);
    }

    @Override
    public 
            QuadConstraintStream
            groupBy(BiConstraintCollector collectorA,
                    BiConstraintCollector collectorB,
                    BiConstraintCollector collectorC,
                    BiConstraintCollector collectorD) {
        BiGroupNodeConstructor> nodeConstructor =
                (inputStoreIndex, tupleLifecycle, outputStoreSize) -> new Group0Mapping4CollectorBiNode<>(inputStoreIndex,
                        collectorA, collectorB, collectorC, collectorD, tupleLifecycle, outputStoreSize);
        return buildQuadGroupBy(nodeConstructor);
    }

    private  QuadConstraintStream
            buildQuadGroupBy(BiGroupNodeConstructor> nodeConstructor) {
        BavetQuadGroupBridgeBiConstraintStream bridge = shareAndAddChild(
                new BavetQuadGroupBridgeBiConstraintStream<>(constraintFactory, this, nodeConstructor));
        return constraintFactory.share(
                new BavetGroupQuadConstraintStream<>(constraintFactory, bridge),
                bridge::setGroupStream);
    }

    @Override
    public  UniConstraintStream groupBy(BiFunction groupKeyMapping) {
        BiGroupNodeConstructor> nodeConstructor =
                (inputStoreIndex, tupleLifecycle, outputStoreSize) -> new Group1Mapping0CollectorBiNode<>(groupKeyMapping,
                        inputStoreIndex, tupleLifecycle, outputStoreSize);
        return buildUniGroupBy(nodeConstructor);
    }

    @Override
    public 
            TriConstraintStream groupBy(BiFunction groupKeyMapping,
                    BiConstraintCollector collectorB,
                    BiConstraintCollector collectorC) {
        BiGroupNodeConstructor> nodeConstructor =
                (inputStoreIndex, tupleLifecycle, outputStoreSize) -> new Group1Mapping2CollectorBiNode<>(groupKeyMapping,
                        inputStoreIndex, collectorB, collectorC, tupleLifecycle, outputStoreSize);
        return buildTriGroupBy(nodeConstructor);
    }

    @Override
    public 
            QuadConstraintStream
            groupBy(BiFunction groupKeyMapping,
                    BiConstraintCollector collectorB,
                    BiConstraintCollector collectorC,
                    BiConstraintCollector collectorD) {
        BiGroupNodeConstructor> nodeConstructor =
                (inputStoreIndex, tupleLifecycle, outputStoreSize) -> new Group1Mapping3CollectorBiNode<>(groupKeyMapping,
                        inputStoreIndex, collectorB, collectorC, collectorD, tupleLifecycle, outputStoreSize);
        return buildQuadGroupBy(nodeConstructor);
    }

    @Override
    public  BiConstraintStream groupBy(
            BiFunction groupKeyMapping,
            BiConstraintCollector collector) {
        BiGroupNodeConstructor> nodeConstructor =
                (inputStoreIndex, tupleLifecycle, outputStoreSize) -> new Group1Mapping1CollectorBiNode<>(groupKeyMapping,
                        inputStoreIndex, collector, tupleLifecycle, outputStoreSize);
        return buildBiGroupBy(nodeConstructor);
    }

    @Override
    public  BiConstraintStream groupBy(
            BiFunction groupKeyAMapping, BiFunction groupKeyBMapping) {
        BiGroupNodeConstructor> nodeConstructor =
                (inputStoreIndex, tupleLifecycle, outputStoreSize) -> new Group2Mapping0CollectorBiNode<>(groupKeyAMapping,
                        groupKeyBMapping, inputStoreIndex, tupleLifecycle, outputStoreSize);
        return buildBiGroupBy(nodeConstructor);
    }

    @Override
    public  TriConstraintStream groupBy(
            BiFunction groupKeyAMapping, BiFunction groupKeyBMapping,
            BiConstraintCollector collector) {
        BiGroupNodeConstructor> nodeConstructor =
                (inputStoreIndex, tupleLifecycle, outputStoreSize) -> new Group2Mapping1CollectorBiNode<>(groupKeyAMapping,
                        groupKeyBMapping, inputStoreIndex, collector, tupleLifecycle, outputStoreSize);
        return buildTriGroupBy(nodeConstructor);
    }

    @Override
    public 
            QuadConstraintStream groupBy(
                    BiFunction groupKeyAMapping, BiFunction groupKeyBMapping,
                    BiConstraintCollector collectorC,
                    BiConstraintCollector collectorD) {
        BiGroupNodeConstructor> nodeConstructor =
                (inputStoreIndex, tupleLifecycle, outputStoreSize) -> new Group2Mapping2CollectorBiNode<>(groupKeyAMapping,
                        groupKeyBMapping, inputStoreIndex, collectorC, collectorD, tupleLifecycle, outputStoreSize);
        return buildQuadGroupBy(nodeConstructor);
    }

    @Override
    public  TriConstraintStream groupBy(
            BiFunction groupKeyAMapping, BiFunction groupKeyBMapping,
            BiFunction groupKeyCMapping) {
        BiGroupNodeConstructor> nodeConstructor =
                (inputStoreIndex, tupleLifecycle, outputStoreSize) -> new Group3Mapping0CollectorBiNode<>(groupKeyAMapping,
                        groupKeyBMapping, groupKeyCMapping, inputStoreIndex, tupleLifecycle, outputStoreSize);
        return buildTriGroupBy(nodeConstructor);
    }

    @Override
    public 
            QuadConstraintStream
            groupBy(BiFunction groupKeyAMapping, BiFunction groupKeyBMapping,
                    BiFunction groupKeyCMapping,
                    BiConstraintCollector collectorD) {
        BiGroupNodeConstructor> nodeConstructor =
                (inputStoreIndex, tupleLifecycle, outputStoreSize) -> new Group3Mapping1CollectorBiNode<>(groupKeyAMapping,
                        groupKeyBMapping, groupKeyCMapping, inputStoreIndex, collectorD, tupleLifecycle, outputStoreSize);
        return buildQuadGroupBy(nodeConstructor);
    }

    @Override
    public  QuadConstraintStream
            groupBy(BiFunction groupKeyAMapping, BiFunction groupKeyBMapping,
                    BiFunction groupKeyCMapping, BiFunction groupKeyDMapping) {
        BiGroupNodeConstructor> nodeConstructor =
                (inputStoreIndex, tupleLifecycle, outputStoreSize) -> new Group4Mapping0CollectorBiNode<>(groupKeyAMapping,
                        groupKeyBMapping, groupKeyCMapping, groupKeyDMapping, inputStoreIndex, tupleLifecycle, outputStoreSize);
        return buildQuadGroupBy(nodeConstructor);
    }

    // ************************************************************************
    // Operations with duplicate tuple possibility
    // ************************************************************************

    @Override
    public  UniConstraintStream map(BiFunction mapping) {
        throw new UnsupportedOperationException();
    }

    @Override
    public  BiConstraintStream flattenLast(Function> mapping) {
        BavetFlattenLastBridgeBiConstraintStream bridge = shareAndAddChild(
                new BavetFlattenLastBridgeBiConstraintStream<>(constraintFactory, this, mapping));
        return constraintFactory.share(
                new BavetFlattenLastBiConstraintStream<>(constraintFactory, bridge),
                bridge::setFlattenLastStream);
    }

    // ************************************************************************
    // Penalize/reward
    // ************************************************************************

    @Override
    public final Constraint impactScore(String constraintPackage, String constraintName, Score constraintWeight,
            ScoreImpactType impactType) {
        BavetScoringBiConstraintStream stream = shareAndAddChild(
                new BavetScoringBiConstraintStream<>(constraintFactory, this));
        return buildConstraint(constraintPackage, constraintName, constraintWeight,
                impactType, stream);
    }

    @Override
    public final Constraint impactScore(String constraintPackage, String constraintName, Score constraintWeight,
            ToIntBiFunction matchWeigher, ScoreImpactType impactType) {
        BavetScoringBiConstraintStream stream = shareAndAddChild(
                new BavetScoringBiConstraintStream<>(constraintFactory, this, matchWeigher));
        return buildConstraint(constraintPackage, constraintName, constraintWeight,
                impactType, stream);
    }

    @Override
    public final Constraint impactScoreLong(String constraintPackage, String constraintName,
            Score constraintWeight, ToLongBiFunction matchWeigher, ScoreImpactType impactType) {
        BavetScoringBiConstraintStream stream = shareAndAddChild(
                new BavetScoringBiConstraintStream<>(constraintFactory, this, matchWeigher));
        return buildConstraint(constraintPackage, constraintName, constraintWeight,
                impactType, stream);
    }

    @Override
    public final Constraint impactScoreBigDecimal(String constraintPackage, String constraintName,
            Score constraintWeight, BiFunction matchWeigher, ScoreImpactType impactType) {
        BavetScoringBiConstraintStream stream = shareAndAddChild(
                new BavetScoringBiConstraintStream<>(constraintFactory, this, matchWeigher));
        return buildConstraint(constraintPackage, constraintName, constraintWeight,
                impactType, stream);
    }

    @Override
    public final Constraint impactScoreConfigurable(String constraintPackage, String constraintName,
            ScoreImpactType impactType) {
        BavetScoringBiConstraintStream stream = shareAndAddChild(
                new BavetScoringBiConstraintStream<>(constraintFactory, this));
        return buildConstraintConfigurable(constraintPackage, constraintName,
                impactType, stream);
    }

    @Override
    public final Constraint impactScoreConfigurable(String constraintPackage, String constraintName,
            ToIntBiFunction matchWeigher, ScoreImpactType impactType) {
        BavetScoringBiConstraintStream stream = shareAndAddChild(
                new BavetScoringBiConstraintStream<>(constraintFactory, this, matchWeigher));
        return buildConstraintConfigurable(constraintPackage, constraintName,
                impactType, stream);
    }

    @Override
    public final Constraint impactScoreConfigurableLong(String constraintPackage, String constraintName,
            ToLongBiFunction matchWeigher, ScoreImpactType impactType) {
        BavetScoringBiConstraintStream stream = shareAndAddChild(
                new BavetScoringBiConstraintStream<>(constraintFactory, this, matchWeigher));
        return buildConstraintConfigurable(constraintPackage, constraintName,
                impactType, stream);
    }

    @Override
    public final Constraint impactScoreConfigurableBigDecimal(String constraintPackage, String constraintName,
            BiFunction matchWeigher, ScoreImpactType impactType) {
        BavetScoringBiConstraintStream stream = shareAndAddChild(
                new BavetScoringBiConstraintStream<>(constraintFactory, this, matchWeigher));
        return buildConstraintConfigurable(constraintPackage, constraintName,
                impactType, stream);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy