Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package ai.timefold.solver.core.impl.neighborhood.stream.enumerating.bi;

import java.util.function.BiFunction;

import ai.timefold.solver.core.impl.bavet.bi.Group2Mapping0CollectorBiNode;
import ai.timefold.solver.core.impl.bavet.common.GroupNodeConstructor;
import ai.timefold.solver.core.impl.bavet.common.tuple.BiTuple;
import ai.timefold.solver.core.impl.bavet.common.tuple.UniTuple;
import ai.timefold.solver.core.impl.neighborhood.stream.enumerating.EnumeratingStreamFactory;
import ai.timefold.solver.core.impl.neighborhood.stream.enumerating.common.AbstractEnumeratingStream;
import ai.timefold.solver.core.impl.neighborhood.stream.enumerating.common.NeighborhoodsGroupNodeConstructor;
import ai.timefold.solver.core.impl.neighborhood.stream.enumerating.common.bridge.AftBridgeBiEnumeratingStream;
import ai.timefold.solver.core.impl.neighborhood.stream.enumerating.common.bridge.AftBridgeUniEnumeratingStream;
import ai.timefold.solver.core.impl.neighborhood.stream.enumerating.uni.AbstractUniEnumeratingStream;
import ai.timefold.solver.core.impl.util.ConstantLambdaUtils;
import ai.timefold.solver.core.preview.api.neighborhood.stream.enumerating.BiEnumeratingStream;
import ai.timefold.solver.core.preview.api.neighborhood.stream.enumerating.UniEnumeratingStream;
import ai.timefold.solver.core.preview.api.neighborhood.stream.enumerating.collector.BiNeighborhoodsCollector;
import ai.timefold.solver.core.preview.api.neighborhood.stream.function.BiNeighborhoodsMapper;
import ai.timefold.solver.core.preview.api.neighborhood.stream.function.BiNeighborhoodsPredicate;

Expand All @@ -36,15 +36,40 @@ public final BiEnumeratingStream<Solution_, A, B> filter(BiNeighborhoodsPredicat
return shareAndAddChild(new FilterBiEnumeratingStream<>(enumeratingStreamFactory, this, filter));
}

protected <GroupKeyA_, GroupKeyB_> AbstractBiEnumeratingStream<Solution_, GroupKeyA_, GroupKeyB_>
groupBy(BiFunction<A, B, GroupKeyA_> groupKeyAMapping, BiFunction<A, B, GroupKeyB_> groupKeyBMapping) {
GroupNodeConstructor<BiTuple<GroupKeyA_, GroupKeyB_>> nodeConstructor =
GroupNodeConstructor.twoKeysGroupBy(groupKeyAMapping, groupKeyBMapping, Group2Mapping0CollectorBiNode::new);
return buildBiGroupBy(nodeConstructor);
@Override
public <GroupKey_> AbstractUniEnumeratingStream<Solution_, GroupKey_> groupBy(
BiNeighborhoodsMapper<Solution_, A, B, GroupKey_> key) {
return buildUniGroupBy(NeighborhoodsGroupNodeConstructor.biOneKeyGroupBy(key));
Comment thread
triceo marked this conversation as resolved.
}

@Override
public <Result_> AbstractUniEnumeratingStream<Solution_, Result_> groupBy(
BiNeighborhoodsCollector<Solution_, A, B, ?, Result_> collector) {
return buildUniGroupBy(NeighborhoodsGroupNodeConstructor.biZeroKeysGroupBy(collector));
}

private <GroupKeyA_, GroupKeyB_> AbstractBiEnumeratingStream<Solution_, GroupKeyA_, GroupKeyB_> groupBy(
BiNeighborhoodsMapper<Solution_, A, B, GroupKeyA_> keyA,
BiNeighborhoodsMapper<Solution_, A, B, GroupKeyB_> keyB) {
return buildBiGroupBy(NeighborhoodsGroupNodeConstructor.biTwoKeysGroupBy(keyA, keyB));
}

@Override
public <GroupKey_, Result_> AbstractBiEnumeratingStream<Solution_, GroupKey_, Result_> groupBy(
BiNeighborhoodsMapper<Solution_, A, B, GroupKey_> key,
BiNeighborhoodsCollector<Solution_, A, B, ?, Result_> collector) {
return buildBiGroupBy(NeighborhoodsGroupNodeConstructor.biOneKeyAndCollectorGroupBy(key, collector));
}

private <NewA> AbstractUniEnumeratingStream<Solution_, NewA> buildUniGroupBy(
NeighborhoodsGroupNodeConstructor<Solution_, UniTuple<NewA>> nodeConstructor) {
var stream = shareAndAddChild(new BiGroupUniEnumeratingStream<>(enumeratingStreamFactory, this, nodeConstructor));
return enumeratingStreamFactory.share(new AftBridgeUniEnumeratingStream<>(enumeratingStreamFactory, stream),
stream::setAftBridge);
}

private <NewA, NewB> AbstractBiEnumeratingStream<Solution_, NewA, NewB>
buildBiGroupBy(GroupNodeConstructor<BiTuple<NewA, NewB>> nodeConstructor) {
private <NewA, NewB> AbstractBiEnumeratingStream<Solution_, NewA, NewB> buildBiGroupBy(
NeighborhoodsGroupNodeConstructor<Solution_, BiTuple<NewA, NewB>> nodeConstructor) {
var stream = shareAndAddChild(new BiGroupBiEnumeratingStream<>(enumeratingStreamFactory, this, nodeConstructor));
return enumeratingStreamFactory.share(new AftBridgeBiEnumeratingStream<>(enumeratingStreamFactory, stream),
stream::setAftBridge);
Expand All @@ -71,7 +96,7 @@ public AbstractBiEnumeratingStream<Solution_, A, B> distinct() {
if (guaranteesDistinct()) {
return this; // Already distinct, no need to create a new stream.
}
return groupBy(ConstantLambdaUtils.biPickFirst(), ConstantLambdaUtils.biPickSecond());
return groupBy(ConstantLambdaUtils.neighborhoodsBiPickFirst(), ConstantLambdaUtils.neighborhoodsBiPickSecond());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

import java.util.Objects;

import ai.timefold.solver.core.impl.bavet.common.GroupNodeConstructor;
import ai.timefold.solver.core.impl.bavet.common.tuple.BiTuple;
import ai.timefold.solver.core.impl.neighborhood.stream.enumerating.EnumeratingStreamFactory;
import ai.timefold.solver.core.impl.neighborhood.stream.enumerating.common.DataNodeBuildHelper;
import ai.timefold.solver.core.impl.neighborhood.stream.enumerating.common.NeighborhoodsGroupNodeConstructor;
import ai.timefold.solver.core.impl.neighborhood.stream.enumerating.common.bridge.AftBridgeBiEnumeratingStream;

import org.jspecify.annotations.NullMarked;
Expand All @@ -15,25 +15,30 @@
final class BiGroupBiEnumeratingStream<Solution_, A, B, NewA, NewB>
extends AbstractBiEnumeratingStream<Solution_, A, B> {

private final GroupNodeConstructor<BiTuple<NewA, NewB>> nodeConstructor;
private final NeighborhoodsGroupNodeConstructor<Solution_, BiTuple<NewA, NewB>> nodeConstructor;
private @Nullable AftBridgeBiEnumeratingStream<Solution_, NewA, NewB> aftStream;

public BiGroupBiEnumeratingStream(EnumeratingStreamFactory<Solution_> enumeratingStreamFactory,
BiGroupBiEnumeratingStream(EnumeratingStreamFactory<Solution_> enumeratingStreamFactory,
AbstractBiEnumeratingStream<Solution_, A, B> parent,
GroupNodeConstructor<BiTuple<NewA, NewB>> nodeConstructor) {
NeighborhoodsGroupNodeConstructor<Solution_, BiTuple<NewA, NewB>> nodeConstructor) {
super(enumeratingStreamFactory, parent);
this.nodeConstructor = nodeConstructor;
this.nodeConstructor = Objects.requireNonNull(nodeConstructor);
}

public void setAftBridge(AftBridgeBiEnumeratingStream<Solution_, NewA, NewB> aftStream) {
void setAftBridge(AftBridgeBiEnumeratingStream<Solution_, NewA, NewB> aftStream) {
this.aftStream = aftStream;
}

@Override
public boolean guaranteesDistinct() {
return true;
}

@Override
public void buildNode(DataNodeBuildHelper<Solution_> buildHelper) {
var aftStreamChildList = aftStream.getChildStreamList();
nodeConstructor.build(buildHelper, parent.getTupleSource(), aftStream, aftStreamChildList, this,
enumeratingStreamFactory.getEnvironmentMode());
var view = buildHelper.getSessionContext().solutionView();
nodeConstructor.build(buildHelper, parent.getTupleSource(), aftStream,
aftStream.getChildStreamList(), this, enumeratingStreamFactory.getEnvironmentMode(), view);
}

@Override
Expand All @@ -53,7 +58,6 @@ public int hashCode() {

@Override
public String toString() {
return "BiGroup()";
return "BiGroupBi()";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package ai.timefold.solver.core.impl.neighborhood.stream.enumerating.bi;

import java.util.Objects;

import ai.timefold.solver.core.impl.bavet.common.tuple.UniTuple;
import ai.timefold.solver.core.impl.neighborhood.stream.enumerating.EnumeratingStreamFactory;
import ai.timefold.solver.core.impl.neighborhood.stream.enumerating.common.DataNodeBuildHelper;
import ai.timefold.solver.core.impl.neighborhood.stream.enumerating.common.NeighborhoodsGroupNodeConstructor;
import ai.timefold.solver.core.impl.neighborhood.stream.enumerating.common.bridge.AftBridgeUniEnumeratingStream;

import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;

@NullMarked
final class BiGroupUniEnumeratingStream<Solution_, A, B, NewA>
extends AbstractBiEnumeratingStream<Solution_, A, B> {

private final NeighborhoodsGroupNodeConstructor<Solution_, UniTuple<NewA>> nodeConstructor;
private @Nullable AftBridgeUniEnumeratingStream<Solution_, NewA> aftStream;

BiGroupUniEnumeratingStream(EnumeratingStreamFactory<Solution_> enumeratingStreamFactory,
AbstractBiEnumeratingStream<Solution_, A, B> parent,
NeighborhoodsGroupNodeConstructor<Solution_, UniTuple<NewA>> nodeConstructor) {
super(enumeratingStreamFactory, parent);
this.nodeConstructor = Objects.requireNonNull(nodeConstructor);
}

void setAftBridge(AftBridgeUniEnumeratingStream<Solution_, NewA> aftStream) {
this.aftStream = aftStream;
}

@Override
public boolean guaranteesDistinct() {
return true;
}

@Override
public void buildNode(DataNodeBuildHelper<Solution_> buildHelper) {
var view = buildHelper.getSessionContext().solutionView();
nodeConstructor.build(buildHelper, parent.getTupleSource(), aftStream,
aftStream.getChildStreamList(), this, enumeratingStreamFactory.getEnvironmentMode(), view);
}

@Override
public boolean equals(Object object) {
if (this == object)
return true;
if (object == null || getClass() != object.getClass())
return false;
var that = (BiGroupUniEnumeratingStream<?, ?, ?, ?>) object;
return Objects.equals(parent, that.parent) && Objects.equals(nodeConstructor, that.nodeConstructor);
}

@Override
public int hashCode() {
return Objects.hash(parent, nodeConstructor);
}

@Override
public String toString() {
return "BiGroupUni()";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package ai.timefold.solver.core.impl.neighborhood.stream.enumerating.collector;

import java.util.Objects;
import java.util.function.Function;
import java.util.function.Supplier;

import ai.timefold.solver.core.preview.api.neighborhood.stream.enumerating.collector.BiNeighborhoodsCollector;
import ai.timefold.solver.core.preview.api.neighborhood.stream.enumerating.collector.BiNeighborhoodsCollectorAccumulator;

import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;

@NullMarked
public final class AndThenBiNeighborhoodsCollector<Solution_, A, B, ResultContainer_, Intermediate_, Result_>
implements BiNeighborhoodsCollector<Solution_, A, B, ResultContainer_, Result_> {

private final BiNeighborhoodsCollector<Solution_, A, B, ResultContainer_, Intermediate_> delegate;
private final Function<@Nullable Intermediate_, @Nullable Result_> mappingFunction;

public AndThenBiNeighborhoodsCollector(
BiNeighborhoodsCollector<Solution_, A, B, ResultContainer_, Intermediate_> delegate,
Function<Intermediate_, Result_> mappingFunction) {
this.delegate = Objects.requireNonNull(delegate);
this.mappingFunction = Objects.requireNonNull(mappingFunction);
}

@Override
public Supplier<ResultContainer_> supplier() {
return delegate.supplier();
}

@Override
public BiNeighborhoodsCollectorAccumulator<Solution_, A, B, ResultContainer_> accumulator() {
return delegate.accumulator();
}

@Override
public Function<ResultContainer_, @Nullable Result_> finisher() {
var finisher = delegate.finisher();
return container -> mappingFunction.apply(finisher.apply(container));
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
return o instanceof AndThenBiNeighborhoodsCollector<?, ?, ?, ?, ?, ?> other
&& Objects.equals(delegate, other.delegate)
&& Objects.equals(mappingFunction, other.mappingFunction);
}

@Override
public int hashCode() {
return Objects.hash(delegate, mappingFunction);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package ai.timefold.solver.core.impl.neighborhood.stream.enumerating.collector;

import java.util.Objects;
import java.util.function.Function;
import java.util.function.Supplier;

import ai.timefold.solver.core.preview.api.neighborhood.stream.enumerating.collector.UniNeighborhoodsCollector;
import ai.timefold.solver.core.preview.api.neighborhood.stream.enumerating.collector.UniNeighborhoodsCollectorAccumulator;

import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;

@NullMarked
public final class AndThenUniNeighborhoodsCollector<Solution_, A, ResultContainer_, Intermediate_, Result_>
implements UniNeighborhoodsCollector<Solution_, A, ResultContainer_, Result_> {

private final UniNeighborhoodsCollector<Solution_, A, ResultContainer_, Intermediate_> delegate;
private final Function<@Nullable Intermediate_, @Nullable Result_> mappingFunction;

public AndThenUniNeighborhoodsCollector(
UniNeighborhoodsCollector<Solution_, A, ResultContainer_, Intermediate_> delegate,
Function<Intermediate_, Result_> mappingFunction) {
this.delegate = Objects.requireNonNull(delegate);
this.mappingFunction = Objects.requireNonNull(mappingFunction);
}

@Override
public Supplier<ResultContainer_> supplier() {
return delegate.supplier();
}

@Override
public UniNeighborhoodsCollectorAccumulator<Solution_, A, ResultContainer_> accumulator() {
return delegate.accumulator();
}

@Override
public Function<ResultContainer_, @Nullable Result_> finisher() {
var finisher = delegate.finisher();
return container -> mappingFunction.apply(finisher.apply(container));
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
return o instanceof AndThenUniNeighborhoodsCollector<?, ?, ?, ?, ?> other
&& Objects.equals(delegate, other.delegate)
&& Objects.equals(mappingFunction, other.mappingFunction);
}

@Override
public int hashCode() {
return Objects.hash(delegate, mappingFunction);
}

}
Loading
Loading