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

org.optaplanner.constraint.streams.bavet.tri.BavetAbstractTriConstraintStream 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.tri;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

import org.optaplanner.constraint.streams.bavet.BavetConstraintFactory;
import org.optaplanner.constraint.streams.bavet.bi.BavetGroupBiConstraintStream;
import org.optaplanner.constraint.streams.bavet.bi.BiTuple;
import org.optaplanner.constraint.streams.bavet.common.BavetAbstractConstraintStream;
import org.optaplanner.constraint.streams.bavet.quad.BavetGroupQuadConstraintStream;
import org.optaplanner.constraint.streams.bavet.quad.BavetJoinQuadConstraintStream;
import org.optaplanner.constraint.streams.bavet.quad.QuadTuple;
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.quad.QuadJoinerComber;
import org.optaplanner.constraint.streams.common.tri.InnerTriConstraintStream;
import org.optaplanner.core.api.function.ToIntTriFunction;
import org.optaplanner.core.api.function.ToLongTriFunction;
import org.optaplanner.core.api.function.TriFunction;
import org.optaplanner.core.api.function.TriPredicate;
import org.optaplanner.core.api.score.Score;
import org.optaplanner.core.api.score.stream.Constraint;
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.quad.QuadJoiner;
import org.optaplanner.core.api.score.stream.tri.TriConstraintCollector;
import org.optaplanner.core.api.score.stream.tri.TriConstraintStream;
import org.optaplanner.core.api.score.stream.uni.UniConstraintStream;

public abstract class BavetAbstractTriConstraintStream extends BavetAbstractConstraintStream
        implements InnerTriConstraintStream {

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

    public BavetAbstractTriConstraintStream(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 BavetAbstractTriConstraintStream filter(TriPredicate predicate) {
        return shareAndAddChild(
                new BavetFilterTriConstraintStream<>(constraintFactory, this, predicate));
    }

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

    @Override
    @SafeVarargs
    public final  QuadConstraintStream join(UniConstraintStream otherStream,
            QuadJoiner... joiners) {
        BavetAbstractUniConstraintStream other = assertBavetUniConstraintStream(otherStream);
        QuadJoinerComber joinerComber = QuadJoinerComber.comb(joiners);

        BavetJoinBridgeTriConstraintStream leftBridge =
                new BavetJoinBridgeTriConstraintStream<>(constraintFactory, this, true);
        BavetJoinBridgeUniConstraintStream rightBridge =
                new BavetJoinBridgeUniConstraintStream<>(constraintFactory, other, false);
        BavetJoinQuadConstraintStream joinStream =
                new BavetJoinQuadConstraintStream<>(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  TriConstraintStream ifExists(Class otherClass, QuadJoiner... 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  TriConstraintStream ifExistsIncludingNullVars(Class otherClass,
            QuadJoiner... joiners) {
        if (getRetrievalSemantics() == RetrievalSemantics.STANDARD) {
            return ifExists(constraintFactory.forEachIncludingNullVars(otherClass), joiners);
        } else {
            return ifExists(constraintFactory.fromUnfiltered(otherClass), joiners);
        }
    }

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

    @SafeVarargs
    @Override
    public final  TriConstraintStream ifNotExists(Class otherClass, QuadJoiner... 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  TriConstraintStream ifNotExistsIncludingNullVars(Class otherClass,
            QuadJoiner... joiners) {
        if (getRetrievalSemantics() == RetrievalSemantics.STANDARD) {
            return ifNotExists(constraintFactory.forEachIncludingNullVars(otherClass), joiners);
        } else {
            return ifNotExists(constraintFactory.fromUnfiltered(otherClass), joiners);
        }
    }

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

    private  TriConstraintStream ifExistsOrNot(boolean shouldExist, UniConstraintStream otherStream,
            QuadJoiner[] joiners) {
        BavetAbstractUniConstraintStream other = assertBavetUniConstraintStream(otherStream);
        QuadJoinerComber joinerComber = QuadJoinerComber.comb(joiners);
        BavetIfExistsBridgeUniConstraintStream parentBridgeD = other.shareAndAddChild(
                new BavetIfExistsBridgeUniConstraintStream<>(constraintFactory, other));
        return constraintFactory.share(
                new BavetIfExistsTriConstraintStream<>(constraintFactory, this, parentBridgeD,
                        shouldExist, joinerComber.getMergedJoiner(), joinerComber.getMergedFiltering()),
                childStreamList::add);
    }

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

    @Override
    public  UniConstraintStream groupBy(
            TriConstraintCollector collector) {
        TriGroupNodeConstructor> nodeConstructor =
                (inputStoreIndex, tupleLifecycle, outputStoreSize) -> new Group0Mapping1CollectorTriNode<>(inputStoreIndex,
                        collector, tupleLifecycle, outputStoreSize);
        return buildUniGroupBy(nodeConstructor);
    }

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

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

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

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

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

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

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

    @Override
    public  UniConstraintStream groupBy(TriFunction groupKeyMapping) {
        TriGroupNodeConstructor> nodeConstructor =
                (inputStoreIndex, tupleLifecycle, outputStoreSize) -> new Group1Mapping0CollectorTriNode<>(groupKeyMapping,
                        inputStoreIndex, tupleLifecycle, outputStoreSize);
        return buildUniGroupBy(nodeConstructor);
    }

    @Override
    public 
            TriConstraintStream groupBy(TriFunction groupKeyMapping,
                    TriConstraintCollector collectorB,
                    TriConstraintCollector collectorC) {
        TriGroupNodeConstructor> nodeConstructor =
                (inputStoreIndex, tupleLifecycle, outputStoreSize) -> new Group1Mapping2CollectorTriNode<>(groupKeyMapping,
                        inputStoreIndex, collectorB, collectorC, tupleLifecycle, outputStoreSize);
        return buildTriGroupBy(nodeConstructor);
    }

    @Override
    public 
            QuadConstraintStream
            groupBy(TriFunction groupKeyMapping,
                    TriConstraintCollector collectorB,
                    TriConstraintCollector collectorC,
                    TriConstraintCollector collectorD) {
        TriGroupNodeConstructor> nodeConstructor =
                (inputStoreIndex, tupleLifecycle, outputStoreSize) -> new Group1Mapping3CollectorTriNode<>(groupKeyMapping,
                        inputStoreIndex, collectorB, collectorC, collectorD, tupleLifecycle, outputStoreSize);
        return buildQuadGroupBy(nodeConstructor);
    }

    @Override
    public  BiConstraintStream groupBy(
            TriFunction groupKeyMapping,
            TriConstraintCollector collector) {
        TriGroupNodeConstructor> nodeConstructor =
                (inputStoreIndex, tupleLifecycle, outputStoreSize) -> new Group1Mapping1CollectorTriNode<>(groupKeyMapping,
                        inputStoreIndex, collector, tupleLifecycle, outputStoreSize);
        return buildBiGroupBy(nodeConstructor);
    }

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

    @Override
    public  TriConstraintStream groupBy(
            TriFunction groupKeyAMapping,
            TriFunction groupKeyBMapping,
            TriConstraintCollector collector) {
        TriGroupNodeConstructor> nodeConstructor =
                (inputStoreIndex, tupleLifecycle, outputStoreSize) -> new Group2Mapping1CollectorTriNode<>(groupKeyAMapping,
                        groupKeyBMapping, inputStoreIndex, collector, tupleLifecycle, outputStoreSize);
        return buildTriGroupBy(nodeConstructor);
    }

    @Override
    public 
            QuadConstraintStream groupBy(
                    TriFunction groupKeyAMapping,
                    TriFunction groupKeyBMapping,
                    TriConstraintCollector collectorC,
                    TriConstraintCollector collectorD) {
        TriGroupNodeConstructor> nodeConstructor =
                (inputStoreIndex, tupleLifecycle, outputStoreSize) -> new Group2Mapping2CollectorTriNode<>(groupKeyAMapping,
                        groupKeyBMapping, inputStoreIndex, collectorC, collectorD, tupleLifecycle, outputStoreSize);
        return buildQuadGroupBy(nodeConstructor);
    }

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

    @Override
    public 
            QuadConstraintStream
            groupBy(TriFunction groupKeyAMapping,
                    TriFunction groupKeyBMapping,
                    TriFunction groupKeyCMapping,
                    TriConstraintCollector collectorD) {
        TriGroupNodeConstructor> nodeConstructor =
                (inputStoreIndex, tupleLifecycle, outputStoreSize) -> new Group3Mapping1CollectorTriNode<>(groupKeyAMapping,
                        groupKeyBMapping, groupKeyCMapping, inputStoreIndex, collectorD, tupleLifecycle, outputStoreSize);
        return buildQuadGroupBy(nodeConstructor);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy