88
99/**
1010 * When a Bavet session is created, some nodes can become inactive.
11- * An inactive node cannot be triggered during a session as it cannot produce output .
12- * Processing inserts, updates and retracts in inactive nodes is possibly expensive .
11+ * An inactive node cannot impact the score, as it cannot produce tuples .
12+ * Yet processing inserts, updates and retracts in inactive nodes still consumes CPU cycles .
1313 * This interface establishes a protocol through which nodes can signal at runtime
1414 * that they are inactive, so that the session can ignore them.
1515 * <p>
1616 * The pattern of interaction is as follows:
1717 * <ul>
1818 * <li>The session will first call {@link #afterAllFactsInserted(boolean)} on every {@link AbstractRootNode}.
19- * The nodes will propagate this call downstream.
20- * Each downstream node must propagate the call further downstream,
21- * until a {@link Scorer} is reached. (In case of Constraint Streams.)</li>
22- * <li>Then the session will call {@link #isActive()} on every single node,
23- * and entirely remove deactivated nodes from propagation.
24- * Each node makes its activity decision independently,
25- * but may ask its downstream nodes.</li>
19+ * Each lifecycle must propagate the call further downstream, until a {@link Scorer} is reached.
20+ * (In case of Constraint Streams.)</li>
21+ * <li>Then the session will call {@link #isActive()} on every single lifecycle,
22+ * and entirely remove deactivated lifecycles from propagation.
23+ * Each lifecycle makes its activity decision independently,
24+ * but may ask its downstream lifecycles.</li>
2625 * <li>Once these two steps have been executed,
2726 * no method of this interface will ever be called again
2827 * for the duration of the session.</li>
2928 * </ul>
29+ *
30+ * @see TupleLifecycle
31+ * @see LeftTupleLifecycle
32+ * @see RightTupleLifecycle
3033 */
3134public interface ActivitySupport {
3235
@@ -39,26 +42,24 @@ public interface ActivitySupport {
3942 * <p>
4043 * It is the responsibility of the lifecycle to trigger initialization
4144 * of all of its downstream lifecycles, should there be any.
42- * It must first decide for itself if it can produce tuples
43- * based on what it learned from upstream,
45+ * It must first decide for itself if it can produce tuples based on what it learned from upstream,
4446 * and then propagate that information downstream so that they can make their own activation decisions.
4547 * <p>
4648 * When deciding whether a lifecycle can produce tuples, consider the following:
4749 * <ul>
4850 * <li>
4951 * Typically, when upstream cannot produce tuples, neither can downstream.
50- * Exceptions exist; ifNotExists() produces tuples exactly when downstream doesn't.
52+ * (Unless downstream has the capability to fabricate tuples out of nowhere.)
5153 * </li>
5254 * <li>
53- * Do not make decisions based on whether downstream produced any tuples by this point.
55+ * Do not make decisions based on whether upstream actually produced any tuples by this point.
5456 * If upstream produced no tuples so far, it doesn't mean it will never produce any.
55- * Filters on variables which previously did not match
56- * can easily create tuples during tuple updates.
57+ * Filters on variables which previously did not match can easily create tuples during tuple updates.
5758 * </li>
5859 * </ul>
5960 *
60- * @param upstreamCanProduceTuples True if the upstream node (s) will produce any tuples.
61- * If false, this lifecycle will never receive any tuples and can deactivate itself.
61+ * @param upstreamCanProduceTuples True if the upstream lifecycle (s) will produce any tuples.
62+ * If false, this lifecycle will never receive any tuples and can most likely deactivate itself.
6263 */
6364 void afterAllFactsInserted (boolean upstreamCanProduceTuples );
6465
@@ -71,8 +72,9 @@ public interface ActivitySupport {
7172 * (Such as forEach(MyClass), when no MyClass instances were inserted.)</li>
7273 * <li>Its downstream tuples are inactive.
7374 * (A forEach() itself may be able to produce a tuple,
74- * but a join downstream cannot, because its other side cannot produce tuples.
75- * In this case, the left side must be deactivated as well.)
75+ * but a join() downstream cannot, because its other side cannot produce tuples.
76+ * In this case, the left side must be deactivated as well,
77+ * unless it also outputs to another active downstream lifecycle.)
7678 * </li>
7779 * </ul>
7880 *
@@ -86,17 +88,21 @@ public interface ActivitySupport {
8688 * </ul>
8789 *
8890 * This is a one-time decision;
89- * for each lifecycle, this method will only be called once for the duration of {@link BavetConstraintSession}.
91+ * for each lifecycle, this method will only be called at the start of {@link BavetConstraintSession},
92+ * and never again.
93+ * It may be called multiple times by different upstream lifecycles,
94+ * and must always return the same value.
9095 *
9196 * <p>
9297 * Typically this decision will be {@code upstreamCanProduceTuples && downstreamIsActive},
93- * but some nodes will have to use different logic.
98+ * but some specialized lifecycles may have to use different logic.
9499 *
95100 * @return true if this lifecycle can produce tuples
96101 */
97102 default boolean isActive () {
98- throw new IllegalStateException ("Impossible state: node (%s) not yet initialized (afterAllFactsInserted not called)."
99- .formatted (this ));
103+ throw new IllegalStateException (
104+ "Impossible state: lifecycle (%s) not yet initialized (afterAllFactsInserted not called)."
105+ .formatted (this ));
100106 }
101107
102108}
0 commit comments