-
Notifications
You must be signed in to change notification settings - Fork 159
feat: allow caching the results of an unfiltered UniStream (WIP) #1853
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
6522504
f33afc6
2f1f7d2
6e94d9e
0c356b0
cf86173
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -192,6 +192,18 @@ public interface ConstraintFactory { | |
*/ | ||
<A> @NonNull BiConstraintStream<A, A> forEachUniquePair(@NonNull Class<A> sourceClass, @NonNull BiJoiner<A, A>... joiners); | ||
|
||
// ************************************************************************ | ||
// staticData | ||
//************************************************************************ | ||
|
||
/** | ||
* Computes and caches the tuples that would be produced by the given stream. | ||
* As this is cached, it is vital the stream does not reference any variables | ||
* (genuine or otherwise). | ||
*/ | ||
<Stream_ extends ConstraintStream> @NonNull Stream_ | ||
staticData(StaticDataSupplier<@NonNull Stream_> staticDataSupplier); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TODO: naming |
||
|
||
// ************************************************************************ | ||
// from* (deprecated) | ||
// ************************************************************************ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package ai.timefold.solver.core.api.score.stream; | ||
|
||
import ai.timefold.solver.core.api.score.stream.uni.UniConstraintStream; | ||
|
||
public interface StaticDataFactory { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TODO: naming |
||
<A> UniConstraintStream<A> forEachUnfiltered(Class<A> sourceClass); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package ai.timefold.solver.core.api.score.stream; | ||
|
||
import org.jspecify.annotations.NullMarked; | ||
|
||
@NullMarked | ||
public interface StaticDataSupplier<Stream_ extends ConstraintStream> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TODO: naming |
||
Stream_ get(StaticDataFactory dataFactory); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,8 +7,8 @@ | |
import java.util.stream.Stream; | ||
|
||
import ai.timefold.solver.core.api.domain.solution.PlanningSolution; | ||
import ai.timefold.solver.core.impl.bavet.common.BavetRootNode; | ||
import ai.timefold.solver.core.impl.bavet.common.Propagator; | ||
import ai.timefold.solver.core.impl.bavet.uni.AbstractForEachUniNode; | ||
|
||
/** | ||
* Represents Bavet's network of nodes, specific to a particular session. | ||
|
@@ -19,7 +19,7 @@ | |
* @param layeredNodes nodes grouped first by their layer, then by their index within the layer; | ||
* propagation needs to happen in this order. | ||
*/ | ||
public record NodeNetwork(Map<Class<?>, List<AbstractForEachUniNode<?>>> declaredClassToNodeMap, | ||
public record NodeNetwork(Map<Class<?>, List<BavetRootNode<?>>> declaredClassToNodeMap, | ||
Propagator[][] layeredNodes) { | ||
|
||
public static final NodeNetwork EMPTY = new NodeNetwork(Map.of(), new Propagator[0][0]); | ||
|
@@ -32,14 +32,21 @@ public int layerCount() { | |
return layeredNodes.length; | ||
} | ||
|
||
public Stream<AbstractForEachUniNode<?>> getForEachNodes(Class<?> factClass) { | ||
public Stream<BavetRootNode<?>> getAllTupleSourceRootNodes() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the type changed, the method name should change as well. In this case, probably |
||
// The node needs to match the fact, or the node needs to be applicable to the entire solution. | ||
// The latter is for FromSolution nodes. | ||
return declaredClassToNodeMap.entrySet() | ||
.stream() | ||
.filter(entry -> factClass == PlanningSolution.class || entry.getKey().isAssignableFrom(factClass)) | ||
.map(Map.Entry::getValue) | ||
.flatMap(List::stream); | ||
.flatMap(entry -> entry.getValue().stream()); | ||
} | ||
|
||
public Stream<BavetRootNode<?>> getTupleSourceRootNodes(Class<?> factClass) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dtto. |
||
// The node needs to match the fact, or the node needs to be applicable to the entire solution. | ||
// The latter is for FromSolution nodes. | ||
return declaredClassToNodeMap.entrySet() | ||
.stream() | ||
.flatMap(entry -> entry.getValue().stream()) | ||
.filter(tupleSourceRoot -> factClass == PlanningSolution.class || tupleSourceRoot.allowsInstancesOf(factClass)); | ||
} | ||
|
||
public void settle() { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package ai.timefold.solver.core.impl.bavet.bi; | ||
|
||
import ai.timefold.solver.core.impl.bavet.NodeNetwork; | ||
import ai.timefold.solver.core.impl.bavet.common.AbstractStaticDataNode; | ||
import ai.timefold.solver.core.impl.bavet.common.tuple.BiTuple; | ||
import ai.timefold.solver.core.impl.bavet.common.tuple.RecordingTupleLifecycle; | ||
import ai.timefold.solver.core.impl.bavet.common.tuple.TupleLifecycle; | ||
|
||
import org.jspecify.annotations.NullMarked; | ||
|
||
@NullMarked | ||
public final class StaticDataBiNode<A, B> extends AbstractStaticDataNode<BiTuple<A, B>> { | ||
private final int outputStoreSize; | ||
|
||
public StaticDataBiNode(NodeNetwork nodeNetwork, | ||
RecordingTupleLifecycle<BiTuple<A, B>> recordingTupleNode, | ||
int outputStoreSize, | ||
TupleLifecycle<BiTuple<A, B>> nextNodesTupleLifecycle, | ||
Class<?>[] sourceClasses) { | ||
super(nodeNetwork, recordingTupleNode, nextNodesTupleLifecycle, sourceClasses); | ||
this.outputStoreSize = outputStoreSize; | ||
} | ||
|
||
@Override | ||
protected BiTuple<A, B> remapTuple(BiTuple<A, B> tuple) { | ||
return new BiTuple<>(tuple.factA, tuple.factB, outputStoreSize); | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.