From 4929779d9fbe8e0cb9bf57fa6109ae74398022f9 Mon Sep 17 00:00:00 2001 From: Mark Proctor Date: Wed, 14 Feb 2024 23:35:18 +0000 Subject: [PATCH] Split Beta Nodes #5787 --- .../org/drools/ancompiler/AssertHandler.java | 7 +- .../drools/ancompiler/CompiledNetwork.java | 8 +- .../org/drools/ancompiler/ModifyHandler.java | 11 +- .../ancompiler/ObjectTypeNodeParser.java | 5 +- .../org/drools/base/common/NetworkNode.java | 2 +- .../drools/base/reteoo/BaseTerminalNode.java | 10 - .../org/drools/base/reteoo/NodeTypeEnums.java | 27 +- .../java/org/drools/core/common/BaseNode.java | 11 +- .../drools/core/common/SuperCacheFixer.java | 62 +- .../drools/core/impl/KnowledgeBaseImpl.java | 4 + .../phreak/BuildtimeSegmentUtilities.java | 36 +- .../core/phreak/EagerPhreakBuilder.java | 37 +- .../drools/core/phreak/LazyPhreakBuilder.java | 132 ++-- .../core/phreak/PhreakAccumulateNode.java | 16 +- .../drools/core/phreak/PhreakExistsNode.java | 2 +- .../drools/core/phreak/PhreakGroupByNode.java | 2 +- .../org/drools/core/phreak/PhreakNotNode.java | 2 +- .../core/phreak/RuleNetworkEvaluator.java | 98 +-- .../core/phreak/RuntimeSegmentUtilities.java | 28 +- .../drools/core/phreak/SegmentPropagator.java | 4 +- .../org/drools/core/phreak/StackEntry.java | 28 +- .../core/phreak/TupleEvaluationUtil.java | 11 +- .../core/reteoo/AbstractTerminalNode.java | 39 +- .../drools/core/reteoo/AccumulateNode.java | 41 +- .../drools/core/reteoo/AccumulateRight.java | 42 ++ .../org/drools/core/reteoo/AlphaNode.java | 4 +- .../drools/core/reteoo/AlphaTerminalNode.java | 10 +- .../drools/core/reteoo/AsyncReceiveNode.java | 2 +- .../org/drools/core/reteoo/AsyncSendNode.java | 2 +- .../org/drools/core/reteoo/BetaMemory.java | 24 +- .../java/org/drools/core/reteoo/BetaNode.java | 357 ++--------- .../reteoo/CompositeObjectSinkAdapter.java | 20 +- ...positePartitionAwareObjectSinkAdapter.java | 8 +- .../core/reteoo/ConditionalBranchNode.java | 6 +- .../core/reteoo/EmptyObjectSinkAdapter.java | 4 +- .../drools/core/reteoo/EvalConditionNode.java | 12 +- .../org/drools/core/reteoo/ExistsNode.java | 32 +- .../org/drools/core/reteoo/ExistsRight.java | 32 + .../java/org/drools/core/reteoo/FromNode.java | 15 +- .../java/org/drools/core/reteoo/JoinNode.java | 26 +- .../core/reteoo/JoinRightAdapterNode.java | 32 + .../core/reteoo/LeftInputAdapterNode.java | 19 +- .../org/drools/core/reteoo/LeftTupleSink.java | 10 +- .../drools/core/reteoo/LeftTupleSource.java | 84 +-- .../java/org/drools/core/reteoo/NotNode.java | 85 +-- .../java/org/drools/core/reteoo/NotRight.java | 96 +++ .../core/reteoo/ObjectSinkPropagator.java | 4 +- .../org/drools/core/reteoo/ObjectSource.java | 26 +- .../drools/core/reteoo/ObjectTypeNode.java | 6 +- .../org/drools/core/reteoo/PathEndNode.java | 6 +- .../org/drools/core/reteoo/PathMemory.java | 2 +- .../drools/core/reteoo/QueryElementNode.java | 2 +- .../drools/core/reteoo/QueryTerminalNode.java | 8 +- .../org/drools/core/reteoo/ReteooBuilder.java | 57 +- .../core/reteoo/RightInputAdapterNode.java | 591 +++++++++--------- .../org/drools/core/reteoo/RightTuple.java | 2 +- .../drools/core/reteoo/RightTupleSink.java | 2 +- .../drools/core/reteoo/RuleTerminalNode.java | 6 +- .../org/drools/core/reteoo/SegmentMemory.java | 22 +- .../core/reteoo/SingleObjectSinkAdapter.java | 43 +- .../org/drools/core/reteoo/TimerNode.java | 2 +- .../org/drools/core/reteoo/TupleFactory.java | 12 +- .../drools/core/reteoo/TupleToObjectNode.java | 437 +++++++++++++ .../org/drools/core/reteoo/WindowNode.java | 6 +- .../reteoo/builder/AccumulateBuilder.java | 12 +- .../core/reteoo/builder/BuildUtils.java | 6 +- .../core/reteoo/builder/CollectBuilder.java | 12 +- .../reteoo/builder/GroupElementBuilder.java | 28 +- .../core/reteoo/builder/NodeFactory.java | 10 +- .../reteoo/builder/PhreakNodeFactory.java | 22 +- .../reteoo/builder/ReteooRuleBuilder.java | 11 +- .../org/drools/core/reteoo/BaseNodeTest.java | 16 + .../org/drools/core/reteoo/BetaNodeTest.java | 11 +- .../drools/core/reteoo/MockLeftTupleSink.java | 17 + .../drools/core/reteoo/NodeTypeEnumTest.java | 12 +- .../drools/core/util/RightTupleListTest.java | 7 +- .../debug/BetaRightAdapterNodeVisitor.java | 60 ++ .../debug/RightInputAdapterNodeVisitor.java | 7 +- .../kiesession/debug/SessionInspector.java | 17 +- .../kiesession/NodeSegmentUnlinkingTest.java | 107 ++-- .../drools/kiesession/RuleUnlinkingTest.java | 79 +-- .../RuleUnlinkingWithSegmentMemoryTest.java | 69 +- .../model/codegen/execmodel/IndexTest.java | 9 +- .../execmodel/PropertyReactivityTest.java | 2 +- .../mvel/MVELConsequenceBuilderTest.java | 79 +-- .../org/drools/retediagram/ReteDiagram.java | 10 +- .../protobuf/iterators/LeftTupleIterator.java | 5 +- .../iterators/PhreakActivationIterator.java | 4 + .../protobuf/marshalling/RuleBaseNodes.java | 5 + .../protobuf/MarshallingTest.java | 9 +- .../AccumulateMvelDialectTest.java | 10 +- .../AlphaNetworkModifyTest.java | 10 +- .../BackwardChainingTest.java | 26 +- .../compiler/integrationtests/CepEspTest.java | 7 +- .../JoinNodeRangeIndexingTest.java | 5 +- .../NegativePatternsTest.java | 5 +- .../integrationtests/operators/NotTest.java | 3 +- .../mvel/CompositeObjectSinkAdapterTest.java | 17 +- .../LeftTupleIndexHashTableIteratorTest.java | 32 +- .../java/org/drools/mvel/MockBetaNode.java | 31 +- .../drools/mvel/compiler/MemoryLeakTest.java | 3 +- .../util/debug/SessionInspectorTest.java | 36 +- .../mvel/integrationtests/LinkingTest.java | 37 +- .../NodePositionInPathTest.java | 6 +- .../NodesPartitioningTest.java | 12 +- .../integrationtests/PathEndNodeTest.java | 9 +- .../PropertySpecificTest.java | 435 ++++++------- .../integrationtests/SegmentCreationTest.java | 25 +- .../integrationtests/phreak/AddRuleTest.java | 44 +- .../phreak/BetaNodeBuilder.java | 10 +- .../integrationtests/phreak/RightBuilder.java | 10 +- .../integrationtests/phreak/RightMemory.java | 2 +- .../util/RightTupleIndexHashTableTest.java | 32 +- 113 files changed, 2296 insertions(+), 1916 deletions(-) create mode 100644 drools-core/src/main/java/org/drools/core/reteoo/AccumulateRight.java create mode 100644 drools-core/src/main/java/org/drools/core/reteoo/ExistsRight.java create mode 100644 drools-core/src/main/java/org/drools/core/reteoo/JoinRightAdapterNode.java create mode 100644 drools-core/src/main/java/org/drools/core/reteoo/NotRight.java create mode 100644 drools-core/src/main/java/org/drools/core/reteoo/TupleToObjectNode.java create mode 100755 drools-kiesession/src/main/java/org/drools/kiesession/debug/BetaRightAdapterNodeVisitor.java diff --git a/drools-alphanetwork-compiler/src/main/java/org/drools/ancompiler/AssertHandler.java b/drools-alphanetwork-compiler/src/main/java/org/drools/ancompiler/AssertHandler.java index 11c4519ae70..b7a112ac586 100644 --- a/drools-alphanetwork-compiler/src/main/java/org/drools/ancompiler/AssertHandler.java +++ b/drools-alphanetwork-compiler/src/main/java/org/drools/ancompiler/AssertHandler.java @@ -23,6 +23,7 @@ import com.github.javaparser.ast.expr.Expression; import com.github.javaparser.ast.expr.NameExpr; import com.github.javaparser.ast.stmt.Statement; +import org.drools.base.reteoo.NodeTypeEnums; import org.drools.core.reteoo.Sink; import static com.github.javaparser.StaticJavaParser.parseStatement; @@ -40,7 +41,11 @@ protected Statement propagateMethod(Sink sink) { if (sinkCanBeInlined(sink)) { assertStatement = parseStatement("ALPHATERMINALNODE.collectObject();"); } else { - assertStatement = parseStatement("ALPHATERMINALNODE.assertObject(handle, context, wm);"); + String g = ""; + if (NodeTypeEnums.isBetaNode(sink)) { + g = "getRightInput()."; + } + assertStatement = parseStatement("ALPHATERMINALNODE." + g + "assertObject(handle, context, wm);"); } replaceNameExpr(assertStatement, "ALPHATERMINALNODE", getVariableName(sink)); return assertStatement; diff --git a/drools-alphanetwork-compiler/src/main/java/org/drools/ancompiler/CompiledNetwork.java b/drools-alphanetwork-compiler/src/main/java/org/drools/ancompiler/CompiledNetwork.java index a5b9d3eabe8..e88f0563998 100644 --- a/drools-alphanetwork-compiler/src/main/java/org/drools/ancompiler/CompiledNetwork.java +++ b/drools-alphanetwork-compiler/src/main/java/org/drools/ancompiler/CompiledNetwork.java @@ -218,13 +218,13 @@ public boolean isEmpty() { } @Override - public void doLinkRiaNode(ReteEvaluator reteEvaluator) { - originalSinkPropagator.doLinkRiaNode(reteEvaluator); + public void doLinkSubnetwork(ReteEvaluator reteEvaluator) { + originalSinkPropagator.doLinkSubnetwork(reteEvaluator); } @Override - public void doUnlinkRiaNode(ReteEvaluator reteEvaluator) { - originalSinkPropagator.doUnlinkRiaNode(reteEvaluator); + public void doUnlinkSubnetwork(ReteEvaluator reteEvaluator) { + originalSinkPropagator.doUnlinkSubnetwork(reteEvaluator); } public abstract void init(Object... args); diff --git a/drools-alphanetwork-compiler/src/main/java/org/drools/ancompiler/ModifyHandler.java b/drools-alphanetwork-compiler/src/main/java/org/drools/ancompiler/ModifyHandler.java index f5091fd2431..b4518fb0924 100644 --- a/drools-alphanetwork-compiler/src/main/java/org/drools/ancompiler/ModifyHandler.java +++ b/drools-alphanetwork-compiler/src/main/java/org/drools/ancompiler/ModifyHandler.java @@ -23,6 +23,7 @@ import com.github.javaparser.ast.expr.Expression; import com.github.javaparser.ast.expr.NameExpr; import com.github.javaparser.ast.stmt.Statement; +import org.drools.base.reteoo.NodeTypeEnums; import org.drools.core.reteoo.Sink; import static com.github.javaparser.StaticJavaParser.parseStatement; @@ -40,8 +41,16 @@ protected Statement propagateMethod(Sink sink) { if (sinkCanBeInlined(sink)) { modifyStatement = parseStatement("ALPHATERMINALNODE.collectObject();"); } else { - modifyStatement = parseStatement("ALPHATERMINALNODE.modifyObject(handle, modifyPreviousTuples, context, wm);"); + String g = ""; + if (NodeTypeEnums.isBetaNode(sink)) { + g = "getRightInput()."; + } + + modifyStatement = parseStatement("ALPHATERMINALNODE." + g + "modifyObject(handle, modifyPreviousTuples, context, wm);"); } + + + replaceNameExpr(modifyStatement, "ALPHATERMINALNODE", getVariableName(sink)); return modifyStatement; } diff --git a/drools-alphanetwork-compiler/src/main/java/org/drools/ancompiler/ObjectTypeNodeParser.java b/drools-alphanetwork-compiler/src/main/java/org/drools/ancompiler/ObjectTypeNodeParser.java index 9069121b14c..e5dc061dcb0 100644 --- a/drools-alphanetwork-compiler/src/main/java/org/drools/ancompiler/ObjectTypeNodeParser.java +++ b/drools-alphanetwork-compiler/src/main/java/org/drools/ancompiler/ObjectTypeNodeParser.java @@ -27,6 +27,7 @@ import org.drools.core.reteoo.AlphaNode; import org.drools.core.reteoo.BetaNode; +import org.drools.core.reteoo.RightInputAdapterNode; import org.drools.core.reteoo.CompositeObjectSinkAdapter; import org.drools.core.reteoo.CompositeObjectSinkAdapter.FieldIndex; import org.drools.core.reteoo.CompositePartitionAwareObjectSinkAdapter; @@ -201,8 +202,8 @@ private void traverseSink(ObjectSink sink, NetworkHandler handler) { traversePropagator(alphaNode.getObjectSinkPropagator(), handler); handler.endNonHashedAlphaNode(alphaNode); - } else if (NodeTypeEnums.isBetaNode( sink ) ) { - BetaNode betaNode = (BetaNode) sink; + } else if (NodeTypeEnums.isBetaRightNode( sink ) ) { + BetaNode betaNode = ((RightInputAdapterNode) sink).getBetaNode(); handler.startBetaNode(betaNode); handler.endBetaNode(betaNode); diff --git a/drools-base/src/main/java/org/drools/base/common/NetworkNode.java b/drools-base/src/main/java/org/drools/base/common/NetworkNode.java index 5d0288312cd..0bb1b229ddc 100644 --- a/drools-base/src/main/java/org/drools/base/common/NetworkNode.java +++ b/drools-base/src/main/java/org/drools/base/common/NetworkNode.java @@ -54,7 +54,7 @@ public interface NetworkNode extends Serializable { NetworkNode[] getSinks(); - default boolean isRightInputIsRiaNode() { + default boolean inputIsTupleToObjectNode() { // not ideal, but this was here to allow NetworkNode to be in drools-base return false; } diff --git a/drools-base/src/main/java/org/drools/base/reteoo/BaseTerminalNode.java b/drools-base/src/main/java/org/drools/base/reteoo/BaseTerminalNode.java index 66f2b6b4d7b..cec8893e962 100644 --- a/drools-base/src/main/java/org/drools/base/reteoo/BaseTerminalNode.java +++ b/drools-base/src/main/java/org/drools/base/reteoo/BaseTerminalNode.java @@ -33,18 +33,8 @@ public interface BaseTerminalNode extends NetworkNode { void initInferredMask(); - BitMask getDeclaredMask(); - - void setDeclaredMask(BitMask mask); - - BitMask getInferredMask(); - - void setInferredMask(BitMask mask); - BitMask getNegativeMask(); - void setNegativeMask(BitMask mask); - RuleImpl getRule(); GroupElement getSubRule(); diff --git a/drools-base/src/main/java/org/drools/base/reteoo/NodeTypeEnums.java b/drools-base/src/main/java/org/drools/base/reteoo/NodeTypeEnums.java index 83b09a16291..ce509eb8516 100644 --- a/drools-base/src/main/java/org/drools/base/reteoo/NodeTypeEnums.java +++ b/drools-base/src/main/java/org/drools/base/reteoo/NodeTypeEnums.java @@ -34,7 +34,9 @@ public class NodeTypeEnums { public static final int EndNodeMask = 1 << 8; public static final int BetaMask = 1 << 9; - public static final int MemoryFactoryMask = 1 << 10; + public static final int BetaRightMask = 1 << 10; + + public static final int MemoryFactoryMask = 1 << 11; public static final int shift = 15; // This must shift the node IDs, enough so their bits are not mutated by the masks. @@ -46,8 +48,15 @@ public class NodeTypeEnums { public static final int WindowNode = (150 << shift) | ObjectSourceMask | ObjectSinkMask | MemoryFactoryMask; // ObjectSource, LeftTupleSink - public static final int RightInputAdapterNode = (160 << shift) | ObjectSourceMask | TupleSinkMask | - TupleNodeMask | EndNodeMask | MemoryFactoryMask; + public static final int TupleToObjectNode = (160 << shift) | ObjectSourceMask | TupleSinkMask | + TupleNodeMask | EndNodeMask | MemoryFactoryMask; + + public static final int JoinRightAdapterNode = (162 << shift) | ObjectSinkMask | BetaRightMask; + public static final int ExistsRightAdapterNode = (164 << shift) | ObjectSinkMask | BetaRightMask; + public static final int NotRightAdapterNode = (166 << shift) | ObjectSinkMask | BetaRightMask; + public static final int AccumulateRightAdapterNode = (168 << shift) | ObjectSinkMask | BetaRightMask; + + // LefTTupleSink, LeftTupleNode public static final int RuleTerminalNode = (180 << shift) | TupleSinkMask | TerminalNodeMask | TupleNodeMask | EndNodeMask | MemoryFactoryMask; @@ -97,8 +106,12 @@ public static boolean isBetaNode(NetworkNode node) { return (node.getType() & BetaMask) != 0; } - public static boolean isBetaNodeWithRian(NetworkNode node) { - return isBetaNode(node) && node.isRightInputIsRiaNode(); + public static boolean isBetaNodeWithSubnetwork(NetworkNode node) { + return isBetaNode(node) && node.inputIsTupleToObjectNode(); + } + + public static boolean isBetaNodeWithoutSubnetwork(NetworkNode node) { + return isBetaNode(node) && !node.inputIsTupleToObjectNode(); } public static boolean isTerminalNode(NetworkNode node) { @@ -130,4 +143,8 @@ public static boolean isLeftInputAdapterNode(NetworkNode node) { return (node.getType() & LeftInputAdapterMask) != 0; } + public static boolean isBetaRightNode(NetworkNode node) { + return (node.getType() & BetaRightMask) != 0; + } + } diff --git a/drools-core/src/main/java/org/drools/core/common/BaseNode.java b/drools-core/src/main/java/org/drools/core/common/BaseNode.java index 9677f359451..fd151c12918 100644 --- a/drools-core/src/main/java/org/drools/core/common/BaseNode.java +++ b/drools-core/src/main/java/org/drools/core/common/BaseNode.java @@ -36,6 +36,7 @@ import org.drools.core.reteoo.Sink; import org.drools.core.reteoo.TerminalNode; import org.drools.core.reteoo.builder.BuildContext; +import org.drools.util.bitmask.BitMask; import org.kie.api.definition.rule.Rule; import org.drools.base.reteoo.NodeTypeEnums; @@ -110,6 +111,8 @@ protected void setStreamMode(boolean streamMode) { this.streamMode = streamMode; } + public abstract BaseNode getParent(); + /** * Attaches the node into the network. Usually to the parent ObjectSource or TupleSource */ @@ -174,14 +177,10 @@ public void setPartitionId(BuildContext context, RuleBasePartitionId partitionId /** * Associates this node with the give rule */ - public void addAssociation( Rule rule ) { + public void addAssociation(Rule rule, BuildContext context) { this.associations.add( rule ); } - public void addAssociation( BuildContext context, Rule rule ) { - addAssociation( rule ); - } - /** * Removes the association to the given rule from the * associations map. @@ -242,4 +241,6 @@ public NetworkNode[] getSinks() { } + public abstract BitMask getDeclaredMask(); + public abstract BitMask getInferredMask(); } diff --git a/drools-core/src/main/java/org/drools/core/common/SuperCacheFixer.java b/drools-core/src/main/java/org/drools/core/common/SuperCacheFixer.java index c98789a52ec..b08a1f10f75 100644 --- a/drools-core/src/main/java/org/drools/core/common/SuperCacheFixer.java +++ b/drools-core/src/main/java/org/drools/core/common/SuperCacheFixer.java @@ -21,24 +21,28 @@ import org.drools.base.common.NetworkNode; import org.drools.base.reteoo.NodeTypeEnums; import org.drools.core.reteoo.AccumulateNode; +import org.drools.core.reteoo.AccumulateRight; import org.drools.core.reteoo.AlphaTerminalNode; import org.drools.core.reteoo.AsyncReceiveNode; import org.drools.core.reteoo.AsyncSendNode; import org.drools.core.reteoo.ConditionalBranchNode; import org.drools.core.reteoo.EvalConditionNode; import org.drools.core.reteoo.ExistsNode; +import org.drools.core.reteoo.ExistsRight; import org.drools.core.reteoo.FromNode; import org.drools.core.reteoo.JoinNode; +import org.drools.core.reteoo.JoinRightAdapterNode; import org.drools.core.reteoo.LeftInputAdapterNode; import org.drools.core.reteoo.LeftTupleNode; import org.drools.core.reteoo.LeftTupleSinkNode; import org.drools.core.reteoo.LeftTupleSource; import org.drools.core.reteoo.NotNode; +import org.drools.core.reteoo.NotRight; import org.drools.core.reteoo.ObjectTypeNodeId; import org.drools.core.reteoo.QueryElementNode; import org.drools.core.reteoo.QueryTerminalNode; import org.drools.core.reteoo.ReactiveFromNode; -import org.drools.core.reteoo.RightInputAdapterNode; +import org.drools.core.reteoo.TupleToObjectNode; import org.drools.core.reteoo.RightTuple; import org.drools.core.reteoo.RightTupleSink; import org.drools.core.reteoo.RuleTerminalNode; @@ -57,7 +61,7 @@ public static LeftTupleNode getLeftTupleNode(TupleImpl t) { switch (s.getType()) { case NodeTypeEnums.RuleTerminalNode : return (RuleTerminalNode) s; case NodeTypeEnums.QueryTerminalNode: return (QueryTerminalNode) s; - case NodeTypeEnums.RightInputAdapterNode: return (RightInputAdapterNode) s; + case NodeTypeEnums.TupleToObjectNode: return (TupleToObjectNode) s; case NodeTypeEnums.LeftInputAdapterNode: return (LeftInputAdapterNode) s; case NodeTypeEnums.AlphaTerminalNode: return (AlphaTerminalNode) s; case NodeTypeEnums.AccumulateNode : return (AccumulateNode) s; @@ -81,10 +85,10 @@ public static LeftTupleNode getLeftTupleNode(TupleImpl t) { public static RightTupleSink getRightTupleSink(RightTuple t) { Sink s = t.getSink(); switch (s.getType()) { - case NodeTypeEnums.AccumulateNode : return (AccumulateNode) s; - case NodeTypeEnums.ExistsNode: return (ExistsNode) s; - case NodeTypeEnums.NotNode: return (NotNode) s; - case NodeTypeEnums.JoinNode: return (JoinNode) s; + case NodeTypeEnums.AccumulateRightAdapterNode: return (AccumulateRight) s; + case NodeTypeEnums.ExistsRightAdapterNode: return (ExistsRight) s; + case NodeTypeEnums.NotRightAdapterNode: return (NotRight) s; + case NodeTypeEnums.JoinRightAdapterNode: return (JoinRightAdapterNode) s; case NodeTypeEnums.WindowNode: return (WindowNode) s; case NodeTypeEnums.MockBetaNode: return (RightTupleSink) s; case NodeTypeEnums.MockAlphaNode: return (RightTupleSink) s; @@ -97,7 +101,7 @@ public static LeftTupleSinkNode asLeftTupleSink(NetworkNode n) { switch (n.getType()) { case NodeTypeEnums.RuleTerminalNode : return (RuleTerminalNode) n; case NodeTypeEnums.QueryTerminalNode: return (QueryTerminalNode) n; - case NodeTypeEnums.RightInputAdapterNode: return (RightInputAdapterNode) n; + case NodeTypeEnums.TupleToObjectNode: return (TupleToObjectNode) n; case NodeTypeEnums.AccumulateNode : return (AccumulateNode) n; case NodeTypeEnums.ExistsNode: return (ExistsNode) n; case NodeTypeEnums.NotNode: return (NotNode) n; @@ -119,22 +123,22 @@ public static LeftTupleSinkNode asLeftTupleSink(NetworkNode n) { public static ObjectTypeNodeId getLeftInputOtnId(TupleImpl t) { Sink s = t.getSink(); switch (s.getType()) { - case NodeTypeEnums.RuleTerminalNode : return ((RuleTerminalNode) s).getLeftInputOtnId(); - case NodeTypeEnums.QueryTerminalNode: return ((QueryTerminalNode) s).getLeftInputOtnId(); - case NodeTypeEnums.RightInputAdapterNode: return ((RightInputAdapterNode) s).getLeftInputOtnId(); - case NodeTypeEnums.AccumulateNode : return ((AccumulateNode) s).getLeftInputOtnId(); - case NodeTypeEnums.ExistsNode: return ((ExistsNode) s).getLeftInputOtnId(); - case NodeTypeEnums.NotNode: return ((NotNode) s).getLeftInputOtnId(); - case NodeTypeEnums.JoinNode: return ((JoinNode) s).getLeftInputOtnId(); - case NodeTypeEnums.FromNode: return ((FromNode) s).getLeftInputOtnId(); - case NodeTypeEnums.EvalConditionNode: return ((EvalConditionNode) s).getLeftInputOtnId(); - case NodeTypeEnums.AsyncReceiveNode: return ((AsyncReceiveNode) s).getLeftInputOtnId(); - case NodeTypeEnums.AsyncSendNode: return ((AsyncSendNode) s).getLeftInputOtnId(); - case NodeTypeEnums.ReactiveFromNode: return ((ReactiveFromNode) s).getLeftInputOtnId(); - case NodeTypeEnums.ConditionalBranchNode: return ((ConditionalBranchNode) s).getLeftInputOtnId(); - case NodeTypeEnums.QueryElementNode: return ((QueryElementNode) s).getLeftInputOtnId(); - case NodeTypeEnums.TimerConditionNode: return ((TimerNode) s).getLeftInputOtnId(); - case NodeTypeEnums.MockBetaNode: return ((LeftTupleSource)s).getLeftInputOtnId(); + case NodeTypeEnums.RuleTerminalNode : return ((RuleTerminalNode) s).getInputOtnId(); + case NodeTypeEnums.QueryTerminalNode: return ((QueryTerminalNode) s).getInputOtnId(); + case NodeTypeEnums.TupleToObjectNode: return ((TupleToObjectNode) s).getInputOtnId(); + case NodeTypeEnums.AccumulateNode : return ((AccumulateNode) s).getInputOtnId(); + case NodeTypeEnums.ExistsNode: return ((ExistsNode) s).getInputOtnId(); + case NodeTypeEnums.NotNode: return ((NotNode) s).getInputOtnId(); + case NodeTypeEnums.JoinNode: return ((JoinNode) s).getInputOtnId(); + case NodeTypeEnums.FromNode: return ((FromNode) s).getInputOtnId(); + case NodeTypeEnums.EvalConditionNode: return ((EvalConditionNode) s).getInputOtnId(); + case NodeTypeEnums.AsyncReceiveNode: return ((AsyncReceiveNode) s).getInputOtnId(); + case NodeTypeEnums.AsyncSendNode: return ((AsyncSendNode) s).getInputOtnId(); + case NodeTypeEnums.ReactiveFromNode: return ((ReactiveFromNode) s).getInputOtnId(); + case NodeTypeEnums.ConditionalBranchNode: return ((ConditionalBranchNode) s).getInputOtnId(); + case NodeTypeEnums.QueryElementNode: return ((QueryElementNode) s).getInputOtnId(); + case NodeTypeEnums.TimerConditionNode: return ((TimerNode) s).getInputOtnId(); + case NodeTypeEnums.MockBetaNode: return ((LeftTupleSource)s).getInputOtnId(); default: throw new UnsupportedOperationException("Node does not have an LeftInputOtnId: " + s); } @@ -143,11 +147,11 @@ public static ObjectTypeNodeId getLeftInputOtnId(TupleImpl t) { public static ObjectTypeNodeId getRightInputOtnId(TupleImpl t) { Sink s = t.getSink(); switch (s.getType()) { - case NodeTypeEnums.AccumulateNode : return ((AccumulateNode) s).getRightInputOtnId(); - case NodeTypeEnums.ExistsNode: return ((ExistsNode) s).getRightInputOtnId(); - case NodeTypeEnums.NotNode: return ((NotNode) s).getRightInputOtnId(); - case NodeTypeEnums.JoinNode: return ((JoinNode) s).getRightInputOtnId(); - case NodeTypeEnums.WindowNode: return ((WindowNode) s).getRightInputOtnId(); + case NodeTypeEnums.AccumulateRightAdapterNode: return ((AccumulateRight) s).getInputOtnId(); + case NodeTypeEnums.ExistsRightAdapterNode: return ((ExistsRight) s).getInputOtnId(); + case NodeTypeEnums.NotRightAdapterNode: return ((NotRight) s).getInputOtnId(); + case NodeTypeEnums.JoinRightAdapterNode: return ((JoinRightAdapterNode) s).getInputOtnId(); + case NodeTypeEnums.WindowNode: return ((WindowNode) s).getInputOtnId(); default: throw new UnsupportedOperationException("Node does not have an RightInputOtnId: " + s); } @@ -158,7 +162,7 @@ public static LeftTupleSource getLeftTupleSource(TupleImpl t) { switch (s.getType()) { case NodeTypeEnums.RuleTerminalNode : return ((RuleTerminalNode) s).getLeftTupleSource(); case NodeTypeEnums.QueryTerminalNode: return ((QueryTerminalNode) s).getLeftTupleSource(); - case NodeTypeEnums.RightInputAdapterNode: return ((RightInputAdapterNode) s).getLeftTupleSource(); + case NodeTypeEnums.TupleToObjectNode: return ((TupleToObjectNode) s).getLeftTupleSource(); case NodeTypeEnums.AccumulateNode : return ((AccumulateNode) s).getLeftTupleSource(); case NodeTypeEnums.ExistsNode: return ((ExistsNode) s).getLeftTupleSource(); case NodeTypeEnums.NotNode: return ((NotNode) s).getLeftTupleSource(); diff --git a/drools-core/src/main/java/org/drools/core/impl/KnowledgeBaseImpl.java b/drools-core/src/main/java/org/drools/core/impl/KnowledgeBaseImpl.java index e14d287f218..9f39ec1c843 100644 --- a/drools-core/src/main/java/org/drools/core/impl/KnowledgeBaseImpl.java +++ b/drools-core/src/main/java/org/drools/core/impl/KnowledgeBaseImpl.java @@ -160,6 +160,10 @@ public class KnowledgeBaseImpl implements InternalRuleBase { public KnowledgeBaseImpl() { } + public KnowledgeBaseImpl(String id) { + this(id, (CompositeBaseConfiguration) RuleBaseFactory.newKnowledgeBaseConfiguration()); + } + public KnowledgeBaseImpl(final String id, final CompositeBaseConfiguration config) { this.config = config; diff --git a/drools-core/src/main/java/org/drools/core/phreak/BuildtimeSegmentUtilities.java b/drools-core/src/main/java/org/drools/core/phreak/BuildtimeSegmentUtilities.java index 1c570fdebe0..d3b64d0130e 100644 --- a/drools-core/src/main/java/org/drools/core/phreak/BuildtimeSegmentUtilities.java +++ b/drools-core/src/main/java/org/drools/core/phreak/BuildtimeSegmentUtilities.java @@ -41,7 +41,7 @@ import org.drools.core.reteoo.PathEndNode.PathMemSpec; import org.drools.core.reteoo.QueryElementNode; import org.drools.core.reteoo.ReactiveFromNode; -import org.drools.core.reteoo.RightInputAdapterNode; +import org.drools.core.reteoo.TupleToObjectNode; import org.drools.core.reteoo.SegmentMemory.AccumulateMemoryPrototype; import org.drools.core.reteoo.SegmentMemory.AsyncReceiveMemoryPrototype; import org.drools.core.reteoo.SegmentMemory.AsyncSendMemoryPrototype; @@ -66,7 +66,7 @@ public static void updateSegmentEndNodes(PathEndNode endNode) { SegmentPrototype smproto = endNode.getSegmentPrototypes()[endNode.getSegmentPrototypes().length-1]; if (smproto.getPathEndNodes() != null) { // This is a special check, for shared subnetwork paths. It ensure it's initallysed only once, - // even though the rian is shared with different TNs. + // even though the TupleToObjectNode is shared with different TNs. return; } @@ -88,7 +88,7 @@ public static void updateSegmentEndNodes(PathEndNode endNode) { private static void setSegments(PathEndNode endNode, SegmentPrototype[] smems) { List eager = new ArrayList<>(); for (SegmentPrototype smem : smems) { - // The segments before the start of a subnetwork, will be null for a rian path. + // The segments before the start of a subnetwork, will be null for a TupleToObjectNode path. if (smem != null && smem.requiresEager()) { eager.add(smem); } @@ -162,7 +162,7 @@ public static SegmentPrototype[] createLeftTupleNodeProtoMemories(LeftTupleNode // reset to find the next segments and set their position and their bit mask int ruleSegmentPosMask = 1; for (int i = 0; i < smems.size(); i++) { - if ( start >= 0 && smems.get(i) != null) { // The segments before the start of a subnetwork, will be null for a rian path. + if ( start >= 0 && smems.get(i) != null) { // The segments before the start of a subnetwork, will be null for a TupleToObjectNode path. smems.get(i).setPos(i); if (smems.get(i).getAllLinkedMaskTest() > 0) { smems.get(i).setSegmentPosMaskBit(ruleSegmentPosMask); @@ -239,8 +239,8 @@ public static SegmentPrototype createSegmentMemory(LeftTupleNode segmentRoot, Le case NodeTypeEnums.QueryElementNode: updateNodeBit = processQueryNode((QueryElementNode) node, memories, nodes, nodePosMask); break; - case NodeTypeEnums.RightInputAdapterNode: - processRightInputAdapterNode((RightInputAdapterNode) node, memories, nodes); + case NodeTypeEnums.TupleToObjectNode: + processRightInputAdapterNode((TupleToObjectNode) node, memories, nodes); break; case NodeTypeEnums.RuleTerminalNode: case NodeTypeEnums.QueryTerminalNode: @@ -309,7 +309,7 @@ private static void processConditionalBranchNode(ConditionalBranchNode tupleSour nodes.add(tupleSource); } - private static void processRightInputAdapterNode(RightInputAdapterNode tupleSource, List memories, List nodes) { + private static void processRightInputAdapterNode(TupleToObjectNode tupleSource, List memories, List nodes) { RightInputAdapterPrototype mem = new RightInputAdapterPrototype(); memories.add(mem); nodes.add(tupleSource); @@ -356,16 +356,16 @@ private static long processLiaNode(LeftInputAdapterNode tupleSource, List memories, List nodes, long nodePosMask, long allLinkedTestMask, boolean updateNodeBit, TerminalNode removingTn, InternalRuleBase rbase) { - RightInputAdapterNode riaNode = null; - if (betaNode.isRightInputIsRiaNode()) { + TupleToObjectNode tton = null; + if (betaNode.getRightInput().inputIsTupleToObjectNode()) { // there is a subnetwork, so create all it's segment memory prototypes - riaNode = (RightInputAdapterNode) betaNode.getRightInput(); + tton = (TupleToObjectNode) betaNode.getRightInput().getParent(); - SegmentPrototype[] smems = createLeftTupleNodeProtoMemories(riaNode, removingTn, rbase); - setSegments(riaNode, smems); + SegmentPrototype[] smems = createLeftTupleNodeProtoMemories(tton, removingTn, rbase); + setSegments(tton, smems); - if (updateNodeBit && canBeDisabled(betaNode) && riaNode.getPathMemSpec().allLinkedTestMask() > 0) { - // only ria's with reactive subnetworks can be disabled and thus need checking + if (updateNodeBit && canBeDisabled(betaNode) && tton.getPathMemSpec().allLinkedTestMask() > 0) { + // only TupleToObjectNode's with reactive subnetworks can be disabled and thus need checking allLinkedTestMask = allLinkedTestMask | nodePosMask; } } else if (updateNodeBit && canBeDisabled(betaNode)) { @@ -377,7 +377,7 @@ private static long processBetaNode(BetaNode betaNode, SegmentPrototype smem, Li smem.linkNode(nodePosMask); } - BetaMemoryPrototype bm = new BetaMemoryPrototype(nodePosMask, riaNode); + BetaMemoryPrototype bm = new BetaMemoryPrototype(nodePosMask, tton); if (NodeTypeEnums.AccumulateNode == betaNode.getType()) { AccumulateMemoryPrototype am = new AccumulateMemoryPrototype(bm); @@ -393,7 +393,7 @@ private static long processBetaNode(BetaNode betaNode, SegmentPrototype smem, Li public static boolean canBeDisabled(BetaNode betaNode) { // non empty not nodes and accumulates can never be disabled and thus don't need checking return (!(NodeTypeEnums.NotNode == betaNode.getType() && !((NotNode) betaNode).isEmptyBetaConstraints()) && - NodeTypeEnums.AccumulateNode != betaNode.getType() && !betaNode.isRightInputPassive()); + NodeTypeEnums.AccumulateNode != betaNode.getType() && !betaNode.getRightInput().isRightInputPassive()); } /** @@ -411,7 +411,7 @@ public static boolean isRootNode(LeftTupleNode node, TerminalNode ignoreTn) { /** * Returns whether the node is the tip of a segment. - * EndNodes (rtn and rian) are always the tip of a segment. + * EndNodes (rtn and TupleToObjectNode) are always the tip of a segment. * * node cannot be null. * @@ -466,7 +466,7 @@ public static int updateNodeTypesMask(NetworkNode node, int mask) { mask |= JOIN_NODE_BIT; break; case NodeTypeEnums.ExistsNode: - if ( ( (ExistsNode) node ).isRightInputPassive() ) { + if ( ( (ExistsNode) node ).getRightInput().isRightInputPassive() ) { mask |= PASSIVE_EXISTS_NODE_BIT; } else { mask |= REACTIVE_EXISTS_NODE_BIT; diff --git a/drools-core/src/main/java/org/drools/core/phreak/EagerPhreakBuilder.java b/drools-core/src/main/java/org/drools/core/phreak/EagerPhreakBuilder.java index 2c4e58d806f..1475867533f 100644 --- a/drools-core/src/main/java/org/drools/core/phreak/EagerPhreakBuilder.java +++ b/drools-core/src/main/java/org/drools/core/phreak/EagerPhreakBuilder.java @@ -31,6 +31,7 @@ import org.drools.base.common.NetworkNode; import org.drools.base.reteoo.NodeTypeEnums; import org.drools.core.WorkingMemory; +import org.drools.core.common.BaseNode; import org.drools.core.common.DefaultEventHandle; import org.drools.core.common.InternalAgenda; import org.drools.core.common.InternalFactHandle; @@ -61,6 +62,7 @@ import org.drools.core.reteoo.PathMemory; import org.drools.core.reteoo.QueryElementNode; import org.drools.core.reteoo.RightInputAdapterNode; +import org.drools.core.reteoo.TupleToObjectNode; import org.drools.core.reteoo.RightTuple; import org.drools.core.reteoo.RuleTerminalNodeLeftTuple; import org.drools.core.reteoo.RuntimeComponentFactory; @@ -246,8 +248,8 @@ public static List getExclusiveBranchRoots(TerminalNode tn) { } while (node.getLeftTupleSource() != null) { - if (NodeTypeEnums.isBetaNodeWithRian(node) && ((BetaNode)node).getRightInput().getAssociatedTerminalsSize() > 1) { - exclbranchRoots.add( new Pair((LeftTupleNode) ((BetaNode)node).getRightInput(), node)); + if (NodeTypeEnums.isBetaNodeWithSubnetwork(node) && ((BetaNode)node).getRightInput().getParent().getAssociatedTerminalsSize() > 1) { + exclbranchRoots.add( new Pair((LeftTupleNode) ((BetaNode)node).getRightInput().getParent(), node)); } if (node.getLeftTupleSource().getAssociatedTerminalsSize()> 1) { @@ -342,7 +344,7 @@ public static void insertFacts(TerminalNode tn, InternalWorkingMemory wm, Set exclBranchRoots, TerminalNode tn, for (InternalWorkingMemory wm : wms) { for (PathEndNode endNode : tn.getPathEndNodes() ) { if (endNode.getAssociatedTerminalsSize() > 1) { - // can only happen on rians, and we need to notify, incase they are already linked in + // can only happen on TupleToObjectNodes, and we need to notify, incase they are already linked in Memory mem = wm.getNodeMemories().peekNodeMemory(endNode); if (mem != null && mem.getSegmentMemory() != null) { SegmentMemory sm = mem.getSegmentMemory(); @@ -675,8 +677,8 @@ private static void removeExistingPaths(List exclBranchRoots, TerminalNode for (int i = exclBranchRoots.size() - 1; i >= 0; i--) { // last is the most inner LeftTupleNode child = exclBranchRoots.get(i).child; LeftTupleNode parent = exclBranchRoots.get(i).parent; - if (parent.getType() == NodeTypeEnums.RightInputAdapterNode) { - continue; // A RIAN as it's also a PathEnd doesn't have a child segment + if (parent.getType() == NodeTypeEnums.TupleToObjectNode) { + continue; // A TupleToObjectNode as it's also a PathEnd doesn't have a child segment } // If it exists, remove the child segment memory for the path being removed. @@ -999,7 +1001,7 @@ private static void deleteRightInputData(LeftTupleNode node, Memory m, InternalW } private static void deleteFactsFromRightInput(BetaNode bn, InternalWorkingMemory wm) { - ObjectSource source = bn.getRightInput(); + BaseNode source = bn.getRightInput(); if (source.getType() == NodeTypeEnums.WindowNode) { WindowNode.WindowMemory memory = (WindowNode.WindowMemory) wm.getNodeMemories().peekNodeMemory(source); if (memory != null) { @@ -1088,7 +1090,7 @@ private static void processLeftTuples(LeftTupleNode node, boolean insert, Termin visitChild((TupleImpl) accctx.getResultLeftTuple(), insert, wm, tn); } } else if (NodeTypeEnums.ExistsNode == node.getType() && - !((BetaNode) node).isRightInputIsRiaNode()) { // do not process exists with subnetworks + !((BetaNode) node).getRightInput().inputIsTupleToObjectNode()) { // do not process exists with subnetworks // If there is a subnetwork, then there is no populated RTM, but the LTM is populated, // so this would be procsssed in the "else". @@ -1132,9 +1134,9 @@ private static void processLeftTuples(LeftTupleNode node, boolean insert, Termin } private static void processLeftTuplesOnLian( InternalWorkingMemory wm, boolean insert, TerminalNode tn, LeftInputAdapterNode lian ) { - ObjectSource os = lian.getObjectSource(); + BaseNode os = lian.getObjectSource(); while (os.getType() != NodeTypeEnums.ObjectTypeNode) { - os = os.getParentObjectSource(); + os = os.getParent(); } ObjectTypeNode otn = (ObjectTypeNode) os; @@ -1184,7 +1186,7 @@ private static void visitChild(TupleImpl lt, boolean insert, InternalWorkingMemo for ( TupleImpl child = lt.getFirstChild(); child != null; child = child.getHandleNext() ) { visitChild(child, insert, wm, tn); } - } else if (lt.getSink().getType() == NodeTypeEnums.RightInputAdapterNode) { + } else if (lt.getSink().getType() == NodeTypeEnums.TupleToObjectNode) { insertPeerRightTuple(lt, wm, tn, insert); } } else if (!insert) { @@ -1214,10 +1216,10 @@ private static void visitChild(TupleImpl lt, boolean insert, InternalWorkingMemo private static void insertPeerRightTuple(TupleImpl lt, InternalWorkingMemory wm, TerminalNode tn, boolean insert ) { // There's a shared RightInputAdapterNode, so check if one of its sinks is associated only to the new rule - TupleImpl prevLt = null; - RightInputAdapterNode rian = (RightInputAdapterNode) lt.getSink(); + TupleImpl prevLt = null; + TupleToObjectNode tton = (TupleToObjectNode) lt.getSink(); - for (ObjectSink sink : rian.getObjectSinkPropagator().getSinks()) { + for (ObjectSink sink : tton.getObjectSinkPropagator().getSinks()) { if (lt != null) { if (prevLt != null && !insert && isAssociatedWith(sink, tn) && sink.getAssociatedTerminalsSize() == 1) { prevLt.setPeer( null ); @@ -1225,10 +1227,11 @@ private static void insertPeerRightTuple(TupleImpl lt, InternalWorkingMemory wm, prevLt = lt; lt = lt.getPeer(); } else if (insert) { - BetaMemory bm = (BetaMemory) wm.getNodeMemories().peekNodeMemory(sink); + BetaNode betaNode = ((RightInputAdapterNode)sink).getBetaNode(); + BetaMemory bm = (BetaMemory) wm.getNodeMemories().peekNodeMemory(betaNode); if (bm != null) { - prevLt = TupleFactory.createPeer(rian, prevLt); - bm.linkNode((BetaNode) sink, wm); + prevLt = TupleFactory.createPeer(tton, prevLt); + bm.linkNode(betaNode, wm); bm.getStagedRightTuples().addInsert(prevLt); } } diff --git a/drools-core/src/main/java/org/drools/core/phreak/LazyPhreakBuilder.java b/drools-core/src/main/java/org/drools/core/phreak/LazyPhreakBuilder.java index 52e6b86fb83..518f425ba08 100644 --- a/drools-core/src/main/java/org/drools/core/phreak/LazyPhreakBuilder.java +++ b/drools-core/src/main/java/org/drools/core/phreak/LazyPhreakBuilder.java @@ -30,6 +30,7 @@ import org.drools.base.definitions.rule.impl.RuleImpl; import org.drools.base.reteoo.NodeTypeEnums; +import org.drools.core.common.BaseNode; import org.drools.core.common.DefaultEventHandle; import org.drools.core.common.InternalAgenda; import org.drools.core.common.InternalFactHandle; @@ -51,6 +52,7 @@ import org.drools.core.reteoo.AsyncSendNode; import org.drools.core.reteoo.BetaMemory; import org.drools.core.reteoo.BetaNode; +import org.drools.core.reteoo.RightInputAdapterNode; import org.drools.core.reteoo.ConditionalBranchNode; import org.drools.core.reteoo.EvalConditionNode; import org.drools.core.reteoo.FromNode; @@ -62,13 +64,12 @@ import org.drools.core.reteoo.LeftTupleSinkNode; import org.drools.core.reteoo.LeftTupleSource; import org.drools.core.reteoo.ObjectSink; -import org.drools.core.reteoo.ObjectSource; import org.drools.core.reteoo.ObjectTypeNode; import org.drools.core.reteoo.PathEndNode; import org.drools.core.reteoo.PathMemory; import org.drools.core.reteoo.QueryElementNode; -import org.drools.core.reteoo.RightInputAdapterNode; -import org.drools.core.reteoo.RightInputAdapterNode.RiaPathMemory; +import org.drools.core.reteoo.TupleToObjectNode; +import org.drools.core.reteoo.TupleToObjectNode.SubnetworkPathMemory; import org.drools.core.reteoo.RightTuple; import org.drools.core.reteoo.RuleTerminalNodeLeftTuple; import org.drools.core.reteoo.RuntimeComponentFactory; @@ -97,7 +98,7 @@ import static org.drools.core.phreak.BuildtimeSegmentUtilities.updateNodeTypesMask; import static org.drools.core.phreak.EagerPhreakBuilder.Add.attachAdapterAndPropagate; import static org.drools.core.phreak.EagerPhreakBuilder.deleteLeftTuple; -import static org.drools.core.phreak.RuntimeSegmentUtilities.createRiaSegmentMemory; +import static org.drools.core.phreak.RuntimeSegmentUtilities.createSubnetworkSegmentMemory; import static org.drools.core.phreak.RuntimeSegmentUtilities.getOrCreateSegmentMemory; import static org.drools.core.phreak.RuntimeSegmentUtilities.getQuerySegmentMemory; import static org.drools.core.phreak.TupleEvaluationUtil.forceFlushLeftTuple; @@ -728,7 +729,7 @@ private static void insertFacts(PathEndNodes endNodes, Collection) node); + if (node.getType() == NodeTypeEnums.TupleToObjectNode) { + SubnetworkPathMemory subnMem = (SubnetworkPathMemory) wm.getNodeMemories().peekNodeMemory(node); + if (subnMem == null && !tnMems.otherPmems.isEmpty()) { + subnMem = (SubnetworkPathMemory) wm.getNodeMemory((MemoryFactory) node); } - if (riaMem != null) { - tnMems.subjectPmems.add(riaMem); + if (subnMem != null) { + tnMems.subjectPmems.add(subnMem); } } else { PathMemory pmem = (PathMemory) wm.getNodeMemories().peekNodeMemory(node); @@ -1311,7 +1313,7 @@ private static void collectPathEndNodes(InternalRuleBase kBase, collectPathEndNodes(kBase, sink, endNodes, tn, processedRule, hasProtos, hasWms, isBelowNewSplit); } else if (NodeTypeEnums.isTerminalNode(sink)) { endNodes.otherEndNodes.add((PathEndNode) sink); - } else if (NodeTypeEnums.RightInputAdapterNode == sink.getType()) { + } else if (NodeTypeEnums.TupleToObjectNode == sink.getType()) { if (sink.isAssociatedWith( processedRule )) { endNodes.subjectEndNodes.add( (PathEndNode) sink ); } @@ -1343,7 +1345,7 @@ static SegmentMemory createChildSegment(ReteEvaluator reteEvaluator, LeftTupleNo Memory memory = reteEvaluator.getNodeMemory((MemoryFactory) node); if (memory.getSegmentMemory() == null) { if (NodeTypeEnums.isEndNode(node)) { - // RTNS and RiaNode's have their own segment, if they are the child of a split. + // RTNS and TupleToObjectNode's have their own segment, if they are the child of a split. createChildSegmentForTerminalNode( node, memory ); } else { createSegmentMemory((LeftTupleSource) node, reteEvaluator); @@ -1361,7 +1363,7 @@ static SegmentMemory createSegmentMemory(ReteEvaluator reteEvaluator, LeftTupleN } private static SegmentMemory createChildSegmentForTerminalNode( LeftTupleNode node, Memory memory ) { - SegmentMemory childSmem = new SegmentMemory( node ); // rtns or riatns don't need a queue + SegmentMemory childSmem = new SegmentMemory( node ); // rtns or TupleToObjectNodes don't need a queue PathMemory pmem = (PathMemory) memory; childSmem.setPos( pmem.getSegmentMemories().length - 1 ); @@ -1429,16 +1431,16 @@ private static SegmentMemory createSegmentMemory(LeftTupleSource segmentRoot, Re if (NodeTypeEnums.isLeftTupleSource(sink)) { tupleSource = (LeftTupleSource) sink; } else { - // rtn or rian - // While not technically in a segment, we want to be able to iterate easily from the last node memory to the ria/rtn memory - // we don't use createNodeMemory, as these may already have been created by, but not added, by the method updateRiaAndTerminalMemory + // rtn or TupleToObjectNode + // While not technically in a segment, we want to be able to iterate easily from the last node memory to the TupleToObjectNode/rtn memory + // we don't use createNodeMemory, as these may already have been created by, but not added, by the method updateTupleToObjectAndTerminalMemory Memory memory = reteEvaluator.getNodeMemory((MemoryFactory) sink); - if (sink.getType() == NodeTypeEnums.RightInputAdapterNode) { - PathMemory riaPmem = (RightInputAdapterNode.RiaPathMemory)memory; - memories.add( riaPmem ); + if (sink.getType() == NodeTypeEnums.TupleToObjectNode) { + PathMemory subnMem = (SubnetworkPathMemory)memory; + memories.add( subnMem ); - RightInputAdapterNode rian = ( RightInputAdapterNode ) sink; - ObjectSink[] nodes = rian.getObjectSinkPropagator().getSinks(); + TupleToObjectNode tton = (TupleToObjectNode) sink; + ObjectSink[] nodes = tton.getObjectSinkPropagator().getSinks(); for ( ObjectSink node : nodes ) { if ( NodeTypeEnums.isLeftTupleSource(node) ) { getOrCreateSegmentMemory( (LeftTupleSource) node, reteEvaluator ); @@ -1486,7 +1488,7 @@ private static SegmentMemory createSegmentMemory(LeftTupleSource segmentRoot, Re smem.setSegmentPosMaskBit(ruleSegmentPosMask); smem.setPos(counter); - updateRiaAndTerminalMemory(tupleSource, tupleSource, smem, reteEvaluator, false, nodeTypesInSegment); + updateSubnetworkAndTerminalMemory(tupleSource, tupleSource, smem, reteEvaluator, false, nodeTypesInSegment); reteEvaluator.getKnowledgeBase().registerSegmentPrototype(segmentRoot, smem.getSegmentPrototype().initFromSegmentMemory(smem)); @@ -1579,13 +1581,13 @@ private static long processBetaNode(BetaNode betaNode, ReteEvaluator reteEvaluat // and bm.getSegmentMemory == null check can be used to avoid recursion. bm.setSegmentMemory(smem); - if (betaNode.isRightInputIsRiaNode()) { - RightInputAdapterNode riaNode = createRiaSegmentMemory( betaNode, reteEvaluator ); + if (betaNode.getRightInput().inputIsTupleToObjectNode()) { + TupleToObjectNode tton = createSubnetworkSegmentMemory(betaNode, reteEvaluator); - PathMemory riaMem = reteEvaluator.getNodeMemory(riaNode); - bm.setRiaRuleMemory((RiaPathMemory) riaMem); - if (updateNodeBit && canBeDisabled(betaNode) && riaMem.getAllLinkedMaskTest() > 0) { - // only ria's with reactive subnetworks can be disabled and thus need checking + PathMemory subnetworkPathMemory = reteEvaluator.getNodeMemory(tton); + bm.setSubnetworkPathMemory((SubnetworkPathMemory) subnetworkPathMemory); + if (updateNodeBit && canBeDisabled(betaNode) && subnetworkPathMemory.getAllLinkedMaskTest() > 0) { + // only TupleToObjectNode's with reactive subnetworks can be disabled and thus need checking allLinkedTestMask = allLinkedTestMask | nodePosMask; } } else if (updateNodeBit && canBeDisabled(betaNode)) { @@ -1601,35 +1603,35 @@ private static long processBetaNode(BetaNode betaNode, ReteEvaluator reteEvaluat } /** - * This adds the segment memory to the terminal node or ria node's list of memories. + * This adds the segment memory to the terminal node or TupleToObjectNode node's list of memories. * In the case of the terminal node this allows it to know that all segments from * the tip to root are linked. * In the case of the ria node its all the segments up to the start of the subnetwork. - * This is because the rianode only cares if all of it's segments are linked, then + * This is because the TupleToObjectNode only cares if all of it's segments are linked, then * it sets the bit of node it is the right input for. */ - private static int updateRiaAndTerminalMemory( LeftTupleSource lt, - LeftTupleSource originalLt, - SegmentMemory smem, - ReteEvaluator reteEvaluator, - boolean fromPrototype, - int nodeTypesInSegment ) { + private static int updateSubnetworkAndTerminalMemory(LeftTupleSource lt, + LeftTupleSource originalLt, + SegmentMemory smem, + ReteEvaluator reteEvaluator, + boolean fromPrototype, + int nodeTypesInSegment) { nodeTypesInSegment = checkSegmentBoundary(lt, reteEvaluator, nodeTypesInSegment); PathMemory pmem = null; for (LeftTupleSink sink : lt.getSinkPropagator().getSinks()) { if (NodeTypeEnums.isLeftTupleSource(sink)) { - nodeTypesInSegment = updateRiaAndTerminalMemory((LeftTupleSource) sink, originalLt, smem, reteEvaluator, fromPrototype, nodeTypesInSegment); - } else if (sink.getType() == NodeTypeEnums.RightInputAdapterNode) { + nodeTypesInSegment = updateSubnetworkAndTerminalMemory((LeftTupleSource) sink, originalLt, smem, reteEvaluator, fromPrototype, nodeTypesInSegment); + } else if (sink.getType() == NodeTypeEnums.TupleToObjectNode) { // Even though we don't add the pmem and smem together, all pmem's for all pathend nodes must be initialized - RightInputAdapterNode.RiaPathMemory riaMem = (RightInputAdapterNode.RiaPathMemory) reteEvaluator.getNodeMemory((MemoryFactory) sink); - // Only add the RIANode, if the LeftTupleSource is part of the RIANode subnetwork - if (inSubNetwork((RightInputAdapterNode) sink, originalLt)) { - pmem = riaMem; + SubnetworkPathMemory subnMem = (SubnetworkPathMemory) reteEvaluator.getNodeMemory((MemoryFactory) sink); + // Only add the TupleToObjectNode, if the LeftTupleSource is part of the TupleToObjectNode subnetwork + if (inSubNetwork((TupleToObjectNode) sink, originalLt)) { + pmem = subnMem; if (fromPrototype) { - ObjectSink[] nodes = ((RightInputAdapterNode) sink).getObjectSinkPropagator().getSinks(); + ObjectSink[] nodes = ((TupleToObjectNode) sink).getObjectSinkPropagator().getSinks(); for ( ObjectSink node : nodes ) { // check if the SegmentMemory has been already created by the BetaNode and if so avoid to build it twice if ( NodeTypeEnums.isLeftTupleSource(node) && reteEvaluator.getNodeMemory((MemoryFactory) node).getSegmentMemory() == null ) { @@ -1638,7 +1640,7 @@ private static int updateRiaAndTerminalMemory( LeftTupleSource lt, } } else if ( ( pmem.getAllLinkedMaskTest() & ( 1L << pmem.getSegmentMemories().length ) ) == 0 ) { // must eagerly initialize child segment memories - ObjectSink[] nodes = ((RightInputAdapterNode) sink).getObjectSinkPropagator().getSinks(); + ObjectSink[] nodes = ((TupleToObjectNode) sink).getObjectSinkPropagator().getSinks(); for ( ObjectSink node : nodes ) { if ( NodeTypeEnums.isLeftTupleSource(node) ) { getOrCreateSegmentMemory( (LeftTupleSource) node, reteEvaluator ); @@ -1667,7 +1669,7 @@ private static int updateRiaAndTerminalMemory( LeftTupleSource lt, private static void restoreSegmentFromPrototype(ReteEvaluator reteEvaluator, LeftTupleSource segmentRoot, int nodeTypesInSegment) { SegmentMemory smem = reteEvaluator.getKnowledgeBase().createSegmentFromPrototype(reteEvaluator, segmentRoot); if ( smem != null ) { - updateRiaAndTerminalMemory(segmentRoot, segmentRoot, smem, reteEvaluator, true, nodeTypesInSegment); + updateSubnetworkAndTerminalMemory(segmentRoot, segmentRoot, smem, reteEvaluator, true, nodeTypesInSegment); } } @@ -1684,11 +1686,11 @@ private static int checkSegmentBoundary(LeftTupleSource lt, ReteEvaluator reteEv /** * Is the LeftTupleSource a node in the sub network for the RightInputAdapterNode * To be in the same network, it must be a node is after the two output of the parent - * and before the rianode. + * and before the TupleToObjectNode. */ - private static boolean inSubNetwork(RightInputAdapterNode riaNode, LeftTupleSource leftTupleSource) { - LeftTupleSource startTupleSource = riaNode.getStartTupleSource().getLeftTupleSource(); - LeftTupleSource current = riaNode.getLeftTupleSource(); + private static boolean inSubNetwork(TupleToObjectNode tton, LeftTupleSource leftTupleSource) { + LeftTupleSource startTupleSource = tton.getStartTupleSource().getLeftTupleSource(); + LeftTupleSource current = tton.getLeftTupleSource(); while (current != startTupleSource) { if (current == leftTupleSource) { diff --git a/drools-core/src/main/java/org/drools/core/phreak/PhreakAccumulateNode.java b/drools-core/src/main/java/org/drools/core/phreak/PhreakAccumulateNode.java index e87a4fba138..05b0b4fa80f 100644 --- a/drools-core/src/main/java/org/drools/core/phreak/PhreakAccumulateNode.java +++ b/drools-core/src/main/java/org/drools/core/phreak/PhreakAccumulateNode.java @@ -83,7 +83,7 @@ public void doNode(AccumulateNode accNode, doLeftUpdates(accNode, am, reteEvaluator, srcLeftTuples, tempLeftTuples); } - if (!accNode.isRightInputIsRiaNode()) { + if (!accNode.getRightInput().inputIsTupleToObjectNode()) { // Non subnetworks ore process right then left. This because it's typically faster to ensure all RightTuples // are in place then you can iterate with the left evaluation cached. if (srcRightTuples.getInsertFirst() != null) { @@ -156,7 +156,7 @@ private void doLeftInserts(AccumulateNode accNode, } BaseAccumulation accresult = initAccumulationContext( am, reteEvaluator, accumulate, leftTuple ); - if (accNode.isRightInputIsRiaNode()) { + if (accNode.getRightInput().inputIsTupleToObjectNode()) { // This is a subnetwork, do not process further. As all matches will processed // by the right insert. This is to avoid double iteration (first right side iteration // then left side iteration) or for the join to find matching tuple chains, which it previously @@ -236,12 +236,12 @@ private void doRightInserts(AccumulateNode accNode, TupleImpl next = rightTuple.getStagedNext(); boolean useTupleMemory = tupleMemoryEnabled || RuleNetworkEvaluator.useLeftMemory(accNode, rightTuple); - if (useTupleMemory || !accNode.isRightInputIsRiaNode()) { + if (useTupleMemory || !accNode.getRightInput().inputIsTupleToObjectNode()) { // If tuple memory is off, it will still be when it is not a subnetwork. rtm.add(rightTuple); } - if (accNode.isRightInputIsRiaNode() || (ltm != null && ltm.size() > 0)) { + if (accNode.getRightInput().inputIsTupleToObjectNode() || (ltm != null && ltm.size() > 0)) { constraints.updateFromFactHandle( contextEntry, reteEvaluator, rightTuple.getFactHandleForEvaluation() ); @@ -284,7 +284,7 @@ private void doLeftUpdates(AccumulateNode accNode, TupleImpl next = leftTuple.getStagedNext(); BaseAccumulation accctx = (BaseAccumulation) leftTuple.getContextObject(); - if (accNode.isRightInputIsRiaNode()) { + if (accNode.getRightInput().inputIsTupleToObjectNode()) { // This is a subnetwork, do not process further. As all matches will processed // by the right updates. This is to avoid double iteration (first right side iteration // then left side iteration) or for the join to find matching tuple chains, which it previously @@ -718,7 +718,7 @@ private void addMatch(final AccumulateNode accNode, TupleImpl tuple = leftTuple; InternalFactHandle handle = rightTuple.getFactHandle(); - if (accNode.isRightInputIsRiaNode()) { + if (accNode.getRightInput().inputIsTupleToObjectNode()) { // if there is a subnetwork, handle must be unwrapped tuple = rightTuple; handle = rightTuple.getFactHandleForEvaluation(); @@ -773,7 +773,7 @@ private boolean removeMatch(final AccumulateNode accNode, // if there is a subnetwork, we need to unwrap the object from inside the tuple FactHandle handle = rightTuple.getFactHandle(); TupleImpl tuple = leftParent; - if (accNode.isRightInputIsRiaNode()) { + if (accNode.getRightInput().inputIsTupleToObjectNode()) { tuple = rightTuple; handle = rightTuple.getFactHandleForEvaluation(); } @@ -817,7 +817,7 @@ protected void reaccumulateForLeftTuple(final AccumulateNode accNode, TupleImpl rightTuple = childMatch.getRightParent(); FactHandle childHandle = rightTuple.getFactHandle(); TupleImpl tuple = leftParent; - if (accNode.isRightInputIsRiaNode()) { + if (accNode.getRightInput().inputIsTupleToObjectNode()) { // if there is a subnetwork, handle must be unwrapped tuple = rightTuple; childHandle = rightTuple.getFactHandleForEvaluation(); diff --git a/drools-core/src/main/java/org/drools/core/phreak/PhreakExistsNode.java b/drools-core/src/main/java/org/drools/core/phreak/PhreakExistsNode.java index bc66defa8e1..7cf6734b428 100644 --- a/drools-core/src/main/java/org/drools/core/phreak/PhreakExistsNode.java +++ b/drools-core/src/main/java/org/drools/core/phreak/PhreakExistsNode.java @@ -42,7 +42,7 @@ public void doNode(ExistsNode existsNode, TupleSets srcLeftTuples, TupleSets trgLeftTuples, TupleSets stagedLeftTuples) { - if (!existsNode.isRightInputIsRiaNode()) { + if (!existsNode.getRightInput().inputIsTupleToObjectNode()) { doNormalNode(existsNode, sink, bm, reteEvaluator, srcLeftTuples, trgLeftTuples, stagedLeftTuples); } else { PhreakSubnetworkNotExistsNode.doSubNetworkNode(existsNode, sink, bm, diff --git a/drools-core/src/main/java/org/drools/core/phreak/PhreakGroupByNode.java b/drools-core/src/main/java/org/drools/core/phreak/PhreakGroupByNode.java index 8a329ac24cf..94db4c87cf3 100644 --- a/drools-core/src/main/java/org/drools/core/phreak/PhreakGroupByNode.java +++ b/drools-core/src/main/java/org/drools/core/phreak/PhreakGroupByNode.java @@ -108,7 +108,7 @@ protected void reaccumulateForLeftTuple(final AccumulateNode accNode, TupleImpl rightTuple = childMatch.getRightParent(); FactHandle childHandle = rightTuple.getFactHandle(); TupleImpl tuple = leftTuple; - if (accNode.isRightInputIsRiaNode()) { + if (accNode.getRightInput().inputIsTupleToObjectNode()) { // if there is a subnetwork, handle must be unwrapped tuple = rightTuple; childHandle = rightTuple.getFactHandleForEvaluation(); diff --git a/drools-core/src/main/java/org/drools/core/phreak/PhreakNotNode.java b/drools-core/src/main/java/org/drools/core/phreak/PhreakNotNode.java index 3cb56b6e013..f8eb034df20 100644 --- a/drools-core/src/main/java/org/drools/core/phreak/PhreakNotNode.java +++ b/drools-core/src/main/java/org/drools/core/phreak/PhreakNotNode.java @@ -43,7 +43,7 @@ public void doNode(NotNode notNode, TupleSets trgLeftTuples, TupleSets stagedLeftTuples) { - if (!notNode.isRightInputIsRiaNode()) { + if (!notNode.getRightInput().inputIsTupleToObjectNode()) { doNormalNode(notNode, sink, bm, reteEvaluator, srcLeftTuples, trgLeftTuples, stagedLeftTuples); } else { PhreakSubnetworkNotExistsNode.doSubNetworkNode(notNode, sink, bm, diff --git a/drools-core/src/main/java/org/drools/core/phreak/RuleNetworkEvaluator.java b/drools-core/src/main/java/org/drools/core/phreak/RuleNetworkEvaluator.java index eef6b8ad1b8..9d17b80cdb6 100644 --- a/drools-core/src/main/java/org/drools/core/phreak/RuleNetworkEvaluator.java +++ b/drools-core/src/main/java/org/drools/core/phreak/RuleNetworkEvaluator.java @@ -30,6 +30,7 @@ import org.drools.core.common.TupleSets; import org.drools.core.common.TupleSetsImpl; import org.drools.core.reteoo.AbstractTerminalNode; +import org.drools.core.reteoo.RightInputAdapterNode; import org.drools.core.reteoo.TupleFactory; import org.drools.core.reteoo.TupleImpl; import org.drools.core.reteoo.AccumulateNode; @@ -61,8 +62,8 @@ import org.drools.core.reteoo.QueryElementNode.QueryElementNodeMemory; import org.drools.core.reteoo.QueryTerminalNode; import org.drools.core.reteoo.ReactiveFromNode; -import org.drools.core.reteoo.RightInputAdapterNode; -import org.drools.core.reteoo.RightInputAdapterNode.RiaPathMemory; +import org.drools.core.reteoo.TupleToObjectNode; +import org.drools.core.reteoo.TupleToObjectNode.SubnetworkPathMemory; import org.drools.core.reteoo.RightTuple; import org.drools.core.reteoo.SegmentMemory; import org.drools.core.reteoo.SubnetworkTuple; @@ -162,8 +163,8 @@ public static int getOffset(NetworkNode node) { if (NodeTypeEnums.isTerminalNode(node)) { lt = ((TerminalNode) node).getLeftTupleSource(); offset++; - } else if (node.getType() == NodeTypeEnums.RightInputAdapterNode) { - lt = ((RightInputAdapterNode) node).getLeftTupleSource(); + } else if (node.getType() == NodeTypeEnums.TupleToObjectNode) { + lt = ((TupleToObjectNode) node).getLeftTupleSource(); } else { lt = (LeftTupleSource) node; } @@ -184,9 +185,9 @@ public void outerEval(PathMemory pmem, TupleSets trgTuples, ActivationsManager activationsManager, LinkedList stack, - boolean processRian, + boolean processSubnetwork, RuleExecutor executor) { - innerEval(pmem, node, bit, nodeMem, smems, smemIndex, trgTuples, activationsManager, stack, processRian, executor); + innerEval(pmem, node, bit, nodeMem, smems, smemIndex, trgTuples, activationsManager, stack, processSubnetwork, executor); while (true) { // eval if (!stack.isEmpty()) { @@ -214,7 +215,7 @@ public void evalStackEntry(StackEntry entry, LinkedList stack, RuleE SegmentMemory[] smems = entry.getSmems(); int smemIndex = entry.getSmemIndex(); - boolean processRian = entry.isProcessRian(); + boolean processSubnetwork = entry.isProcessSubnetwork(); long bit = entry.getBit(); if (entry.isResumeFromNextNode()) { @@ -248,7 +249,7 @@ public void evalStackEntry(StackEntry entry, LinkedList stack, RuleE int offset = getOffset(node); log.trace("{} Resume {} {}", indent(offset), node.toString(), trgTuples.toStringSizes()); } - innerEval(pmem, node, bit, nodeMem, smems, smemIndex, trgTuples, activationsManager, stack, processRian, executor); + innerEval(pmem, node, bit, nodeMem, smems, smemIndex, trgTuples, activationsManager, stack, processSubnetwork, executor); } public void innerEval(PathMemory pmem, @@ -260,7 +261,7 @@ public void innerEval(PathMemory pmem, TupleSets trgTuples, ActivationsManager activationsManager, LinkedList stack, - boolean processRian, + boolean processSubnetwork, RuleExecutor executor) { TupleSets srcTuples; SegmentMemory smem = smems[smemIndex]; @@ -273,8 +274,8 @@ public void innerEval(PathMemory pmem, } boolean emptySrcTuples = srcTuples.isEmpty(); - if ( !(NodeTypeEnums.isBetaNode(node) && ((BetaNode)node).isRightInputIsRiaNode() ) ) { - // The engine cannot skip a ria node, as the dirty might be several levels deep + if ( !(NodeTypeEnums.isBetaNodeWithSubnetwork(node)) ) { + // The engine cannot skip a TupleToObjectNode node, as the dirty might be several levels deep if ( emptySrcTuples && smem.getDirtyNodeMask() == 0) { // empty sources and segment is not dirty, skip to non empty src tuples or dirty segment. boolean foundDirty = false; @@ -298,7 +299,7 @@ public void innerEval(PathMemory pmem, nodeMem = smem.getNodeMemories()[0]; if ( !emptySrcTuples || smem.getDirtyNodeMask() != 0 || - (NodeTypeEnums.isBetaNode(node) && ((BetaNode)node).isRightInputIsRiaNode() )) { + (NodeTypeEnums.isBetaNode(node) && ((BetaNode)node).getRightInput().inputIsTupleToObjectNode() )) { // break if dirty or if we reach a subnetwork. It must break for subnetworks, so they can be searched. foundDirty = true; smemIndex = i; @@ -318,7 +319,8 @@ public void innerEval(PathMemory pmem, long dirtyMask = smem.getDirtyNodeMask(); if ( emptySrcTuples ) { - while ((dirtyMask & bit) == 0 && node != smem.getTipNode() && !(NodeTypeEnums.isBetaNode(node) && ((BetaNode)node).isRightInputIsRiaNode() ) ) { + while ((dirtyMask & bit) == 0 && node != smem.getTipNode() && !NodeTypeEnums.isBetaNodeWithSubnetwork(node) ) { + //while ((dirtyMask & bit) == 0 && node != smem.getTipNode() && NodeTypeEnums.isBetaNodeWithoutSubnetwork(node) ) { if (log.isTraceEnabled()) { int offset = getOffset(node); log.trace("{} Skip Node {}", indent(offset), node); @@ -337,8 +339,8 @@ public void innerEval(PathMemory pmem, case NodeTypeEnums.QueryTerminalNode: pQtNode.doNode((QueryTerminalNode) node, activationsManager, srcTuples, stack); break; - case NodeTypeEnums.RightInputAdapterNode: - doRiaNode2(activationsManager.getReteEvaluator(), srcTuples, (RightInputAdapterNode) node); + case NodeTypeEnums.TupleToObjectNode: + doSubnetwork2(activationsManager.getReteEvaluator(), srcTuples, (TupleToObjectNode) node); break; default: terminalNode = false; @@ -350,7 +352,7 @@ public void innerEval(PathMemory pmem, stagedLeftTuples = getTargetStagedLeftTuples(node, activationsManager.getReteEvaluator(), smem); LeftTupleSinkNode sink = ((LeftTupleSource) node).getSinkPropagator().getFirstLeftTupleSink(); - trgTuples = evalNode( pmem, node, bit, nodeMem, smems, smemIndex, activationsManager, stack, processRian, executor, srcTuples, smem, stagedLeftTuples, sink ); + trgTuples = evalNode( pmem, node, bit, nodeMem, smems, smemIndex, activationsManager, stack, processSubnetwork, executor, srcTuples, smem, stagedLeftTuples, sink ); if ( trgTuples == null ) { break; // Queries exists and has been placed StackEntry, and there are no current trgTuples to process } @@ -376,7 +378,7 @@ public void innerEval(PathMemory pmem, node = smem.getRootNode(); nodeMem = smem.getNodeMemories()[0]; } - processRian = true; // make sure it's reset, so ria nodes are processed + processSubnetwork = true; // make sure it's reset, so ria nodes are processed } if ( stagedLeftTuples != null && !stagedLeftTuples.isEmpty() ) { @@ -386,11 +388,11 @@ public void innerEval(PathMemory pmem, public TupleSets evalNode(PathMemory pmem, NetworkNode node, long bit, Memory nodeMem, SegmentMemory[] smems, int smemIndex, ActivationsManager activationsManager, LinkedList stack, - boolean processRian, RuleExecutor executor, TupleSets srcTuples, SegmentMemory smem, + boolean processSubnetwork, RuleExecutor executor, TupleSets srcTuples, SegmentMemory smem, TupleSets stagedLeftTuples, LeftTupleSinkNode sink ) { TupleSets trgTuples = new TupleSetsImpl(); if ( NodeTypeEnums.isBetaNode( node )) { - boolean exitInnerEval = evalBetaNode(pmem, node, nodeMem, smems, smemIndex, trgTuples, activationsManager, stack, processRian, executor, srcTuples, stagedLeftTuples, sink); + boolean exitInnerEval = evalBetaNode(pmem, node, nodeMem, smems, smemIndex, trgTuples, activationsManager, stack, processSubnetwork, executor, srcTuples, stagedLeftTuples, sink); if ( exitInnerEval ) { return null; } @@ -543,7 +545,7 @@ private boolean evalQueryNode(PathMemory pmem, private boolean evalBetaNode(PathMemory pmem, NetworkNode node, Memory nodeMem, SegmentMemory[] smems, int smemIndex, TupleSets trgTuples, ActivationsManager activationsManager, - LinkedList stack, boolean processRian, RuleExecutor executor, + LinkedList stack, boolean processSubnetwork, RuleExecutor executor, TupleSets srcTuples, TupleSets stagedLeftTuples, LeftTupleSinkNode sink) { BetaNode betaNode = (BetaNode) node; BetaMemory bm; @@ -555,12 +557,12 @@ private boolean evalBetaNode(PathMemory pmem, NetworkNode node, Memory nodeMem, bm = (BetaMemory) nodeMem; } - if (processRian && betaNode.isRightInputIsRiaNode()) { + if (processSubnetwork && betaNode.getRightInput().inputIsTupleToObjectNode()) { // if the subnetwork is nested in this segment, it will create srcTuples containing // peer LeftTuples, suitable for the node in the main path. - doRiaNode( activationsManager, pmem, srcTuples, - betaNode, sink, smems, smemIndex, nodeMem, bm, stack, executor ); - return true; // return here, doRiaNode queues the evaluation on the stack, which is necessary to handled nested query nodes + doSubnetwork(activationsManager, pmem, srcTuples, + betaNode, sink, smems, smemIndex, nodeMem, bm, stack, executor); + return true; // return here, TupleToObjectNode queues the evaluation on the stack, which is necessary to handled nested query nodes } switchOnDoBetaNode(node, trgTuples, activationsManager.getReteEvaluator(), srcTuples, stagedLeftTuples, sink, bm, am); @@ -603,19 +605,19 @@ private void switchOnDoBetaNode(NetworkNode node, TupleSets trgTuples, ReteEvalu } } - private void doRiaNode(ActivationsManager activationsManager, - PathMemory pmem, - TupleSets srcTuples, - BetaNode betaNode, - LeftTupleSinkNode sink, - SegmentMemory[] smems, - int smemIndex, - Memory nodeMem, - BetaMemory bm, - LinkedList stack, - RuleExecutor executor) { - RiaPathMemory pathMem = bm.getRiaRuleMemory(); - SegmentMemory[] subnetworkSmems = pathMem.getSegmentMemories(); + private void doSubnetwork(ActivationsManager activationsManager, + PathMemory pmem, + TupleSets srcTuples, + BetaNode betaNode, + LeftTupleSinkNode sink, + SegmentMemory[] smems, + int smemIndex, + Memory nodeMem, + BetaMemory bm, + LinkedList stack, + RuleExecutor executor) { + SubnetworkPathMemory pathMem = bm.getSubnetworkPathMemory(); + SegmentMemory[] subnetworkSmems = pathMem.getSegmentMemories(); SegmentMemory subSmem = null; for ( int i = 0; subSmem == null; i++) { // segment positions outside of the subnetwork, in the parent chain, are null @@ -623,13 +625,13 @@ private void doRiaNode(ActivationsManager activationsManager, subSmem = subnetworkSmems[i]; } - // Resume the node after the riaNode segment has been processed and the right input memory populated + // Resume the node after the TupleToObjectNode segment has been processed and the right input memory populated StackEntry stackEntry = new StackEntry(betaNode, bm.getNodePosMaskBit(), sink, pmem, nodeMem, smems, smemIndex, srcTuples, false, false); stack.add(stackEntry); if (log.isTraceEnabled()) { int offset = getOffset(betaNode); - log.trace("{} RiaQueue {} {}", indent(offset), betaNode.toString(), srcTuples.toStringSizes()); + log.trace("{} SubnetworkQueue {} {}", indent(offset), betaNode.toString(), srcTuples.toStringSizes()); } @@ -641,13 +643,13 @@ private void doRiaNode(ActivationsManager activationsManager, subLts, activationsManager, stack, true, executor ); } - private void doRiaNode2(ReteEvaluator reteEvaluator, - TupleSets srcTuples, - RightInputAdapterNode riaNode) { + private void doSubnetwork2(ReteEvaluator reteEvaluator, + TupleSets srcTuples, + TupleToObjectNode tton) { - ObjectSink[] sinks = riaNode.getObjectSinkPropagator().getSinks(); + ObjectSink[] sinks = tton.getObjectSinkPropagator().getSinks(); - BetaNode betaNode = (BetaNode) sinks[0]; + BetaNode betaNode = ((RightInputAdapterNode)sinks[0]).getBetaNode(); BetaMemory bm; Memory nodeMem = reteEvaluator.getNodeMemory(betaNode); if (NodeTypeEnums.AccumulateNode == betaNode.getType()) { @@ -665,7 +667,7 @@ private void doRiaNode2(ReteEvaluator reteEvaluator, bns = new BetaNode[sinks.length - 1]; bms = new BetaMemory[sinks.length - 1]; for (int i = 1; i < length; i++) { - bns[i - 1] = (BetaNode) sinks[i]; + bns[i - 1] = ((RightInputAdapterNode)sinks[i]).getBetaNode(); Memory nodeMem2 = reteEvaluator.getNodeMemory(bns[i - 1]); if (NodeTypeEnums.AccumulateNode == betaNode.getType()) { bms[i - 1] = ((AccumulateMemory) nodeMem2).getBetaMemory(); @@ -691,7 +693,7 @@ private void doRiaNode2(ReteEvaluator reteEvaluator, if ( bms[i].getStagedRightTuples().isEmpty() ) { bms[i].setNodeDirtyWithoutNotify(); } - subnetworkTuple = (SubnetworkTuple) TupleFactory.createPeer(riaNode, + subnetworkTuple = (SubnetworkTuple) TupleFactory.createPeer(tton, subnetworkTuple); bms[i].getStagedRightTuples().addInsert(subnetworkTuple); } @@ -776,8 +778,8 @@ public static void findLeftTupleBlocker(BetaNode betaNode, TupleMemory rtm, if (useLeftMemory) { rightTuple.addBlocked((LeftTuple) leftTuple); break; - } else if (betaNode.isRightInputIsRiaNode()) { - // If we aren't using leftMemory and the right input is a RIAN, then we must iterate and find all subetwork right tuples and remove them + } else if (betaNode.getRightInput().inputIsTupleToObjectNode()) { + // If we aren't using leftMemory and the right input is a TupleToObjectNode, then we must iterate and find all subetwork right tuples and remove them // so we don't break rtm.remove(rightTuple); } else { diff --git a/drools-core/src/main/java/org/drools/core/phreak/RuntimeSegmentUtilities.java b/drools-core/src/main/java/org/drools/core/phreak/RuntimeSegmentUtilities.java index 5fdbc510809..43d7d4bdb37 100644 --- a/drools-core/src/main/java/org/drools/core/phreak/RuntimeSegmentUtilities.java +++ b/drools-core/src/main/java/org/drools/core/phreak/RuntimeSegmentUtilities.java @@ -36,7 +36,7 @@ import org.drools.core.reteoo.PathEndNode; import org.drools.core.reteoo.PathMemory; import org.drools.core.reteoo.QueryElementNode; -import org.drools.core.reteoo.RightInputAdapterNode; +import org.drools.core.reteoo.TupleToObjectNode; import org.drools.core.reteoo.SegmentMemory; import org.drools.core.reteoo.SegmentMemory.SegmentPrototype; @@ -65,8 +65,8 @@ public static SegmentMemory getOrCreateSegmentMemory(Memory memory, LeftTupleNod smem = restoreSegmentFromPrototype(reteEvaluator, segmentRoot); if ( smem != null ) { - if (NodeTypeEnums.isBetaNode(segmentRoot) && segmentRoot.isRightInputIsRiaNode()) { - createRiaSegmentMemory((BetaNode) segmentRoot, reteEvaluator); + if (NodeTypeEnums.isBetaNode(segmentRoot) && segmentRoot.inputIsTupleToObjectNode()) { + createSubnetworkSegmentMemory((BetaNode) segmentRoot, reteEvaluator); } return smem; } @@ -99,7 +99,7 @@ private static SegmentMemory restoreSegmentFromPrototype(ReteEvaluator reteEvalu SegmentMemory smem = reteEvaluator.getKnowledgeBase().createSegmentFromPrototype(reteEvaluator, proto); - updateRiaAndTerminalMemory(smem, proto, reteEvaluator); + updateSubnetworkAndTerminalMemory(smem, proto, reteEvaluator); return smem; } @@ -115,10 +115,10 @@ public static SegmentMemory getQuerySegmentMemory(ReteEvaluator reteEvaluator, Q return querySmem; } - static RightInputAdapterNode createRiaSegmentMemory( BetaNode betaNode, ReteEvaluator reteEvaluator ) { - RightInputAdapterNode riaNode = (RightInputAdapterNode) betaNode.getRightInput(); + static TupleToObjectNode createSubnetworkSegmentMemory(BetaNode betaNode, ReteEvaluator reteEvaluator) { + TupleToObjectNode tton = (TupleToObjectNode) betaNode.getRightInput().getParent(); - LeftTupleSource subnetworkLts = riaNode.getStartTupleSource(); + LeftTupleSource subnetworkLts = tton.getStartTupleSource(); Memory rootSubNetwokrMem = reteEvaluator.getNodeMemory( (MemoryFactory) subnetworkLts ); SegmentMemory subNetworkSegmentMemory = rootSubNetwokrMem.getSegmentMemory(); @@ -126,7 +126,7 @@ static RightInputAdapterNode createRiaSegmentMemory( BetaNode betaNode, ReteEval // we need to stop recursion here getOrCreateSegmentMemory(rootSubNetwokrMem, subnetworkLts, reteEvaluator); } - return riaNode; + return tton; } public static void createChildSegments(ReteEvaluator reteEvaluator, SegmentMemory smem, LeftTupleSinkPropagator sinkProp) { @@ -150,16 +150,16 @@ public static SegmentMemory createChildSegment(ReteEvaluator reteEvaluator, Left } /** - * This adds the segment memory to the terminal node or ria node's list of memories. + * This adds the segment memory to the terminal node or TupleToObjectNode node's list of memories. * In the case of the terminal node this allows it to know that all segments from * the tip to root are linked. - * In the case of the ria node its all the segments up to the start of the subnetwork. - * This is because the rianode only cares if all of it's segments are linked, then + * In the case of the TupleToObjectNode node its all the segments up to the start of the subnetwork. + * This is because the TupleToObjectNode only cares if all of it's segments are linked, then * it sets the bit of node it is the right input for. */ - private static void updateRiaAndTerminalMemory(SegmentMemory smem, - SegmentPrototype proto, - ReteEvaluator reteEvaluator) { + private static void updateSubnetworkAndTerminalMemory(SegmentMemory smem, + SegmentPrototype proto, + ReteEvaluator reteEvaluator) { for (PathEndNode endNode : proto.getPathEndNodes()) { if (!isInsideSubnetwork(endNode, proto)) { // While SegmentPrototypes are added for entire path, for traversal reasons. diff --git a/drools-core/src/main/java/org/drools/core/phreak/SegmentPropagator.java b/drools-core/src/main/java/org/drools/core/phreak/SegmentPropagator.java index 70779468ac0..d76960eeaeb 100644 --- a/drools-core/src/main/java/org/drools/core/phreak/SegmentPropagator.java +++ b/drools-core/src/main/java/org/drools/core/phreak/SegmentPropagator.java @@ -32,7 +32,7 @@ import static org.drools.base.reteoo.NodeTypeEnums.AccumulateNode; import static org.drools.core.phreak.TupleEvaluationUtil.forceFlushLeftTuple; -import static org.drools.core.phreak.TupleEvaluationUtil.forceFlushWhenRiaNode; +import static org.drools.core.phreak.TupleEvaluationUtil.forceFlushWhenSubnetwork; public class SegmentPropagator { @@ -60,7 +60,7 @@ public static void propagate(SegmentMemory sourceSegment, TupleSets leftTuples, continue; } forceFlushLeftTuple(dataDrivenPmem, smem, reteEvaluator, smem.getStagedLeftTuples()); - forceFlushWhenRiaNode(reteEvaluator, dataDrivenPmem); + forceFlushWhenSubnetwork(reteEvaluator, dataDrivenPmem); } } } diff --git a/drools-core/src/main/java/org/drools/core/phreak/StackEntry.java b/drools-core/src/main/java/org/drools/core/phreak/StackEntry.java index bf1a2c8a5f9..8bfc4a1a680 100644 --- a/drools-core/src/main/java/org/drools/core/phreak/StackEntry.java +++ b/drools-core/src/main/java/org/drools/core/phreak/StackEntry.java @@ -42,8 +42,8 @@ public class StackEntry extends AbstractLinkedListNode { private final SegmentMemory[] smems; private final int smemIndex; private final TupleSets trgTuples; - private final boolean resumeFromNextNode; - private final boolean processRian; + private final boolean resumeFromNextNode; + private final boolean processSubnetwork; public StackEntry(NetworkNode node, @@ -55,17 +55,17 @@ public StackEntry(NetworkNode node, int smemIndex, TupleSets trgTuples, boolean resumeFromNextNode, - boolean processRian) { - this.bit = bit; - this.node = node; - this.sink = sink; - this.pmem = pmem; - this.nodeMem = nodeMem; - this.smems = smems; - this.smemIndex = smemIndex; - this.trgTuples = trgTuples; + boolean processSubnetwork) { + this.bit = bit; + this.node = node; + this.sink = sink; + this.pmem = pmem; + this.nodeMem = nodeMem; + this.smems = smems; + this.smemIndex = smemIndex; + this.trgTuples = trgTuples; this.resumeFromNextNode = resumeFromNextNode; - this.processRian = processRian; + this.processSubnetwork = processSubnetwork; } public long getBit() { @@ -105,7 +105,7 @@ public boolean isResumeFromNextNode() { } - public boolean isProcessRian() { - return processRian; + public boolean isProcessSubnetwork() { + return processSubnetwork; } } diff --git a/drools-core/src/main/java/org/drools/core/phreak/TupleEvaluationUtil.java b/drools-core/src/main/java/org/drools/core/phreak/TupleEvaluationUtil.java index 2fe3820f41f..9bb89fd6fe7 100644 --- a/drools-core/src/main/java/org/drools/core/phreak/TupleEvaluationUtil.java +++ b/drools-core/src/main/java/org/drools/core/phreak/TupleEvaluationUtil.java @@ -34,7 +34,6 @@ import org.drools.core.reteoo.PathEndNode; import org.drools.core.reteoo.PathMemory; import org.drools.core.reteoo.SegmentMemory; -import org.drools.core.reteoo.TerminalNode; import org.drools.core.reteoo.Tuple; import org.drools.core.util.LinkedList; @@ -51,7 +50,7 @@ public static boolean flushLeftTupleIfNecessary(ReteEvaluator reteEvaluator, Seg } forceFlushLeftTuple( pmem, sm, reteEvaluator, createLeftTupleTupleSets(leftTuple, stagedType) ); - forceFlushWhenRiaNode(reteEvaluator, pmem); + forceFlushWhenSubnetwork(reteEvaluator, pmem); return true; } @@ -78,15 +77,15 @@ public static TupleSets createLeftTupleTupleSets(TupleImpl leftTuple, short stag return leftTupleSets; } - public static void forceFlushWhenRiaNode(ReteEvaluator reteEvaluator, PathMemory pmem) { - for (PathMemory outPmem : findPathsToFlushFromRia(reteEvaluator, pmem)) { + public static void forceFlushWhenSubnetwork(ReteEvaluator reteEvaluator, PathMemory pmem) { + for (PathMemory outPmem : findPathsToFlushFromSubnetwork(reteEvaluator, pmem)) { forceFlushPath(reteEvaluator, outPmem); } } - public static List findPathsToFlushFromRia(ReteEvaluator reteEvaluator, PathMemory pmem) { + public static List findPathsToFlushFromSubnetwork(ReteEvaluator reteEvaluator, PathMemory pmem) { List paths = null; - if (pmem.isDataDriven() && pmem.getNodeType() == NodeTypeEnums.RightInputAdapterNode) { + if (pmem.isDataDriven() && pmem.getNodeType() == NodeTypeEnums.TupleToObjectNode) { for (PathEndNode pnode : pmem.getPathEndNode().getPathEndNodes()) { if ( NodeTypeEnums.isTerminalNode(pnode)) { PathMemory outPmem = reteEvaluator.getNodeMemory(pnode); diff --git a/drools-core/src/main/java/org/drools/core/reteoo/AbstractTerminalNode.java b/drools-core/src/main/java/org/drools/core/reteoo/AbstractTerminalNode.java index d510f41fcb5..43c5e2c7544 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/AbstractTerminalNode.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/AbstractTerminalNode.java @@ -114,6 +114,11 @@ public PathMemSpec getPathMemSpec() { return getPathMemSpec(null); } + @Override + public BaseNode getParent() { + return tupleSource; + } + @Override public void setPathMemSpec(PathMemSpec pathMemSpec) { this.pathMemSpec = pathMemSpec; @@ -130,7 +135,7 @@ public PathMemSpec getPathMemSpec(TerminalNode removingTN) { @Override public void resetPathMemSpec(TerminalNode removingTN) { // null all PathMemSpecs, for all pathEnds, or the recursion will use a previous value. - // calling calculatePathMemSpec, will eventually getPathMemSpec on all nested rians, so previous values must be nulled + // calling calculatePathMemSpec, will eventually getPathMemSpec on all nested ttons, so previous values must be nulled Arrays.stream(pathEndNodes).forEach( n -> { n.nullPathMemSpec(); n.setSegmentPrototypes(null); @@ -212,7 +217,7 @@ public void setObjectCount(int count) { protected void initDeclaredMask(BuildContext context) { if ( !(NodeTypeEnums.isLeftInputAdapterNode(unwrapTupleSource()))) { // RTN's not after LIANode are not relevant for property specific, so don't block anything. - setDeclaredMask( AllSetBitMask.get() ); + declaredMask = AllSetBitMask.get(); return; } @@ -221,11 +226,11 @@ protected void initDeclaredMask(BuildContext context) { if ( isPropertyReactive(context.getRuleBase(), objectType) ) { List accessibleProperties = pattern.getAccessibleProperties( context.getRuleBase() ); - setDeclaredMask( pattern.getPositiveWatchMask(accessibleProperties) ); - setNegativeMask( pattern.getNegativeWatchMask(accessibleProperties) ); + declaredMask = pattern.getPositiveWatchMask(accessibleProperties); + negativeMask = pattern.getNegativeWatchMask(accessibleProperties); } else { // if property specific is not on, then accept all modification propagations - setDeclaredMask( AllSetBitMask.get() ); + declaredMask = AllSetBitMask.get(); } } @@ -234,14 +239,14 @@ public void initInferredMask() { if ( NodeTypeEnums.isLeftInputAdapterNode(leftTupleSource) && ((LeftInputAdapterNode)leftTupleSource).getParentObjectSource().getType() == NodeTypeEnums.AlphaNode ) { AlphaNode alphaNode = (AlphaNode) ((LeftInputAdapterNode)leftTupleSource).getParentObjectSource(); - setInferredMask( alphaNode.updateMask( getDeclaredMask() ) ); + inferredMask = alphaNode.updateMask( getDeclaredMask() ); } else { - setInferredMask( getDeclaredMask() ); + inferredMask = getDeclaredMask(); } - setInferredMask( getInferredMask().resetAll( getNegativeMask() ) ); + inferredMask = getInferredMask().resetAll( getNegativeMask() ); if ( getNegativeMask().isAllSet() && !getDeclaredMask().isAllSet() ) { - setInferredMask( getInferredMask().setAll( getDeclaredMask() ) ); + inferredMask = getInferredMask().setAll( getDeclaredMask() ); } } @@ -278,27 +283,11 @@ public BitMask getDeclaredMask() { public BitMask getInferredMask() { return inferredMask; } - - public BitMask getLeftInferredMask() { - return inferredMask; - } - - public void setDeclaredMask(BitMask mask) { - declaredMask = mask; - } - - public void setInferredMask(BitMask mask) { - inferredMask = mask; - } public BitMask getNegativeMask() { return negativeMask; } - public void setNegativeMask(BitMask mask) { - negativeMask = mask; - } - public void networkUpdated(UpdateContext updateContext) { getLeftTupleSource().networkUpdated(updateContext); } diff --git a/drools-core/src/main/java/org/drools/core/reteoo/AccumulateNode.java b/drools-core/src/main/java/org/drools/core/reteoo/AccumulateNode.java index 2ff681e4f66..28b829aab90 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/AccumulateNode.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/AccumulateNode.java @@ -69,7 +69,7 @@ public AccumulateNode() { public AccumulateNode(final int id, final LeftTupleSource leftInput, - final ObjectSource rightInput, + final RightInputAdapterNode rightInput, final AlphaNodeFieldConstraint[] resultConstraints, final BetaConstraints sourceBinder, final BetaConstraints resultBinder, @@ -98,7 +98,7 @@ public AccumulateNode(final int id, } private void addAccFunctionDeclarationsToLeftMask(InternalRuleBase ruleBase, LeftTupleSource leftInput, Accumulate accumulate) { - BitMask leftMask = getLeftInferredMask(); + BitMask leftMask = getInferredMask(); ObjectType leftObjectType = leftInput.getObjectType(); if (leftObjectType instanceof ClassObjectType ) { TypeDeclaration typeDeclaration = ruleBase.getExactTypeDeclaration(((ClassObjectType) leftObjectType).getClassType() ); @@ -111,12 +111,12 @@ private void addAccFunctionDeclarationsToLeftMask(InternalRuleBase ruleBase, Lef } } } - setLeftInferredMask( leftMask ); + setInferredMask(leftMask); } @Override protected ObjectType getObjectTypeForPropertyReactivity( LeftInputAdapterNode leftInput, Pattern pattern ) { - return pattern != null && isRightInputIsRiaNode() ? + return pattern != null && rightInput.inputIsTupleToObjectNode() ? pattern.getObjectType() : leftInput.getParentObjectSource().getObjectTypeNode().getObjectType(); } @@ -173,7 +173,7 @@ public boolean equals( final Object object ) { } AccumulateNode other = (AccumulateNode) object; - return this.leftInput.getId() == other.leftInput.getId() && this.rightInput.getId() == other.rightInput.getId() && + return this.leftInput.getId() == other.leftInput.getId() && this.rightInput.equals(other.rightInput)&& this.constraints.equals( other.constraints ) && this.accumulate.equals( other.accumulate ) && this.resultBinder.equals( other.resultBinder ) && @@ -369,35 +369,4 @@ public void clear() { lastTupleList = null; } } - - /** - * @inheritDoc - * - * If an object is retract, call modify tuple for each - * tuple match. - */ - public void retractRightTuple( final TupleImpl rightTuple, - final PropagationContext pctx, - final ReteEvaluator reteEvaluator ) { - final AccumulateMemory memory = (AccumulateMemory) reteEvaluator.getNodeMemory( this ); - - BetaMemory bm = memory.getBetaMemory(); - rightTuple.setPropagationContext( pctx ); - doDeleteRightTuple( rightTuple, reteEvaluator, bm ); - } - - @Override - public void modifyRightTuple(TupleImpl rightTuple, PropagationContext context, ReteEvaluator reteEvaluator) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean doRemove(RuleRemovalContext context, ReteooBuilder builder) { - if ( !isInUse() ) { - getLeftTupleSource().removeTupleSink( this ); - getRightInput().removeObjectSink( this ); - return true; - } - return false; - } } diff --git a/drools-core/src/main/java/org/drools/core/reteoo/AccumulateRight.java b/drools-core/src/main/java/org/drools/core/reteoo/AccumulateRight.java new file mode 100644 index 00000000000..ece549033be --- /dev/null +++ b/drools-core/src/main/java/org/drools/core/reteoo/AccumulateRight.java @@ -0,0 +1,42 @@ +package org.drools.core.reteoo; + +import org.drools.base.reteoo.NodeTypeEnums; +import org.drools.core.common.PropagationContext; +import org.drools.core.common.ReteEvaluator; +import org.drools.core.reteoo.AccumulateNode.AccumulateMemory; +import org.drools.core.reteoo.builder.BuildContext; + +public class AccumulateRight extends RightInputAdapterNode { + + public AccumulateRight(int id, ObjectSource rightInput, BuildContext context) { + super(id, rightInput, context); + } + + + /** + * @inheritDoc + * + * If an object is retract, call modify tuple for each + * tuple match. + */ + @Override + public void retractRightTuple( final TupleImpl rightTuple, + final PropagationContext pctx, + final ReteEvaluator reteEvaluator) { + final AccumulateMemory memory = (AccumulateMemory) reteEvaluator.getNodeMemory(betaNode); + + BetaMemory bm = memory.getBetaMemory(); + rightTuple.setPropagationContext( pctx ); + doDeleteRightTuple( rightTuple, reteEvaluator, bm ); + } + + @Override + public void modifyRightTuple(TupleImpl rightTuple, PropagationContext context, ReteEvaluator reteEvaluator) { + throw new UnsupportedOperationException(); + } + + @Override + public int getType() { + return NodeTypeEnums.AccumulateRightAdapterNode; + } +} diff --git a/drools-core/src/main/java/org/drools/core/reteoo/AlphaNode.java b/drools-core/src/main/java/org/drools/core/reteoo/AlphaNode.java index 9214e71e3bf..adb450556b7 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/AlphaNode.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/AlphaNode.java @@ -287,12 +287,12 @@ public boolean isAssociatedWith(Rule rule) { @Override public void addAssociatedTerminal(BaseTerminalNode terminalNode) { - sink.addAssociatedTerminal(terminalNode); + throw new UnsupportedOperationException(); } @Override public void removeAssociatedTerminal(BaseTerminalNode terminalNode) { - sink.removeAssociatedTerminal(terminalNode); + throw new UnsupportedOperationException(); } @Override diff --git a/drools-core/src/main/java/org/drools/core/reteoo/AlphaTerminalNode.java b/drools-core/src/main/java/org/drools/core/reteoo/AlphaTerminalNode.java index 66b53817c0e..99d6107c8c0 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/AlphaTerminalNode.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/AlphaTerminalNode.java @@ -64,9 +64,9 @@ public void modifyObject(InternalFactHandle factHandle, ModifyPreviousTuples mod NetworkNode[] sinks = getSinks(); for (int i = 0; i < sinks.length; i++) { - TerminalNode rtn = ( TerminalNode ) sinks[i]; - ObjectTypeNodeId otnId = rtn.getLeftInputOtnId(); - TupleImpl leftTuple = processDeletesFromModify(modifyPreviousTuples, context, reteEvaluator, otnId); + TerminalNode rtn = ( TerminalNode ) sinks[i]; + ObjectTypeNodeId otnId = rtn.getInputOtnId(); + TupleImpl leftTuple = processDeletesFromModify(modifyPreviousTuples, context, reteEvaluator, otnId); RuleAgendaItem agendaItem = getRuleAgendaItem( reteEvaluator, activationsManager, rtn, true ); RuleExecutor executor = agendaItem.getRuleExecutor(); @@ -74,7 +74,7 @@ public void modifyObject(InternalFactHandle factHandle, ModifyPreviousTuples mod if ( leftTuple != null && leftTuple.getInputOtnId().equals(otnId) ) { modifyPreviousTuples.removeLeftTuple(partitionId); leftTuple.reAdd(); - if ( context.getModificationMask().intersects( rtn.getLeftInferredMask() ) ) { + if ( context.getModificationMask().intersects( rtn.getInferredMask()) ) { leftTuple.setPropagationContext( context ); PhreakRuleTerminalNode.doLeftTupleUpdate( rtn, executor, activationsManager, (RuleTerminalNodeLeftTuple) leftTuple ); if (leftTuple.isFullMatch()) { @@ -82,7 +82,7 @@ public void modifyObject(InternalFactHandle factHandle, ModifyPreviousTuples mod } } } else { - if ( context.getModificationMask().intersects( rtn.getLeftInferredMask() ) ) { + if ( context.getModificationMask().intersects( rtn.getInferredMask()) ) { leftTuple = TupleFactory.createLeftTuple( rtn, factHandle, true ); leftTuple.setPropagationContext( context ); PhreakRuleTerminalNode.doLeftTupleInsert( rtn, executor, activationsManager, agendaItem, (RuleTerminalNodeLeftTuple) leftTuple ); diff --git a/drools-core/src/main/java/org/drools/core/reteoo/AsyncReceiveNode.java b/drools-core/src/main/java/org/drools/core/reteoo/AsyncReceiveNode.java index c224da685b5..f2b78bdc5d6 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/AsyncReceiveNode.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/AsyncReceiveNode.java @@ -81,7 +81,7 @@ public AsyncReceiveNode( final int id, this.betaConstraints = (binder == null) ? EmptyBetaConstraints.getInstance() : binder; this.betaConstraints.init(context, getType()); - initMasks( context, tupleSource ); + initMasks( context ); hashcode = calculateHashCode(); } diff --git a/drools-core/src/main/java/org/drools/core/reteoo/AsyncSendNode.java b/drools-core/src/main/java/org/drools/core/reteoo/AsyncSendNode.java index 1d1665a0a26..cd0e252dda5 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/AsyncSendNode.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/AsyncSendNode.java @@ -82,7 +82,7 @@ public AsyncSendNode( final int id, this.send = send; this.messageId = send.getMessageId(); - initMasks(context, tupleSource); + initMasks(context); hashcode = calculateHashCode(); } diff --git a/drools-core/src/main/java/org/drools/core/reteoo/BetaMemory.java b/drools-core/src/main/java/org/drools/core/reteoo/BetaMemory.java index fd83472bca7..cddd87111f6 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/BetaMemory.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/BetaMemory.java @@ -22,21 +22,21 @@ import org.drools.core.common.ReteEvaluator; import org.drools.core.common.TupleSets; import org.drools.core.common.TupleSetsImpl; -import org.drools.core.reteoo.RightInputAdapterNode.RiaPathMemory; +import org.drools.core.reteoo.TupleToObjectNode.SubnetworkPathMemory; import org.drools.core.util.AbstractLinkedListNode; public class BetaMemory extends AbstractLinkedListNode implements SegmentNodeMemory { private TupleMemory leftTupleMemory; private TupleMemory rightTupleMemory; - private TupleSets stagedRightTuples; - private C context; + private TupleSets stagedRightTuples; + private C context; // the node type this memory belongs to - private int nodeType; - private SegmentMemory segmentMemory; - private long nodePosMaskBit; - private int counter; - private RiaPathMemory riaRuleMemory; + private int nodeType; + private SegmentMemory segmentMemory; + private long nodePosMaskBit; + private int counter; + private SubnetworkPathMemory subnetworkPathMemory; public BetaMemory() { } @@ -68,12 +68,12 @@ public TupleMemory getLeftTupleMemory() { return this.leftTupleMemory; } - public RiaPathMemory getRiaRuleMemory() { - return riaRuleMemory; + public SubnetworkPathMemory getSubnetworkPathMemory() { + return subnetworkPathMemory; } - public void setRiaRuleMemory(RiaPathMemory riaRuleMemory) { - this.riaRuleMemory = riaRuleMemory; + public void setSubnetworkPathMemory(SubnetworkPathMemory subnetworkPathMemory) { + this.subnetworkPathMemory = subnetworkPathMemory; } /** diff --git a/drools-core/src/main/java/org/drools/core/reteoo/BetaNode.java b/drools-core/src/main/java/org/drools/core/reteoo/BetaNode.java index 357d7203501..f0be4ccae4f 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/BetaNode.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/BetaNode.java @@ -23,13 +23,11 @@ import java.util.List; import java.util.Objects; -import org.drools.base.base.ObjectType; import org.drools.base.common.NetworkNode; import org.drools.base.common.RuleBasePartitionId; import org.drools.base.reteoo.BaseTerminalNode; import org.drools.base.reteoo.NodeTypeEnums; import org.drools.base.rule.IndexableConstraint; -import org.drools.base.rule.Pattern; import org.drools.base.util.index.IndexUtil; import org.drools.core.RuleBaseConfiguration; import org.drools.core.common.BetaConstraints; @@ -47,66 +45,44 @@ import org.drools.core.common.SingleNonIndexSkipBetaConstraints; import org.drools.core.common.TripleBetaConstraints; import org.drools.core.common.TripleNonIndexSkipBetaConstraints; -import org.drools.core.common.TupleSets; import org.drools.core.common.UpdateContext; import org.drools.core.phreak.DetachedTuple; import org.drools.core.reteoo.AccumulateNode.AccumulateMemory; import org.drools.core.reteoo.builder.BuildContext; import org.drools.base.rule.constraint.BetaConstraint; import org.drools.core.util.FastIterator; -import org.drools.util.bitmask.AllSetBitMask; -import org.drools.util.bitmask.BitMask; -import org.drools.util.bitmask.EmptyBitMask; import org.kie.api.definition.rule.Rule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static org.drools.base.reteoo.PropertySpecificUtil.isPropertyReactive; -import static org.drools.core.phreak.RuleNetworkEvaluator.doUpdatesReorderChildLeftTuple; import static org.drools.core.phreak.TupleEvaluationUtil.flushLeftTupleIfNecessary; public abstract class BetaNode extends LeftTupleSource implements LeftTupleSinkNode, - ObjectSinkNode, - RightTupleSink, MemoryFactory { protected static final Logger log = LoggerFactory.getLogger(BetaNode.class); protected static final boolean isLogTraceEnabled = log.isTraceEnabled(); - protected ObjectSource rightInput; + protected RightInputAdapterNode rightInput; protected BetaConstraints constraints; private LeftTupleSinkNode previousTupleSinkNode; private LeftTupleSinkNode nextTupleSinkNode; - private ObjectSinkNode previousObjectSinkNode; - private ObjectSinkNode nextObjectSinkNode; - - private ObjectTypeNodeId rightInputOtnId = ObjectTypeNodeId.DEFAULT_ID; - protected boolean objectMemory = true; // hard coded to true protected boolean tupleMemoryEnabled; protected boolean indexedUnificationJoin; - private BitMask rightDeclaredMask = EmptyBitMask.get(); - private BitMask rightInferredMask = EmptyBitMask.get(); - private BitMask rightNegativeMask = EmptyBitMask.get(); - private Collection leftListenedProperties; - private Collection rightListenedProperties; - - protected boolean rightInputIsRiaNode; - private transient ObjectTypeNode objectTypeNode; + private boolean indexable; - private boolean rightInputIsPassive; - private boolean indexable; // ------------------------------------------------------------ // Constructors @@ -125,15 +101,14 @@ public BetaNode() { */ protected BetaNode(final int id, final LeftTupleSource leftInput, - final ObjectSource rightInput, + final RightInputAdapterNode rightInput, final BetaConstraints constraints, final BuildContext context) { super(id, context); + rightInput.setBetaNode(this); setLeftTupleSource(leftInput); this.rightInput = rightInput; - rightInputIsRiaNode = NodeTypeEnums.RightInputAdapterNode == rightInput.getType(); - setConstraints(constraints); if (this.constraints == null) { @@ -143,7 +118,7 @@ protected BetaNode(final int id, this.constraints.init(context, getType()); this.constraints.registerEvaluationContext(context); - initMasks(context, leftInput); + initMasks(context); setStreamMode( context.isStreamMode() && getObjectTypeNode(context).getObjectType().isEvent() ); @@ -159,44 +134,18 @@ private ObjectTypeNode getObjectTypeNode(BuildContext context) { } @Override - protected void initDeclaredMask(BuildContext context, - LeftTupleSource leftInput) { - if (context == null || context.getLastBuiltPatterns() == null) { - // only happens during unit tests - rightDeclaredMask = AllSetBitMask.get(); - super.initDeclaredMask(context, leftInput); - return; - } - - Pattern pattern = context.getLastBuiltPatterns()[0]; // right input pattern - rightInputIsPassive = pattern.isPassive(); - - if (!isRightInputIsRiaNode()) { - ObjectType objectType = pattern.getObjectType(); - - if (isPropertyReactive(context.getRuleBase(), objectType)) { - rightListenedProperties = pattern.getListenedProperties(); - List accessibleProperties = pattern.getAccessibleProperties( context.getRuleBase() ); - rightDeclaredMask = pattern.getPositiveWatchMask(accessibleProperties); - rightDeclaredMask = rightDeclaredMask.setAll(constraints.getListenedPropertyMask(pattern, objectType, accessibleProperties)); - rightNegativeMask = pattern.getNegativeWatchMask(accessibleProperties); - } else { - // if property reactive is not on, then accept all modification propagations - rightDeclaredMask = AllSetBitMask.get(); - } - } else { - rightDeclaredMask = AllSetBitMask.get(); - // There would have been no right input pattern, so swap current to first, so leftInput can still work - context.setLastBuiltPattern( context.getLastBuiltPatterns()[0] ); - } + protected void initDeclaredMask(BuildContext context) { + rightInput.initDeclaredMask(context); - super.initDeclaredMask(context, leftInput); + super.initDeclaredMask(context); } @Override public void setPartitionId(BuildContext context, RuleBasePartitionId partitionId ) { - if (rightInput.getPartitionId() != RuleBasePartitionId.MAIN_PARTITION && !rightInput.getPartitionId().equals( partitionId )) { - this.partitionId = rightInput.getPartitionId(); + RuleBasePartitionId parentId = rightInput.getParent().getPartitionId(); + if (parentId != RuleBasePartitionId.MAIN_PARTITION && !parentId.equals(partitionId)) { + this.partitionId = parentId; + rightInput.setPartitionId(context, this.partitionId); context.setPartitionId( this.partitionId ); leftInput.setSourcePartitionId( context, this.partitionId ); } else { @@ -209,26 +158,10 @@ protected void setLeftListenedProperties(Collection leftListenedProperti this.leftListenedProperties = leftListenedProperties; } - public void initInferredMask() { - initInferredMask(leftInput); - } - @Override - protected void initInferredMask(LeftTupleSource leftInput) { - super.initInferredMask( leftInput ); - - ObjectSource unwrappedRight = unwrapRightInput(); - if ( unwrappedRight.getType() == NodeTypeEnums.AlphaNode ) { - AlphaNode alphaNode = (AlphaNode) unwrappedRight; - rightInferredMask = alphaNode.updateMask( rightDeclaredMask ); - } else { - rightInferredMask = rightDeclaredMask; - } - rightInferredMask = rightInferredMask.resetAll(rightNegativeMask); - } - - public ObjectSource unwrapRightInput() { - return rightInput; + protected void initInferredMask() { + super.initInferredMask(); + rightInput.initInferredMask(); } private void setUnificationJoin() { @@ -253,127 +186,12 @@ private void setUnificationJoin() { } } - @Override - public void assertObject( InternalFactHandle factHandle, PropagationContext pctx, ReteEvaluator reteEvaluator ) { - final BetaMemory memory = (BetaMemory) getBetaMemoryFromRightInput(this, reteEvaluator); - - RightTuple rightTuple = createRightTuple(factHandle, this, pctx); - - boolean stagedInsertWasEmpty = memory.getStagedRightTuples().addInsert(rightTuple); - if ( isLogTraceEnabled ) { - log.trace("BetaNode stagedInsertWasEmpty={}", stagedInsertWasEmpty ); - } - - boolean shouldFlush = isStreamMode(); - if ( memory.getAndIncCounter() == 0 ) { - if ( stagedInsertWasEmpty ) { - memory.setNodeDirtyWithoutNotify(); - } - shouldFlush = memory.linkNode( this, reteEvaluator, !rightInputIsPassive ) | shouldFlush; - } else if ( stagedInsertWasEmpty ) { - shouldFlush = memory.setNodeDirty( this, reteEvaluator, !rightInputIsPassive ) | shouldFlush; - } - - if (shouldFlush) { - flushLeftTupleIfNecessary( reteEvaluator, memory.getOrCreateSegmentMemory( this, reteEvaluator ), isStreamMode() ); - } - } - - public void modifyObject(InternalFactHandle factHandle, ModifyPreviousTuples modifyPreviousTuples, PropagationContext context, ReteEvaluator reteEvaluator) { - TupleImpl rightTuple = modifyPreviousTuples.peekRightTuple(partitionId); - - // if the peek is for a different OTN we assume that it is after the current one and then this is an assert - while ( rightTuple != null && rightTuple.getInputOtnId().before(getRightInputOtnId()) ) { - modifyPreviousTuples.removeRightTuple(partitionId); - - // we skipped this node, due to alpha hashing, so retract now - rightTuple.setPropagationContext( context ); - BetaMemory bm = getBetaMemory(rightTuple.getSink(), reteEvaluator); - (( BetaNode ) rightTuple.getSink()).doDeleteRightTuple(rightTuple, reteEvaluator, bm); - rightTuple = modifyPreviousTuples.peekRightTuple(partitionId); - } - - if ( rightTuple != null && rightTuple.getInputOtnId().equals(getRightInputOtnId()) ) { - modifyPreviousTuples.removeRightTuple(partitionId); - rightTuple.reAdd(); - if ( context.getModificationMask().intersects(getRightInferredMask()) ) { - // RightTuple previously existed, so continue as modify - rightTuple.setPropagationContext( context ); // only update, if the mask intersects - - BetaMemory bm = getBetaMemory(this, reteEvaluator); - rightTuple.setPropagationContext( context ); - doUpdateRightTuple(rightTuple, reteEvaluator, bm); - } else if (rightTuple.getMemory() != null) { - reorderRightTuple(reteEvaluator, rightTuple); - } - } else { - if ( context.getModificationMask().intersects(getRightInferredMask()) ) { - // RightTuple does not exist for this node, so create and continue as assert - assertObject( factHandle, context, reteEvaluator ); - } - } - } - - protected void reorderRightTuple(ReteEvaluator reteEvaluator, TupleImpl rightTuple) { - getBetaMemory(this, reteEvaluator).getRightTupleMemory().removeAdd(rightTuple); - doUpdatesReorderChildLeftTuple(rightTuple); - } - - public void doDeleteRightTuple(final TupleImpl rightTuple, - final ReteEvaluator reteEvaluator, - final BetaMemory memory) { - TupleSets stagedRightTuples = memory.getStagedRightTuples(); - - boolean stagedDeleteWasEmpty = stagedRightTuples.addDelete(rightTuple); - - boolean shouldFlush = isStreamMode(); - if ( memory.getAndDecCounter() == 1 ) { - if ( stagedDeleteWasEmpty ) { - memory.setNodeDirtyWithoutNotify(); - } - shouldFlush = memory.unlinkNode(reteEvaluator) | shouldFlush; - } else if ( stagedDeleteWasEmpty ) { - // nothing staged before, notify rule, so it can evaluate network - shouldFlush = memory.setNodeDirty( this, reteEvaluator ) | shouldFlush; - } - - if (shouldFlush) { - flushLeftTupleIfNecessary( reteEvaluator, memory.getOrCreateSegmentMemory( this, reteEvaluator ), isStreamMode() ); - } - } - - public void doUpdateRightTuple(final TupleImpl rightTuple, - final ReteEvaluator reteEvaluator, - final BetaMemory memory) { - TupleSets stagedRightTuples = memory.getStagedRightTuples(); - - boolean stagedUpdateWasEmpty = stagedRightTuples.addUpdate( rightTuple ); - - boolean shouldFlush = isStreamMode(); - if ( stagedUpdateWasEmpty ) { - shouldFlush = memory.setNodeDirty( this, reteEvaluator ) | shouldFlush; - } - - if (shouldFlush) { - flushLeftTupleIfNecessary( reteEvaluator, memory.getOrCreateSegmentMemory( this, reteEvaluator ), isStreamMode() ); - } - } - - public boolean isRightInputIsRiaNode() { - return rightInputIsRiaNode; - } - - public boolean isRightInputPassive() { - return rightInputIsPassive; - } - - public ObjectSource getRightInput() { + public RightInputAdapterNode getRightInput() { return this.rightInput; } - public void setRightInput( ObjectSource rightInput ) { - this.rightInput = rightInput; - rightInputIsRiaNode = NodeTypeEnums.RightInputAdapterNode == rightInput.getType(); + public boolean inputIsTupleToObjectNode() { + return rightInput.inputIsTupleToObjectNode(); } public FastIterator getRightIterator(TupleMemory memory) { @@ -395,7 +213,7 @@ public RightTuple getFirstRightTuple(final TupleImpl leftTuple, } public FastIterator getLeftIterator(TupleMemory memory) { - if (rightInputIsRiaNode) { + if (rightInput.inputIsTupleToObjectNode()) { return FastIterator.NullFastIterator.INSTANCE; } else { if ( this.indexedUnificationJoin ) { @@ -409,7 +227,7 @@ public FastIterator getLeftIterator(TupleMemory memory) { public TupleImpl getFirstLeftTuple(final TupleImpl rightTuple, final TupleMemory memory, final FastIterator it) { - if (rightInputIsRiaNode) { + if (rightInput.inputIsTupleToObjectNode()) { return getStartTuple(rightTuple); } else { if ( this.indexedUnificationJoin ) { @@ -421,7 +239,8 @@ public TupleImpl getFirstLeftTuple(final TupleImpl rightTuple, } public TupleImpl getStartTuple(TupleImpl lt) { - LeftTupleSource startTupleSource = (( RightInputAdapterNode ) getRightInput()).getStartTupleSource(); + + LeftTupleSource startTupleSource = ((TupleToObjectNode) rightInput.getParent()).getStartTupleSource(); // Iterate find start while (lt.getIndex() != startTupleSource.getPathIndex()-1) { // -1 as it needs the split node, not the start of the branch @@ -462,7 +281,7 @@ private void setConstraints(BetaConstraints constraints) { public void networkUpdated(UpdateContext updateContext) { updateContext.startVisitNode( leftInput ); - rightInput.networkUpdated( updateContext ); + rightInput.networkUpdated(updateContext); updateContext.endVisit(); if ( !updateContext.isVisiting( leftInput ) ) { leftInput.networkUpdated( updateContext ); @@ -485,33 +304,17 @@ public List getRules() { @Override public ObjectTypeNode getObjectTypeNode() { - if (objectTypeNode == null) { - ObjectSource source = this.rightInput; - while ( source != null ) { - if ( NodeTypeEnums.ObjectTypeNode == source.getType()) { - objectTypeNode = (ObjectTypeNode) source; - break; - } - source = source.source; - } - } - return objectTypeNode; + return rightInput.getObjectTypeNode(); } public void doAttach(BuildContext context) { super.doAttach(context); setUnificationJoin(); - this.rightInput.addObjectSink(this); + this.rightInput.doAttach(context); this.leftInput.addTupleSink( this, context ); } - public void byPassModifyToBetaNode (final InternalFactHandle factHandle, - final ModifyPreviousTuples modifyPreviousTuples, - final PropagationContext context, - final ReteEvaluator reteEvaluator) { - modifyObject( factHandle, modifyPreviousTuples, context, reteEvaluator ); - } public static BetaMemory getBetaMemory(NetworkNode node, ReteEvaluator reteEvaluator) { @@ -542,14 +345,11 @@ public String toString() { } protected int calculateHashCode() { - int hash = ( 23 * leftInput.hashCode() ) + ( 29 * rightInput.hashCode() ) + ( 31 * constraints.hashCode() ); + int hash = ( 23 * leftInput.hashCode() ) + (29 * rightInput.hashCode() ) + (31 * constraints.hashCode() ); if (leftListenedProperties != null) { hash += 37 * leftListenedProperties.hashCode(); } - if (rightListenedProperties != null) { - hash += 41 * rightListenedProperties.hashCode(); - } - return hash + (rightInputIsPassive ? 43 : 0); + return hash; } @Override @@ -565,11 +365,9 @@ public boolean equals(Object object) { BetaNode other = (BetaNode) object; return this.getClass() == other.getClass() && this.constraints.equals( other.constraints ) && - this.rightInputIsPassive == other.rightInputIsPassive && + this.rightInput.equals(other.rightInput) && Objects.equals(this.leftListenedProperties, other.leftListenedProperties) && - Objects.equals(this.rightListenedProperties, other.rightListenedProperties) && - this.leftInput.getId() == other.leftInput.getId() && - this.rightInput.getId() == other.rightInput.getId(); + this.leftInput.getId() == other.leftInput.getId(); } /** @@ -607,82 +405,47 @@ public LeftTupleSinkNode getPreviousLeftTupleSinkNode() { public void setPreviousLeftTupleSinkNode(final LeftTupleSinkNode previous) { this.previousTupleSinkNode = previous; } - - /** - * Returns the next node - * @return - * The next ObjectSinkNode - */ - public ObjectSinkNode getNextObjectSinkNode() { - return this.nextObjectSinkNode; - } - - /** - * Sets the next node - * @param next - * The next ObjectSinkNode - */ - public void setNextObjectSinkNode(final ObjectSinkNode next) { - this.nextObjectSinkNode = next; + void disablePropertyReactivity() { + rightInput.disablePropertyReactivity(); + if (NodeTypeEnums.isBetaNode(leftInput)) { + ((BetaNode)leftInput).disablePropertyReactivity(); + } } - /** - * Returns the previous node - * @return - * The previous ObjectSinkNode - */ - public ObjectSinkNode getPreviousObjectSinkNode() { - return this.previousObjectSinkNode; + @Override + public boolean doRemove(RuleRemovalContext context, ReteooBuilder builder) { + if ( !isInUse() ) { + getLeftTupleSource().removeTupleSink( this ); + return true; + } + return false; } /** - * Sets the previous node - * @param previous - * The previous ObjectSinkNode + * Associates this node with the give rule */ - public void setPreviousObjectSinkNode(final ObjectSinkNode previous) { - this.previousObjectSinkNode = previous; + public void addAssociation(Rule rule, BuildContext context) { + super.addAssociation(rule, context); + rightInput.addAssociation(rule, context); } - public RightTuple createRightTuple(InternalFactHandle handle, - RightTupleSink sink, - PropagationContext context) { - RightTuple rightTuple = new RightTuple(handle, sink ); - rightTuple.setPropagationContext( context ); - return rightTuple; - } - - public static BetaMemory getBetaMemoryFromRightInput(BetaNode betaNode, ReteEvaluator reteEvaluator) { - return NodeTypeEnums.AccumulateNode == betaNode.getType() ? - ((AccumulateMemory)reteEvaluator.getNodeMemory( betaNode )).getBetaMemory() : - (BetaMemory) reteEvaluator.getNodeMemory( betaNode ); - } - - public BitMask getRightDeclaredMask() { - return rightDeclaredMask; - } - - public BitMask getRightInferredMask() { - return rightInferredMask; - } - - void disablePropertyReactivity() { - rightInferredMask = AllSetBitMask.get(); - if (NodeTypeEnums.isBetaNode(leftInput)) { - ((BetaNode)leftInput).disablePropertyReactivity(); - } - } - - public BitMask getRightNegativeMask() { - return rightNegativeMask; + @Override + public boolean removeAssociation(Rule rule, RuleRemovalContext context) { + boolean result = super.removeAssociation(rule, context); + rightInput.removeAssociation(rule, context); + return result; } - public ObjectTypeNodeId getRightInputOtnId() { - return rightInputOtnId; + @Override + public void addAssociatedTerminal(BaseTerminalNode terminalNode) { + super.addAssociatedTerminal(terminalNode); + rightInput.addAssociatedTerminal(terminalNode); } - public void setRightInputOtnId(ObjectTypeNodeId rightInputOtnId) { - this.rightInputOtnId = rightInputOtnId; + @Override + public void removeAssociatedTerminal(BaseTerminalNode terminalNode) { + super.removeAssociatedTerminal(terminalNode); + rightInput.removeAssociatedTerminal(terminalNode); } /** @@ -710,13 +473,13 @@ public RightTupleSinkAdapter() { public void assertObject(final InternalFactHandle factHandle, final PropagationContext context, final ReteEvaluator reteEvaluator) { - ObjectTypeNodeId otnId = bnNode.getRightInputOtnId(); + ObjectTypeNodeId otnId = bnNode.getRightInput().getInputOtnId(); TupleImpl detached = factHandle.getLinkedTuples().detachRightTupleAfter(getPartitionId(), otnId); if (detached != null) { detachedTuples.add(new DetachedTuple((DefaultFactHandle) factHandle, detached)); } - bnNode.assertObject(factHandle, context, reteEvaluator); + bnNode.getRightInput().assertObject(factHandle, context, reteEvaluator); } public void modifyObject(InternalFactHandle factHandle, diff --git a/drools-core/src/main/java/org/drools/core/reteoo/CompositeObjectSinkAdapter.java b/drools-core/src/main/java/org/drools/core/reteoo/CompositeObjectSinkAdapter.java index 99eb4c941db..f69e3c1e5a3 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/CompositeObjectSinkAdapter.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/CompositeObjectSinkAdapter.java @@ -282,7 +282,13 @@ public ObjectSinkPropagator removeObjectSink(final ObjectSink sink) { } } - this.otherSinks.remove( (ObjectSinkNode) sink ); + // BetaRights must be removed by identity + for (Iterator it = otherSinks.iterator(); it.hasNext();) { + if (sink == it.next()) { + it.remove(); + break; + } + } if ( this.otherSinks.isEmpty() ) { this.otherSinks = null; @@ -859,20 +865,20 @@ public ObjectSink[] getSinks() { return newSinks; } - public void doLinkRiaNode(ReteEvaluator reteEvaluator) { + public void doLinkSubnetwork(ReteEvaluator reteEvaluator) { if ( this.otherSinks != null ) { - // this is only used for ria nodes when exists are shared, we know there is no indexing for those + // this is only used for TupleToObjectNode nodes when exists are shared, we know there is no indexing for those for ( ObjectSinkNode sink : this.otherSinks ) { - SingleObjectSinkAdapter.staticDoLinkRiaNode( sink, reteEvaluator ); + SingleObjectSinkAdapter.staticDoLinkSubnetwork(sink, reteEvaluator); } } } - public void doUnlinkRiaNode(ReteEvaluator reteEvaluator) { + public void doUnlinkSubnetwork(ReteEvaluator reteEvaluator) { if ( this.otherSinks != null ) { - // this is only used for ria nodes when exists are shared, we know there is no indexing for those + // this is only used for TupleToObjectNode nodes when exists are shared, we know there is no indexing for those for ( ObjectSinkNode sink : this.otherSinks ) { - SingleObjectSinkAdapter.staticDoUnlinkRiaNode( sink, reteEvaluator ); + SingleObjectSinkAdapter.staticDoUnlinkSubnetwork(sink, reteEvaluator); } } } diff --git a/drools-core/src/main/java/org/drools/core/reteoo/CompositePartitionAwareObjectSinkAdapter.java b/drools-core/src/main/java/org/drools/core/reteoo/CompositePartitionAwareObjectSinkAdapter.java index df9fb055ba9..f4d49dd6b08 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/CompositePartitionAwareObjectSinkAdapter.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/CompositePartitionAwareObjectSinkAdapter.java @@ -220,14 +220,14 @@ public void byPassModifyToBetaNode( InternalFactHandle factHandle, ModifyPreviou } @Override - public void doLinkRiaNode( ReteEvaluator reteEvaluator ) { - throw new UnsupportedOperationException("This sink is only used for OTNs, it cannot be the sink for a RIA"); + public void doLinkSubnetwork(ReteEvaluator reteEvaluator) { + throw new UnsupportedOperationException("This sink is only used for OTNs, it cannot be the sink for a TupleToObjectNode"); } @Override - public void doUnlinkRiaNode( ReteEvaluator reteEvaluator ) { - throw new UnsupportedOperationException("This sink is only used for OTNs, it cannot be the sink for a RIA"); + public void doUnlinkSubnetwork(ReteEvaluator reteEvaluator) { + throw new UnsupportedOperationException("This sink is only used for OTNs, it cannot be the sink for a TupleToObjectNode"); } diff --git a/drools-core/src/main/java/org/drools/core/reteoo/ConditionalBranchNode.java b/drools-core/src/main/java/org/drools/core/reteoo/ConditionalBranchNode.java index c95e84ca86e..fcff4080429 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/ConditionalBranchNode.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/ConditionalBranchNode.java @@ -60,7 +60,7 @@ public ConditionalBranchNode(int id, this.tupleMemoryEnabled = context.isTupleMemoryEnabled(); this.branchEvaluator = branchEvaluator; - initMasks(context, tupleSource); + initMasks(context); hashcode = calculateHashCode(); } @@ -213,14 +213,14 @@ protected boolean doRemove(final RuleRemovalContext context, } @Override - protected void initDeclaredMask(BuildContext context, LeftTupleSource leftInput) { + public void initDeclaredMask(BuildContext context) { // See LeftTupleSource.initDeclaredMask() should result for the ConditionalBranch to result in ALLSET: // at the moment if pattern is null (e.g. for eval node) we cannot calculate the mask, so we leave it to 0 // // In other words, a conditional branch is analogous to an eval() call - mask ALL SET // To achieve the result, we highjack the call: - super.initDeclaredMask(null, null); + super.initDeclaredMask(null); } } diff --git a/drools-core/src/main/java/org/drools/core/reteoo/EmptyObjectSinkAdapter.java b/drools-core/src/main/java/org/drools/core/reteoo/EmptyObjectSinkAdapter.java index 4a0b3be8128..b1f235d52a7 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/EmptyObjectSinkAdapter.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/EmptyObjectSinkAdapter.java @@ -94,12 +94,12 @@ public boolean equals(Object obj) { return obj instanceof EmptyObjectSinkAdapter; } - public void doLinkRiaNode(ReteEvaluator reteEvaluator) { + public void doLinkSubnetwork(ReteEvaluator reteEvaluator) { // TODO Auto-generated method stub } - public void doUnlinkRiaNode(ReteEvaluator reteEvaluator) { + public void doUnlinkSubnetwork(ReteEvaluator reteEvaluator) { // TODO Auto-generated method stub } diff --git a/drools-core/src/main/java/org/drools/core/reteoo/EvalConditionNode.java b/drools-core/src/main/java/org/drools/core/reteoo/EvalConditionNode.java index c9e9275965a..7aa457ee388 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/EvalConditionNode.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/EvalConditionNode.java @@ -30,10 +30,8 @@ import org.drools.base.rule.EvalCondition; import org.drools.base.rule.RuleComponent; import org.drools.core.RuleBaseConfiguration; -import org.drools.core.common.InternalFactHandle; import org.drools.core.common.Memory; import org.drools.core.common.MemoryFactory; -import org.drools.core.common.PropagationContext; import org.drools.core.common.ReteEvaluator; import org.drools.core.common.UpdateContext; import org.drools.core.reteoo.builder.BuildContext; @@ -74,7 +72,7 @@ public EvalConditionNode(final int id, this.setObjectCount(leftInput.getObjectCount()); // 'eval' nodes do not increase the count this.tupleMemoryEnabled = context.isTupleMemoryEnabled(); - initMasks(context, tupleSource); + initMasks(context); hashcode = calculateHashCode(); } @@ -89,8 +87,8 @@ public void networkUpdated(UpdateContext updateContext) { } @Override - protected void initInferredMask(LeftTupleSource leftInput) { - super.initInferredMask( leftInput ); + protected void initInferredMask() { + super.initInferredMask( ); if (NodeTypeEnums.isBetaNode(leftInput)) { ((BetaNode)leftInput).disablePropertyReactivity(); } @@ -268,8 +266,8 @@ public int hashCode() { } @Override - public void addAssociation( BuildContext context, Rule rule ) { - super.addAssociation(context, rule); + public void addAssociation(Rule rule, BuildContext context) { + super.addAssociation(rule, context); componentsMap.put(new RuleKey(rule, context.getSubRuleIndex()), context.peekRuleComponent()); } diff --git a/drools-core/src/main/java/org/drools/core/reteoo/ExistsNode.java b/drools-core/src/main/java/org/drools/core/reteoo/ExistsNode.java index ead9220acd9..25391378c6d 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/ExistsNode.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/ExistsNode.java @@ -19,9 +19,8 @@ package org.drools.core.reteoo; import org.drools.base.reteoo.NodeTypeEnums; +import org.drools.core.common.BaseNode; import org.drools.core.common.BetaConstraints; -import org.drools.core.common.PropagationContext; -import org.drools.core.common.ReteEvaluator; import org.drools.core.reteoo.builder.BuildContext; /** @@ -44,7 +43,7 @@ public ExistsNode() { } public ExistsNode(final int id, final LeftTupleSource leftInput, - final ObjectSource rightInput, + final RightInputAdapterNode rightInput, final BetaConstraints joinNodeBinder, final BuildContext context) { super( id, @@ -57,9 +56,9 @@ public ExistsNode(final int id, } public String toString() { - ObjectSource source = this.rightInput; + BaseNode source = this.rightInput; while ( source != null && source.getClass() != ObjectTypeNode.class ) { - source = source.source; + source = source.getParent(); } return "[ExistsNode(" + this.getId() + ") - " + ((source != null) ? ((ObjectTypeNode) source).getObjectType() : "") + "]"; } @@ -68,29 +67,6 @@ public int getType() { return NodeTypeEnums.ExistsNode; } - public void retractRightTuple(final TupleImpl rightTuple, - final PropagationContext pctx, - final ReteEvaluator reteEvaluator) { - final BetaMemory memory = (BetaMemory) reteEvaluator.getNodeMemory(this); - rightTuple.setPropagationContext( pctx ); - doDeleteRightTuple( rightTuple, reteEvaluator, memory ); - } - - @Override - public void modifyRightTuple(TupleImpl rightTuple, PropagationContext context, ReteEvaluator reteEvaluator) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean doRemove(RuleRemovalContext context, ReteooBuilder builder) { - if ( !isInUse() ) { - getLeftTupleSource().removeTupleSink( this ); - getRightInput().removeObjectSink( this ); - return true; - } - return false; - } - public boolean isLeftUpdateOptimizationAllowed() { return getRawConstraints().isLeftUpdateOptimizationAllowed(); } diff --git a/drools-core/src/main/java/org/drools/core/reteoo/ExistsRight.java b/drools-core/src/main/java/org/drools/core/reteoo/ExistsRight.java new file mode 100644 index 00000000000..246a3e7a3c4 --- /dev/null +++ b/drools-core/src/main/java/org/drools/core/reteoo/ExistsRight.java @@ -0,0 +1,32 @@ +package org.drools.core.reteoo; + +import org.drools.base.reteoo.NodeTypeEnums; +import org.drools.core.common.PropagationContext; +import org.drools.core.common.ReteEvaluator; +import org.drools.core.reteoo.builder.BuildContext; + +public class ExistsRight extends RightInputAdapterNode { + + public ExistsRight(int id, ObjectSource rightInput, BuildContext context) { + super(id, rightInput, context); + } + + @Override + public void retractRightTuple(final TupleImpl rightTuple, + final PropagationContext pctx, + final ReteEvaluator reteEvaluator) { + final BetaMemory memory = (BetaMemory) reteEvaluator.getNodeMemory(betaNode); + rightTuple.setPropagationContext( pctx ); + doDeleteRightTuple( rightTuple, reteEvaluator, memory ); + } + + @Override + public void modifyRightTuple(TupleImpl rightTuple, PropagationContext context, ReteEvaluator reteEvaluator) { + throw new UnsupportedOperationException(); + } + + @Override + public int getType() { + return NodeTypeEnums.ExistsRightAdapterNode; + } +} diff --git a/drools-core/src/main/java/org/drools/core/reteoo/FromNode.java b/drools-core/src/main/java/org/drools/core/reteoo/FromNode.java index d0b4cffc483..07911833534 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/FromNode.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/FromNode.java @@ -94,7 +94,7 @@ public FromNode(final int id, this.tupleMemoryEnabled = tupleMemoryEnabled; this.from = from; - initMasks(context, tupleSource); + initMasks(context); hashcode = calculateHashCode(); } @@ -145,17 +145,16 @@ public BetaConstraints getBetaConstraints() { } @Override - protected void initDeclaredMask(BuildContext context, - LeftTupleSource leftInput) { - super.initDeclaredMask(context, leftInput); + protected void initDeclaredMask(BuildContext context) { + super.initDeclaredMask(context); - if ( leftDeclaredMask.isAllSet() ) { + if ( declaredMask.isAllSet() ) { return; } if ( context == null || context.getLastBuiltPatterns() == null ) { // only happens during unit tests - leftDeclaredMask = AllSetBitMask.get(); + declaredMask = AllSetBitMask.get(); return; } @@ -170,8 +169,8 @@ protected void initDeclaredMask(BuildContext context, if ( isPropertyReactive( context.getRuleBase(), objectType ) ) { Collection leftListenedProperties = pattern.getListenedProperties(); List accessibleProperties = getAccessibleProperties( context.getRuleBase(), objectType ); - leftDeclaredMask = leftDeclaredMask.setAll( calculatePositiveMask( objectType, leftListenedProperties, accessibleProperties ) ); - leftNegativeMask = leftNegativeMask.setAll( calculateNegativeMask( objectType, leftListenedProperties, accessibleProperties ) ); + declaredMask = declaredMask.setAll(calculatePositiveMask(objectType, leftListenedProperties, accessibleProperties)); + negativeMask = negativeMask.setAll(calculateNegativeMask(objectType, leftListenedProperties, accessibleProperties)); } } diff --git a/drools-core/src/main/java/org/drools/core/reteoo/JoinNode.java b/drools-core/src/main/java/org/drools/core/reteoo/JoinNode.java index 7f464d7c93b..cd47ccc7494 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/JoinNode.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/JoinNode.java @@ -20,8 +20,6 @@ import org.drools.base.reteoo.NodeTypeEnums; import org.drools.core.common.BetaConstraints; -import org.drools.core.common.PropagationContext; -import org.drools.core.common.ReteEvaluator; import org.drools.core.reteoo.builder.BuildContext; public class JoinNode extends BetaNode { @@ -34,7 +32,7 @@ public JoinNode() { public JoinNode(final int id, final LeftTupleSource leftInput, - final ObjectSource rightInput, + final RightInputAdapterNode rightInput, final BetaConstraints binder, final BuildContext context) { super( id, @@ -54,26 +52,4 @@ public String toString() { return "[JoinNode(" + this.getId() + ") - " + getObjectTypeNode().getObjectType() + "]"; } - public void retractRightTuple( final TupleImpl rightTuple, - final PropagationContext pctx, - final ReteEvaluator reteEvaluator ) { - final BetaMemory memory = (BetaMemory) reteEvaluator.getNodeMemory(this); - rightTuple.setPropagationContext( pctx ); - doDeleteRightTuple( rightTuple, reteEvaluator, memory ); - } - - @Override - public void modifyRightTuple(TupleImpl rightTuple, PropagationContext context, ReteEvaluator reteEvaluator) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean doRemove(RuleRemovalContext context, ReteooBuilder builder) { - if ( !isInUse() ) { - getLeftTupleSource().removeTupleSink( this ); - getRightInput().removeObjectSink( this ); - return true; - } - return false; - } } diff --git a/drools-core/src/main/java/org/drools/core/reteoo/JoinRightAdapterNode.java b/drools-core/src/main/java/org/drools/core/reteoo/JoinRightAdapterNode.java new file mode 100644 index 00000000000..983e9d67ffb --- /dev/null +++ b/drools-core/src/main/java/org/drools/core/reteoo/JoinRightAdapterNode.java @@ -0,0 +1,32 @@ +package org.drools.core.reteoo; + +import org.drools.base.reteoo.NodeTypeEnums; +import org.drools.core.common.PropagationContext; +import org.drools.core.common.ReteEvaluator; +import org.drools.core.reteoo.builder.BuildContext; + +public class JoinRightAdapterNode extends RightInputAdapterNode { + public JoinRightAdapterNode(int id, ObjectSource rightInput, BuildContext context) { + super(id, rightInput, context); + } + + @Override + public void retractRightTuple( final TupleImpl rightTuple, + final PropagationContext pctx, + final ReteEvaluator reteEvaluator) { + final BetaMemory memory = (BetaMemory) reteEvaluator.getNodeMemory(betaNode); + rightTuple.setPropagationContext( pctx ); + doDeleteRightTuple( rightTuple, reteEvaluator, memory ); + } + + @Override + public void modifyRightTuple(TupleImpl rightTuple, PropagationContext context, ReteEvaluator reteEvaluator) { + throw new UnsupportedOperationException(); + } + + @Override + public int getType() { + return NodeTypeEnums.JoinRightAdapterNode; + } + +} diff --git a/drools-core/src/main/java/org/drools/core/reteoo/LeftInputAdapterNode.java b/drools-core/src/main/java/org/drools/core/reteoo/LeftInputAdapterNode.java index 793d0ff3303..99295c32dc6 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/LeftInputAdapterNode.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/LeftInputAdapterNode.java @@ -31,6 +31,7 @@ import org.drools.base.reteoo.NodeTypeEnums; import org.drools.base.rule.Pattern; import org.drools.core.RuleBaseConfiguration; +import org.drools.core.common.BaseNode; import org.drools.core.common.DefaultFactHandle; import org.drools.core.common.InternalFactHandle; import org.drools.core.common.Memory; @@ -54,7 +55,7 @@ import static org.drools.base.reteoo.PropertySpecificUtil.isPropertyReactive; import static org.drools.core.phreak.TupleEvaluationUtil.createLeftTupleTupleSets; import static org.drools.core.phreak.TupleEvaluationUtil.findPathToFlush; -import static org.drools.core.phreak.TupleEvaluationUtil.findPathsToFlushFromRia; +import static org.drools.core.phreak.TupleEvaluationUtil.findPathsToFlushFromSubnetwork; import static org.drools.core.phreak.TupleEvaluationUtil.flushLeftTupleIfNecessary; import static org.drools.core.phreak.TupleEvaluationUtil.forceFlushLeftTuple; import static org.drools.core.phreak.TupleEvaluationUtil.forceFlushPath; @@ -102,9 +103,9 @@ public LeftInputAdapterNode(final int id, this.setObjectCount(1); // 'lia' start at 1 this.objectSource = source; this.leftTupleMemoryEnabled = context.isTupleMemoryEnabled(); - ObjectSource current = source; + BaseNode current = source; while (current.getType() != NodeTypeEnums.ObjectTypeNode) { - current = current.getParentObjectSource(); + current = current.getParent(); } setStreamMode( context.isStreamMode() && context.getRootObjectTypeNode().getObjectType().isEvent() ); @@ -113,6 +114,10 @@ public LeftInputAdapterNode(final int id, hashcode = calculateHashCode(); } + public ObjectSource getParent() { + return objectSource; + } + private BitMask calculateSinkMask(BuildContext context) { Pattern pattern = context.getLastBuiltPatterns() != null ? context.getLastBuiltPatterns()[0] : null; if (pattern == null) { @@ -244,7 +249,7 @@ public static List doInsertSegmentMemory(ReteEvaluator reteEvaluator if ( linkOrNotify ) { lm.setNodeDirty( reteEvaluator ); } - return findPathsToFlushFromRia(reteEvaluator, pmem); + return findPathsToFlushFromSubnetwork(reteEvaluator, pmem); } // mask check is necessary if insert is a result of a modify @@ -389,13 +394,13 @@ public void modifyObject(InternalFactHandle factHandle, final ModifyPreviousTuples modifyPreviousTuples, PropagationContext context, ReteEvaluator reteEvaluator) { - ObjectTypeNodeId otnId = this.sink.getFirstLeftTupleSink().getLeftInputOtnId(); + ObjectTypeNodeId otnId = this.sink.getFirstLeftTupleSink().getInputOtnId(); TupleImpl leftTuple = processDeletesFromModify(modifyPreviousTuples, context, reteEvaluator, otnId); LiaNodeMemory lm = reteEvaluator.getNodeMemory( this ); LeftTupleSink sink = getSinkPropagator().getFirstLeftTupleSink(); - BitMask mask = sink.getLeftInferredMask(); + BitMask mask = sink.getInferredMask(); if ( leftTuple != null && leftTuple.getInputOtnId().equals(otnId) ) { modifyPreviousTuples.removeLeftTuple(partitionId); @@ -617,7 +622,7 @@ public LeftTupleSinkAdapter() { public void assertObject(final InternalFactHandle factHandle, final PropagationContext context, final ReteEvaluator reteEvaluator) { - ObjectTypeNodeId otnId = liaNode.getSinkPropagator().getFirstLeftTupleSink().getLeftInputOtnId(); + ObjectTypeNodeId otnId = liaNode.getSinkPropagator().getFirstLeftTupleSink().getInputOtnId(); TupleImpl detached = factHandle.getLinkedTuples().detachLeftTupleAfter(getPartitionId(), otnId); if (detached != null) { detachedTuples.add(new DetachedTuple((DefaultFactHandle) factHandle, detached)); diff --git a/drools-core/src/main/java/org/drools/core/reteoo/LeftTupleSink.java b/drools-core/src/main/java/org/drools/core/reteoo/LeftTupleSink.java index bda78288904..6b2a7847ea3 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/LeftTupleSink.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/LeftTupleSink.java @@ -19,8 +19,6 @@ package org.drools.core.reteoo; import org.drools.base.common.RuleBasePartitionId; -import org.drools.core.common.InternalFactHandle; -import org.drools.core.common.PropagationContext; import org.drools.util.bitmask.BitMask; /** @@ -33,11 +31,13 @@ public interface LeftTupleSink extends LeftTupleNode, Sink { boolean isLeftTupleMemoryEnabled(); - ObjectTypeNodeId getLeftInputOtnId(); + ObjectTypeNodeId getInputOtnId(); - void setLeftInputOtnId(ObjectTypeNodeId leftInputOtnId); + void setInputOtnId(ObjectTypeNodeId leftInputOtnId); - BitMask getLeftInferredMask(); + BitMask getDeclaredMask(); + + BitMask getInferredMask(); void setPartitionIdWithSinks( RuleBasePartitionId partitionId ); } diff --git a/drools-core/src/main/java/org/drools/core/reteoo/LeftTupleSource.java b/drools-core/src/main/java/org/drools/core/reteoo/LeftTupleSource.java index 7391eb4117f..ec379058912 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/LeftTupleSource.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/LeftTupleSource.java @@ -50,16 +50,16 @@ */ public abstract class LeftTupleSource extends BaseNode implements LeftTupleNode { - protected BitMask leftDeclaredMask = EmptyBitMask.get(); - protected BitMask leftInferredMask = EmptyBitMask.get(); - protected BitMask leftNegativeMask = EmptyBitMask.get(); + protected BitMask declaredMask = EmptyBitMask.get(); + protected BitMask inferredMask = EmptyBitMask.get(); + protected BitMask negativeMask = EmptyBitMask.get(); /** The left input TupleSource. */ protected LeftTupleSource leftInput; - private ObjectTypeNodeId leftInputOtnId = ObjectTypeNodeId.DEFAULT_ID; + private ObjectTypeNodeId inputOtnId = ObjectTypeNodeId.DEFAULT_ID; /** The destination for Tuples. */ protected LeftTupleSinkPropagator sink; @@ -81,7 +81,7 @@ public LeftTupleSource() { * @param id */ protected LeftTupleSource(int id, BuildContext context) { - super(id, context != null ? context.getPartitionId() : RuleBasePartitionId.MAIN_PARTITION); + super(id, context.getPartitionId()); this.sink = EmptyLeftTupleSinkAdapter.getInstance(); initMemoryId( context ); } @@ -96,12 +96,12 @@ public int getPathIndex() { public abstract int getType(); - public ObjectTypeNodeId getLeftInputOtnId() { - return leftInputOtnId; + public ObjectTypeNodeId getInputOtnId() { + return inputOtnId; } - public void setLeftInputOtnId(ObjectTypeNodeId leftInputOtnId) { - this.leftInputOtnId = leftInputOtnId; + public void setInputOtnId(ObjectTypeNodeId inputOtnId) { + this.inputOtnId = inputOtnId; } @@ -113,6 +113,14 @@ public LeftTupleSource getLeftTupleSource() { return leftInput; } + public LeftTupleSource getLeftInput() { + return leftInput; + } + + public LeftTupleSinkPropagator getSink() { + return sink; + } + public final void setLeftTupleSource(LeftTupleSource leftInput) { this.leftInput = leftInput; pathIndex = leftInput.getPathIndex() + 1; @@ -126,6 +134,10 @@ public void setObjectCount(int count) { objectCount = count; } + public BaseNode getParent() { + return leftInput; + } + /** * Adds the TupleSink so that it may receive * Tuples propagated from this TupleSource. @@ -224,23 +236,21 @@ public boolean isInUse() { return this.sink.size() > 0; } - protected final void initMasks(BuildContext context, - LeftTupleSource leftInput) { - initDeclaredMask( context, leftInput ); - initInferredMask( leftInput ); + protected final void initMasks(BuildContext context) { + initDeclaredMask( context ); + initInferredMask( ); } - protected void initDeclaredMask(BuildContext context, - LeftTupleSource leftInput) { - if ( context == null || context.getLastBuiltPatterns() == null ) { + protected void initDeclaredMask(BuildContext context) { + if ( context == null || context.getLastBuiltPatterns() == null) { // only happens during unit tests - leftDeclaredMask = AllSetBitMask.get(); + declaredMask = AllSetBitMask.get(); return; } if ( !NodeTypeEnums.isLeftInputAdapterNode(leftInput)) { // BetaNode's not after LIANode are not relevant for left mask property specific, so don't block anything. - leftDeclaredMask = AllSetBitMask.get(); + declaredMask = AllSetBitMask.get(); return; } @@ -250,20 +260,20 @@ protected void initDeclaredMask(BuildContext context, if ( !(objectType instanceof ClassObjectType) ) { // Only ClassObjectType can use property specific - leftDeclaredMask = AllSetBitMask.get(); + declaredMask = AllSetBitMask.get(); return; } if ( pattern != null && isPropertyReactive(context.getRuleBase(), objectType) ) { Collection leftListenedProperties = pattern.getListenedProperties(); List accessibleProperties = getAccessibleProperties( context.getRuleBase(), objectType ); - leftDeclaredMask = calculatePositiveMask( objectType, leftListenedProperties, accessibleProperties ); - leftDeclaredMask = setNodeConstraintsPropertyReactiveMask(leftDeclaredMask, objectType, accessibleProperties); - leftNegativeMask = calculateNegativeMask( objectType, leftListenedProperties, accessibleProperties ); + declaredMask = calculatePositiveMask(objectType, leftListenedProperties, accessibleProperties); + declaredMask = setNodeConstraintsPropertyReactiveMask(declaredMask, objectType, accessibleProperties); + negativeMask = calculateNegativeMask(objectType, leftListenedProperties, accessibleProperties); setLeftListenedProperties(leftListenedProperties); } else { // if property specific is not on, then accept all modification propagations - leftDeclaredMask = AllSetBitMask.get(); + declaredMask = AllSetBitMask.get(); } } @@ -283,38 +293,38 @@ protected ObjectType getObjectTypeForPropertyReactivity( LeftInputAdapterNode le protected void setLeftListenedProperties(Collection leftListenedProperties) { } - protected void initInferredMask(LeftTupleSource leftInput) { - LeftTupleSource unwrappedLeft = unwrapLeftInput(leftInput); + protected void initInferredMask() { + LeftTupleSource unwrappedLeft = unwrapLeftInput(); if ( NodeTypeEnums.isLeftInputAdapterNode(unwrappedLeft) && ((LeftInputAdapterNode)unwrappedLeft).getParentObjectSource().getType() == NodeTypeEnums.AlphaNode ) { ObjectSource objectSource = ((LeftInputAdapterNode)unwrappedLeft).getParentObjectSource(); - leftInferredMask = objectSource.updateMask( leftDeclaredMask ); + inferredMask = objectSource.updateMask(declaredMask); } else { - leftInferredMask = leftDeclaredMask; + inferredMask = declaredMask; } - leftInferredMask = leftInferredMask.resetAll(leftNegativeMask); + inferredMask = inferredMask.resetAll(negativeMask); } - private LeftTupleSource unwrapLeftInput(LeftTupleSource leftInput) { + private LeftTupleSource unwrapLeftInput() { if (leftInput.getType() == NodeTypeEnums.FromNode || leftInput.getType() == NodeTypeEnums.ReactiveFromNode) { return leftInput.getLeftTupleSource(); } return leftInput; } - public BitMask getLeftDeclaredMask() { - return leftDeclaredMask; + public BitMask getDeclaredMask() { + return declaredMask; } - public BitMask getLeftInferredMask() { - return leftInferredMask; + public BitMask getInferredMask() { + return inferredMask; } - protected void setLeftInferredMask(BitMask leftInferredMask) { - this.leftInferredMask = leftInferredMask; + protected void setInferredMask(BitMask inferredMask) { + this.inferredMask = inferredMask; } - public BitMask getLeftNegativeMask() { - return leftNegativeMask; + public BitMask getNegativeMask() { + return negativeMask; } public ObjectType getObjectType() { diff --git a/drools-core/src/main/java/org/drools/core/reteoo/NotNode.java b/drools-core/src/main/java/org/drools/core/reteoo/NotNode.java index 6d1d8d58120..7af29e2e2f9 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/NotNode.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/NotNode.java @@ -20,13 +20,8 @@ import org.drools.base.reteoo.NodeTypeEnums; import org.drools.core.common.BetaConstraints; -import org.drools.core.common.InternalFactHandle; -import org.drools.core.common.PropagationContext; -import org.drools.core.common.ReteEvaluator; -import org.drools.core.common.TupleSets; import org.drools.core.reteoo.builder.BuildContext; -import static org.drools.core.phreak.RuleNetworkEvaluator.doExistentialUpdatesReorderChildLeftTuple; import static org.drools.core.phreak.TupleEvaluationUtil.flushLeftTupleIfNecessary; public class NotNode extends BetaNode { @@ -43,7 +38,7 @@ public NotNode() { public NotNode(final int id, final LeftTupleSource leftInput, - final ObjectSource rightInput, + final RightInputAdapterNode rightInput, final BetaConstraints joinNodeBinder, final BuildContext context) { super(id, @@ -60,10 +55,6 @@ public NotNode(final int id, emptyBetaConstraints = joinNodeBinder.getConstraints().length == 0 || context.isEmptyForAllBetaConstraints(); } - @Override - protected void reorderRightTuple(ReteEvaluator reteEvaluator, TupleImpl rightTuple) { - doExistentialUpdatesReorderChildLeftTuple(reteEvaluator, this, (RightTuple) rightTuple); - } public boolean isEmptyBetaConstraints() { return emptyBetaConstraints; @@ -82,80 +73,6 @@ public String toString() { return "[NotNode(" + this.getId() + ") - " + ((source != null) ? source.getObjectType() : "") + "]"; } - public void assertObject( final InternalFactHandle factHandle, - final PropagationContext pctx, - final ReteEvaluator reteEvaluator ) { - final BetaMemory memory = (BetaMemory) getBetaMemoryFromRightInput(this, reteEvaluator); - - TupleImpl rightTuple = createRightTuple( factHandle, - this, - pctx); - - rightTuple.setPropagationContext(pctx); - - boolean stagedInsertWasEmpty = memory.getStagedRightTuples().addInsert( rightTuple ); - - if (memory.getAndIncCounter() == 0 && isEmptyBetaConstraints() ) { - // strangely we link here, this is actually just to force a network evaluation - // The assert is then processed and the rule unlinks then. - // This is because we need the first RightTuple to link with it's blocked - if ( stagedInsertWasEmpty ) { - memory.setNodeDirtyWithoutNotify(); - } - - // NotNodes can only be unlinked, if they have no variable constraints - memory.linkNode( this, reteEvaluator ); - } else if ( stagedInsertWasEmpty ) { - // nothing staged before, notify rule, so it can evaluate network - memory.setNodeDirty(this, reteEvaluator); - } - - flushLeftTupleIfNecessary( reteEvaluator, memory.getOrCreateSegmentMemory( this, reteEvaluator ), isStreamMode() ); - } - - public void retractRightTuple(final TupleImpl rightTuple, - final PropagationContext pctx, - final ReteEvaluator reteEvaluator) { - final BetaMemory memory = (BetaMemory) reteEvaluator.getNodeMemory(this); - rightTuple.setPropagationContext( pctx ); - doDeleteRightTuple( rightTuple, reteEvaluator, memory ); - } - - public void doDeleteRightTuple(final TupleImpl rightTuple, - final ReteEvaluator reteEvaluator, - final BetaMemory memory) { - TupleSets stagedRightTuples = memory.getStagedRightTuples(); - boolean stagedDeleteWasEmpty = stagedRightTuples.addDelete( rightTuple ); - - if ( memory.getAndDecCounter() == 1 && isEmptyBetaConstraints() ) { - if ( stagedDeleteWasEmpty ) { - memory.setNodeDirtyWithoutNotify(); - } - // NotNodes can only be unlinked, if they have no variable constraints - memory.linkNode( this, reteEvaluator ); - } else if ( stagedDeleteWasEmpty ) { - // nothing staged before, notify rule, so it can evaluate network - memory.setNodeDirty( this, reteEvaluator ); - } - - flushLeftTupleIfNecessary( reteEvaluator, memory.getOrCreateSegmentMemory( this, reteEvaluator ), isStreamMode() ); - } - - @Override - public void modifyRightTuple(TupleImpl rightTuple, PropagationContext context, ReteEvaluator reteEvaluator) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean doRemove(RuleRemovalContext context, ReteooBuilder builder) { - if ( !isInUse() ) { - getLeftTupleSource().removeTupleSink( this ); - getRightInput().removeObjectSink( this ); - return true; - } - return false; - } - public boolean isLeftUpdateOptimizationAllowed() { return getRawConstraints().isLeftUpdateOptimizationAllowed(); } diff --git a/drools-core/src/main/java/org/drools/core/reteoo/NotRight.java b/drools-core/src/main/java/org/drools/core/reteoo/NotRight.java new file mode 100644 index 00000000000..f889997172b --- /dev/null +++ b/drools-core/src/main/java/org/drools/core/reteoo/NotRight.java @@ -0,0 +1,96 @@ +package org.drools.core.reteoo; + +import org.drools.base.reteoo.NodeTypeEnums; +import org.drools.core.common.InternalFactHandle; +import org.drools.core.common.PropagationContext; +import org.drools.core.common.ReteEvaluator; +import org.drools.core.common.TupleSets; +import org.drools.core.reteoo.builder.BuildContext; + +import static org.drools.core.phreak.RuleNetworkEvaluator.doExistentialUpdatesReorderChildLeftTuple; +import static org.drools.core.phreak.TupleEvaluationUtil.flushLeftTupleIfNecessary; + +public class NotRight extends RightInputAdapterNode { + + public NotRight(int id, ObjectSource rightInput, BuildContext context) { + super(id, rightInput, context); + } + + @Override + protected void reorderRightTuple(ReteEvaluator reteEvaluator, TupleImpl rightTuple) { + doExistentialUpdatesReorderChildLeftTuple(reteEvaluator, (NotNode) betaNode, (RightTuple) rightTuple); + } + + @Override + public void assertObject( final InternalFactHandle factHandle, + final PropagationContext pctx, + final ReteEvaluator reteEvaluator ) { + + final BetaMemory memory = getBetaMemoryFromRightInput(betaNode, reteEvaluator); + + TupleImpl rightTuple = createRightTuple( factHandle, + this, + pctx); + + rightTuple.setPropagationContext(pctx); + + boolean stagedInsertWasEmpty = memory.getStagedRightTuples().addInsert( rightTuple ); + + if (memory.getAndIncCounter() == 0 && ((NotNode)betaNode).isEmptyBetaConstraints() ) { + // strangely we link here, this is actually just to force a network evaluation + // The assert is then processed and the rule unlinks then. + // This is because we need the first RightTuple to link with it's blocked + if ( stagedInsertWasEmpty ) { + memory.setNodeDirtyWithoutNotify(); + } + + // NotNodes can only be unlinked, if they have no variable constraints + memory.linkNode( betaNode, reteEvaluator ); + } else if ( stagedInsertWasEmpty ) { + // nothing staged before, notify rule, so it can evaluate network + memory.setNodeDirty(betaNode, reteEvaluator); + } + + flushLeftTupleIfNecessary( reteEvaluator, memory.getOrCreateSegmentMemory( betaNode, reteEvaluator ), isStreamMode() ); + } + + @Override + public void modifyRightTuple(TupleImpl rightTuple, PropagationContext context, ReteEvaluator reteEvaluator) { + throw new UnsupportedOperationException(); + } + + @Override + public void retractRightTuple(final TupleImpl rightTuple, + final PropagationContext pctx, + final ReteEvaluator reteEvaluator) { + final BetaMemory memory = (BetaMemory) reteEvaluator.getNodeMemory(betaNode); + rightTuple.setPropagationContext( pctx ); + doDeleteRightTuple( rightTuple, reteEvaluator, memory ); + } + + @Override + public void doDeleteRightTuple(final TupleImpl rightTuple, + final ReteEvaluator reteEvaluator, + final BetaMemory memory) { + TupleSets stagedRightTuples = memory.getStagedRightTuples(); + boolean stagedDeleteWasEmpty = stagedRightTuples.addDelete( rightTuple ); + + if ( memory.getAndDecCounter() == 1 && ((NotNode)betaNode).isEmptyBetaConstraints() ) { + if ( stagedDeleteWasEmpty ) { + memory.setNodeDirtyWithoutNotify(); + } + // NotNodes can only be unlinked, if they have no variable constraints + memory.linkNode( betaNode, reteEvaluator ); + } else if ( stagedDeleteWasEmpty ) { + // nothing staged before, notify rule, so it can evaluate network + memory.setNodeDirty( betaNode, reteEvaluator ); + } + + flushLeftTupleIfNecessary( reteEvaluator, memory.getOrCreateSegmentMemory( betaNode, reteEvaluator ), isStreamMode() ); + } + + @Override + public int getType() { + return NodeTypeEnums.NotRightAdapterNode; + } +} diff --git a/drools-core/src/main/java/org/drools/core/reteoo/ObjectSinkPropagator.java b/drools-core/src/main/java/org/drools/core/reteoo/ObjectSinkPropagator.java index 4b971610bcc..99d6e1d9e06 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/ObjectSinkPropagator.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/ObjectSinkPropagator.java @@ -56,8 +56,8 @@ void byPassModifyToBetaNode (final InternalFactHandle factHandle, final PropagationContext context, final ReteEvaluator reteEvaluator); - void doLinkRiaNode(ReteEvaluator reteEvaluator); + void doLinkSubnetwork(ReteEvaluator reteEvaluator); - void doUnlinkRiaNode(ReteEvaluator reteEvaluator); + void doUnlinkSubnetwork(ReteEvaluator reteEvaluator); } diff --git a/drools-core/src/main/java/org/drools/core/reteoo/ObjectSource.java b/drools-core/src/main/java/org/drools/core/reteoo/ObjectSource.java index faad3ecd97d..8f557b9dfee 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/ObjectSource.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/ObjectSource.java @@ -78,6 +78,10 @@ protected ObjectSource(int id, RuleBasePartitionId partitionId) { this( id, partitionId, null, 3, 3); } + protected ObjectSource(int id, final ObjectSource objectSource, RuleBasePartitionId partitionId) { + this( id, partitionId, objectSource, 3, 3); + } + /** * Single parameter constructor that specifies the unique id of the node. */ @@ -93,22 +97,14 @@ protected ObjectSource(int id, RuleBasePartitionId partitionId) { this.sink = EmptyObjectSinkAdapter.getInstance(); } - // ------------------------------------------------------------ - // Instance methods - // ------------------------------------------------------------ - - public ObjectSource getParentObjectSource() { - return this.source; - } - - public void setParentObjectSource(ObjectSource source) { - this.source = source; - } - public InternalRuleBase getRuleBase() { return source.getRuleBase(); } + public BaseNode getParent() { + return source; + } + public void initDeclaredMask(BuildContext context) { if ( context == null || context.getLastBuiltPatterns() == null ) { // only happens during unit tests @@ -237,6 +233,10 @@ public ObjectTypeNode getObjectTypeNode() { } public BitMask getDeclaredMask() { - return EmptyBitMask.get(); + return declaredMask; + } + + public BitMask getInferredMask() { + return inferredMask; } } diff --git a/drools-core/src/main/java/org/drools/core/reteoo/ObjectTypeNode.java b/drools-core/src/main/java/org/drools/core/reteoo/ObjectTypeNode.java index dcbac740338..39bb5b2e205 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/ObjectTypeNode.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/ObjectTypeNode.java @@ -355,11 +355,11 @@ public void networkUpdated(UpdateContext updateContext) { protected static void updateTupleSinkId(ObjectTypeNode otn, ObjectSource source) { for (ObjectSink sink : source.sink.getSinks()) { - if (NodeTypeEnums.isBetaNode(sink)) { - ((BetaNode)sink).setRightInputOtnId(otn.nextOtnId()); + if (NodeTypeEnums.isBetaRightNode(sink)) { + ((RightInputAdapterNode)sink).setInputOtnId(otn.nextOtnId()); } else if (NodeTypeEnums.isLeftInputAdapterNode(sink)) { for (LeftTupleSink liaChildSink : ((LeftInputAdapterNode) sink).getSinkPropagator().getSinks()) { - liaChildSink.setLeftInputOtnId(otn.nextOtnId()); + liaChildSink.setInputOtnId(otn.nextOtnId()); } } else if (sink.getType() == NodeTypeEnums.WindowNode) { ((WindowNode)sink).setRightInputOtnId(otn.nextOtnId()); diff --git a/drools-core/src/main/java/org/drools/core/reteoo/PathEndNode.java b/drools-core/src/main/java/org/drools/core/reteoo/PathEndNode.java index a94c10377d8..654f716effe 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/PathEndNode.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/PathEndNode.java @@ -101,12 +101,12 @@ default PathMemSpec calculatePathMemSpec(LeftTupleSource startTupleSource, Termi NodeTypeEnums.isBetaNode( tupleSource ) && NodeTypeEnums.AccumulateNode != tupleSource.getType()) { // accumulates can never be disabled BetaNode bn = ( BetaNode) tupleSource; - if ( bn.isRightInputIsRiaNode() ) { + if ( bn.getRightInput().inputIsTupleToObjectNode() ) { updateBitInNewSegment = false; - RightInputAdapterNode rian = (RightInputAdapterNode) bn.getRightInput(); + TupleToObjectNode tton = (TupleToObjectNode) bn.getRightInput().getParent(); // only ria's without reactive subnetworks can be disabled and thus need checking // The getNodeMemory will call this method recursive for sub networks it reaches - if ( rian.getPathMemSpec(removingTN).allLinkedTestMask != 0 ) { + if ( tton.getPathMemSpec(removingTN).allLinkedTestMask != 0 ) { allLinkedTestMask = allLinkedTestMask | 1; } } else if ( NodeTypeEnums.NotNode != bn.getType() || ((NotNode)bn).isEmptyBetaConstraints()) { diff --git a/drools-core/src/main/java/org/drools/core/reteoo/PathMemory.java b/drools-core/src/main/java/org/drools/core/reteoo/PathMemory.java index 9551ab4c781..93c41fe9aea 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/PathMemory.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/PathMemory.java @@ -102,7 +102,7 @@ public void linkSegment(long mask, ReteEvaluator reteEvaluator) { TerminalNode rtn = (TerminalNode) getPathEndNode(); log.trace(" LinkSegment smask={} rmask={} name={}", mask, linkedSegmentMask, rtn.getRule().getName()); } else { - log.trace(" LinkSegment smask={} rmask={}", mask, "RiaNode"); + log.trace(" LinkSegment smask={} rmask={}", mask, "TupleToObjectNode"); } } if (isRuleLinked()) { diff --git a/drools-core/src/main/java/org/drools/core/reteoo/QueryElementNode.java b/drools-core/src/main/java/org/drools/core/reteoo/QueryElementNode.java index 400e7dd01e3..73039ef50be 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/QueryElementNode.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/QueryElementNode.java @@ -78,7 +78,7 @@ public QueryElementNode(final int id, this.tupleMemoryEnabled = tupleMemoryEnabled; this.openQuery = openQuery; this.dataDriven = context != null && context.getRule().isDataDriven(); - initMasks( context, tupleSource ); + initMasks( context ); this.argsTemplate = initArgsTemplate( context ); hashcode = calculateHashCode(); diff --git a/drools-core/src/main/java/org/drools/core/reteoo/QueryTerminalNode.java b/drools-core/src/main/java/org/drools/core/reteoo/QueryTerminalNode.java index d239c23067d..e4016cf7195 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/QueryTerminalNode.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/QueryTerminalNode.java @@ -25,8 +25,6 @@ import org.drools.base.reteoo.NodeTypeEnums; import org.drools.base.rule.Declaration; import org.drools.base.rule.GroupElement; -import org.drools.core.common.InternalFactHandle; -import org.drools.core.common.PropagationContext; import org.drools.core.reteoo.builder.BuildContext; /** @@ -100,11 +98,11 @@ public int getType() { } - public ObjectTypeNodeId getLeftInputOtnId() { + public ObjectTypeNodeId getInputOtnId() { return leftInputOtnId; } - public void setLeftInputOtnId(ObjectTypeNodeId leftInputOtnId) { + public void setInputOtnId(ObjectTypeNodeId leftInputOtnId) { this.leftInputOtnId = leftInputOtnId; } @@ -116,6 +114,6 @@ public Declaration[] getSalienceDeclarations() { public void doAttach( BuildContext context ) { super.doAttach(context); getLeftTupleSource().addTupleSink( this, context ); - addAssociation( context, context.getRule() ); + addAssociation(context.getRule(), context); } } diff --git a/drools-core/src/main/java/org/drools/core/reteoo/ReteooBuilder.java b/drools-core/src/main/java/org/drools/core/reteoo/ReteooBuilder.java index 2d7ada53d35..471b86a9400 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/ReteooBuilder.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/ReteooBuilder.java @@ -25,6 +25,7 @@ import java.io.ObjectInput; import java.io.ObjectOutput; import java.util.ArrayDeque; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -46,7 +47,6 @@ import org.drools.core.impl.InternalRuleBase; import org.drools.core.phreak.PhreakBuilder; import org.drools.core.reteoo.builder.ReteooRuleBuilder; -import org.drools.core.util.TupleRBTree.Node; import org.kie.api.definition.rule.Rule; /** @@ -203,7 +203,7 @@ private Collection removeNodes(AbstractTerminalNode terminalNode, Coll Map stillInUse = new HashMap<>(); Collection alphas = new HashSet<>(); - removePath(wms, context, stillInUse, alphas, terminalNode); + removePath(wms, context, stillInUse, alphas, terminalNode, terminalNode.getStartTupleSource()); Set removedNodes = new HashSet<>(); for (ObjectSource alpha : alphas) { @@ -218,7 +218,7 @@ private Collection removeNodes(AbstractTerminalNode terminalNode, Coll * Each time it reaches a subnetwork beta node, the current path evaluation ends, and instead the subnetwork * path continues. */ - private void removePath( Collection wms, RuleRemovalContext context, Map stillInUse, Collection alphas, PathEndNode endNode ) { + private void removePath( Collection wms, RuleRemovalContext context, Map stillInUse, Collection alphas, PathEndNode endNode, NetworkNode startNode) { LeftTupleNode[] nodes = endNode.getPathNodes(); for (int i = endNode.getPathIndex(); i >= 0; i--) { BaseNode node = (BaseNode) nodes[i]; @@ -230,17 +230,25 @@ private void removePath( Collection wms, RuleRemovalConte if ( removed ) { // reteoo requires to call remove on the OTN for tuples cleanup - if (NodeTypeEnums.isBetaNode(node) && !((BetaNode) node).isRightInputIsRiaNode()) { - alphas.add(((BetaNode) node).getRightInput()); + if (NodeTypeEnums.isBetaNodeWithoutSubnetwork(node)) { + alphas.add(((BetaNode) node).getRightInput().getParent()); } else if (NodeTypeEnums.isLeftInputAdapterNode(node)) { alphas.add(((LeftInputAdapterNode) node).getObjectSource()); } - } - if (NodeTypeEnums.isBetaNode(node) && ((BetaNode) node).isRightInputIsRiaNode()) { - endNode = (PathEndNode) ((BetaNode) node).getRightInput(); - removePath(wms, context, stillInUse, alphas, endNode); - return; + if (NodeTypeEnums.isBetaNodeWithoutSubnetwork(node)) { + // this must be removed after alpha nodes are collected + removeLeftTupleNode(wms, context, stillInUse, ((BetaNode) node).getRightInput()); + } else if (NodeTypeEnums.isBetaNodeWithSubnetwork(node)) { + endNode = (PathEndNode) ((BetaNode) node).getRightInput().getParent(); + // this must be removed after we have a reference to the TupleToObjectNode endnode + removeLeftTupleNode(wms, context, stillInUse, ((BetaNode) node).getRightInput()); + removePath(wms, context, stillInUse, alphas, endNode, endNode.getStartTupleSource()); + } + + if (node == startNode) { // don't go past the network start node + return; + } } } } @@ -251,8 +259,10 @@ private boolean removeLeftTupleNode(Collection wms, RuleR if (removed) { stillInUse.remove( node.getId() ); - for (InternalWorkingMemory workingMemory : wms) { - workingMemory.clearNodeMemory((MemoryFactory) node); + if (NodeTypeEnums.isMemoryFactory(node)) { + for (InternalWorkingMemory workingMemory : wms) { + workingMemory.clearNodeMemory((MemoryFactory) node); + } } } else { stillInUse.put( node.getId(), node ); @@ -261,11 +271,11 @@ private boolean removeLeftTupleNode(Collection wms, RuleR return removed; } - private void removeObjectSource(Collection wms, Map stillInUse, Set removedNodes, ObjectSource node, RuleRemovalContext context ) { + private void removeObjectSource(Collection wms, Map stillInUse, Set removedNodes, BaseNode node, RuleRemovalContext context ) { if (removedNodes.contains( node.getId() )) { return; } - ObjectSource parent = node.getParentObjectSource(); + BaseNode parent = node.getParent(); boolean removed = node.remove( context, this ); @@ -275,9 +285,8 @@ private void removeObjectSource(Collection wms, Map remove removeNodeAssociation( ((LeftTupleNode)node).getLeftTupleSource(), rule, removedNodes, context ); } if ( NodeTypeEnums.isBetaNode( node ) ) { - removeNodeAssociation( ((BetaNode) node).getRightInput(), rule, removedNodes, context ); + removeNodeAssociation( ((BetaNode) node).getRightInput().getParent(), rule, removedNodes, context ); } else if ( NodeTypeEnums.isLeftInputAdapterNode(node)) { - removeNodeAssociation( ((LeftInputAdapterNode) node).getObjectSource(), rule, removedNodes, context ); + removeNodeAssociation( node.getParent(), rule, removedNodes, context ); } else if ( node.getType() == NodeTypeEnums.AlphaNode ) { - removeNodeAssociation( ((AlphaNode) node).getParentObjectSource(), rule, removedNodes, context ); + removeNodeAssociation( node.getParent(), rule, removedNodes, context ); } } @@ -313,11 +322,11 @@ private void resetMasks(Collection nodes) { ObjectSource source = (AlphaNode) node; while ( true ) { source.resetInferredMask(); - ObjectSource parent = source.getParentObjectSource(); + BaseNode parent = source.getParent(); if (parent.getType() != NodeTypeEnums.AlphaNode) { break; } - source = parent; + source = (ObjectSource) parent; } updateLeafSet(source, leafSet ); } else if( NodeTypeEnums.isBetaNode( node ) ) { @@ -336,6 +345,8 @@ private void resetMasks(Collection nodes) { for ( BaseNode node : leafSet ) { if ( NodeTypeEnums.isTerminalNode( node ) ) { ((TerminalNode)node).initInferredMask(); + } else if (NodeTypeEnums.isBetaRightNode(node)){ + ((RightInputAdapterNode)node).initInferredMask(); } else { // else node instanceof BetaNode ((BetaNode)node).initInferredMask(); } @@ -357,6 +368,8 @@ private void updateLeafSet(BaseNode baseNode, NodeSet leafSet) { updateLeafSet( ( BaseNode ) sink, leafSet ); } } + } else if ( NodeTypeEnums.isBetaRightNode( baseNode ) && ( baseNode.isInUse() )) { + leafSet.add( baseNode ); } else if ( baseNode.getType() == NodeTypeEnums.EvalConditionNode ) { for ( LeftTupleSink sink : ((EvalConditionNode) baseNode).getSinkPropagator().getSinks() ) { if ( ((BaseNode)sink).isInUse() ) { diff --git a/drools-core/src/main/java/org/drools/core/reteoo/RightInputAdapterNode.java b/drools-core/src/main/java/org/drools/core/reteoo/RightInputAdapterNode.java index 60e1320f88e..914870add92 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/RightInputAdapterNode.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/RightInputAdapterNode.java @@ -1,438 +1,413 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ package org.drools.core.reteoo; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - import org.drools.base.base.ObjectType; -import org.drools.base.common.NetworkNode; -import org.drools.base.definitions.rule.impl.RuleImpl; +import org.drools.base.common.RuleBasePartitionId; import org.drools.base.reteoo.NodeTypeEnums; import org.drools.base.rule.Pattern; -import org.drools.core.RuleBaseConfiguration; -import org.drools.core.common.ActivationsManager; +import org.drools.core.common.BaseNode; import org.drools.core.common.InternalFactHandle; import org.drools.core.common.InternalWorkingMemory; -import org.drools.core.common.Memory; import org.drools.core.common.PropagationContext; import org.drools.core.common.ReteEvaluator; +import org.drools.core.common.TupleSets; import org.drools.core.common.UpdateContext; -import org.drools.core.reteoo.SegmentMemory.SegmentPrototype; +import org.drools.core.reteoo.AccumulateNode.AccumulateMemory; import org.drools.core.reteoo.builder.BuildContext; +import org.drools.util.bitmask.AllSetBitMask; import org.drools.util.bitmask.BitMask; -import org.kie.api.definition.rule.Rule; +import org.drools.util.bitmask.EmptyBitMask; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -/** - * When joining a subnetwork into the main network again, RightInputAdapterNode adapts the - * subnetwork's tuple into a fact in order right join it with the tuple being propagated in - * the main network. - */ -public class RightInputAdapterNode extends ObjectSource - implements - LeftTupleSinkNode, - PathEndNode { +import java.util.Collection; +import java.util.List; +import java.util.Objects; - private static final long serialVersionUID = 510l; +import static org.drools.base.reteoo.PropertySpecificUtil.isPropertyReactive; +import static org.drools.core.phreak.RuleNetworkEvaluator.doUpdatesReorderChildLeftTuple; +import static org.drools.core.phreak.TupleEvaluationUtil.flushLeftTupleIfNecessary; - private LeftTupleSource tupleSource; +public abstract class RightInputAdapterNode extends BaseNode + implements ObjectSinkNode, + RightTupleSink { - /** - * This is first node inside of the subnetwork. The split, with two outs, would be the parent node. - */ - private LeftTupleSource startTupleSource; + protected static final Logger log = LoggerFactory.getLogger(RightInputAdapterNode.class); + protected static final boolean isLogTraceEnabled = log.isTraceEnabled(); - private boolean tupleMemoryEnabled; + protected T betaNode; - private LeftTupleSinkNode previousTupleSinkNode; - private LeftTupleSinkNode nextTupleSinkNode; + private ObjectSinkNode previousObjectSinkNode; + protected BitMask declaredMask = EmptyBitMask.get(); + protected BitMask inferredMask = EmptyBitMask.get(); + private ObjectSinkNode nextObjectSinkNode; + private BitMask negativeMask = EmptyBitMask.get(); + private ObjectTypeNodeId inputOtnId = ObjectTypeNodeId.DEFAULT_ID; - private LeftTupleNode[] pathNodes; + private ObjectSource source; - private PathEndNode[] pathEndNodes; + private Collection listenedProperties; - private PathMemSpec pathMemSpec; + protected boolean inputIsTupleToObjectNode; - private SegmentPrototype[] segmentPrototypes; + private boolean inputIsPassive; - private SegmentPrototype[] eagerSegmentPrototypes; + private transient ObjectTypeNode objectTypeNode; - private int objectCount; + public RightInputAdapterNode(int id, ObjectSource input, BuildContext context) { + super(id, context.getPartitionId()); + inputIsTupleToObjectNode = NodeTypeEnums.TupleToObjectNode == input.getType(); - public RightInputAdapterNode() { - } + source = input; - /** - * Constructor specifying the unique id of the node in the Rete network, the position of the propagating FactHandleImpl in - * ReteTuple and the source that propagates the receive ReteTuples. - * - * @param id - * Unique id - * @param source - * The TupleSource which propagates the received ReteTuple - */ - public RightInputAdapterNode(final int id, - final LeftTupleSource source, - final LeftTupleSource startTupleSource, - final BuildContext context) { - super( id, context.getPartitionId() ); - this.tupleSource = source; - this.tupleMemoryEnabled = context.isTupleMemoryEnabled(); - this.startTupleSource = startTupleSource; + this.hashcode = calculateHashCode(); - hashcode = calculateHashCode(); - initMemoryId( context ); + if (context.isStreamMode() ) { + ObjectTypeNode otn = getObjectTypeNode(); + if (otn != null) { + setStreamMode(otn.getObjectType().isEvent() ); + } + } + } + public ObjectSource getParent() { + return source; } - @Override - public PathMemSpec getPathMemSpec() { - return getPathMemSpec(null); + public T getBetaNode() { + return betaNode; } + public void setBetaNode(T betaNode) { + this.betaNode = betaNode; + } - /** - * used during network build time, potentially during rule removal time. - * @param removingTN - * @return - */ @Override - public PathMemSpec getPathMemSpec(TerminalNode removingTN) { - if (pathMemSpec == null) { - pathMemSpec = calculatePathMemSpec( startTupleSource, removingTN ); + public void assertObject( InternalFactHandle factHandle, PropagationContext pctx, ReteEvaluator reteEvaluator ) { + final BetaMemory memory = getBetaMemoryFromRightInput(betaNode, reteEvaluator); + + RightTuple rightTuple = createRightTuple(factHandle, this, pctx); + + boolean stagedInsertWasEmpty = memory.getStagedRightTuples().addInsert(rightTuple); + if ( isLogTraceEnabled ) { + log.trace("BetaNode stagedInsertWasEmpty={}", stagedInsertWasEmpty ); } - return pathMemSpec; - } + boolean shouldFlush = isStreamMode(); + if ( memory.getAndIncCounter() == 0 ) { + if ( stagedInsertWasEmpty ) { + memory.setNodeDirtyWithoutNotify(); + } + shouldFlush = memory.linkNode( betaNode, reteEvaluator, !inputIsPassive) | shouldFlush; + } else if ( stagedInsertWasEmpty ) { + shouldFlush = memory.setNodeDirty( betaNode, reteEvaluator, !inputIsPassive) | shouldFlush; + } - @Override - public void nullPathMemSpec() { - pathMemSpec = null; + if (shouldFlush) { + flushLeftTupleIfNecessary( reteEvaluator, memory.getOrCreateSegmentMemory( betaNode, reteEvaluator ), isStreamMode() ); + } } - @Override - public void setPathMemSpec(PathMemSpec pathMemSpec) { - this.pathMemSpec = pathMemSpec; - } + public void modifyObject(InternalFactHandle factHandle, ModifyPreviousTuples modifyPreviousTuples, PropagationContext context, ReteEvaluator reteEvaluator) { + TupleImpl rightTuple = modifyPreviousTuples.peekRightTuple(partitionId); - @Override - public void resetPathMemSpec(TerminalNode removingTN) { - nullPathMemSpec(); - pathMemSpec = getPathMemSpec(removingTN); - } + // if the peek is for a different OTN we assume that it is after the current one and then this is an assert + while ( rightTuple != null && rightTuple.getInputOtnId().before(getInputOtnId()) ) { + modifyPreviousTuples.removeRightTuple(partitionId); - @Override - public void setSegmentPrototypes(SegmentPrototype[] smems) { - this.segmentPrototypes = smems; - } + // we skipped this node, due to alpha hashing, so retract now + rightTuple.setPropagationContext( context ); + BetaMemory bm = BetaNode.getBetaMemory(((RightInputAdapterNode)rightTuple.getSink()).getBetaNode(), reteEvaluator); + ((RightInputAdapterNode) rightTuple.getSink()).doDeleteRightTuple(rightTuple, reteEvaluator, bm); + rightTuple = modifyPreviousTuples.peekRightTuple(partitionId); + } - @Override - public SegmentPrototype[] getSegmentPrototypes() { - return segmentPrototypes; + if ( rightTuple != null && rightTuple.getInputOtnId().equals(getInputOtnId()) ) { + modifyPreviousTuples.removeRightTuple(partitionId); + rightTuple.reAdd(); + if ( context.getModificationMask().intersects(inferredMask) ) { + // RightTuple previously existed, so continue as modify + rightTuple.setPropagationContext( context ); // only update, if the mask intersects + + BetaMemory bm = BetaNode.getBetaMemory(betaNode, reteEvaluator); + rightTuple.setPropagationContext( context ); + doUpdateRightTuple(rightTuple, reteEvaluator, bm); + } else if (rightTuple.getMemory() != null) { + reorderRightTuple(reteEvaluator, rightTuple); + } + } else { + if ( context.getModificationMask().intersects(inferredMask) ) { + // RightTuple does not exist for this node, so create and continue as assert + assertObject( factHandle, context, reteEvaluator ); + } + } } - @Override - public SegmentPrototype[] getEagerSegmentPrototypes() { - return eagerSegmentPrototypes; + protected void reorderRightTuple(ReteEvaluator reteEvaluator, TupleImpl rightTuple) { + BetaNode.getBetaMemory(betaNode, reteEvaluator).getRightTupleMemory().removeAdd(rightTuple); + doUpdatesReorderChildLeftTuple(rightTuple); } - @Override - public void setEagerSegmentPrototypes(SegmentPrototype[] eagerSegmentPrototypes) { - this.eagerSegmentPrototypes = eagerSegmentPrototypes; - } + public void doDeleteRightTuple(final TupleImpl rightTuple, + final ReteEvaluator reteEvaluator, + final BetaMemory memory) { + TupleSets stagedRightTuples = memory.getStagedRightTuples(); - @Override - public void setPathEndNodes(PathEndNode[] pathEndNodes) { - this.pathEndNodes = pathEndNodes; - } + boolean stagedDeleteWasEmpty = stagedRightTuples.addDelete(rightTuple); - @Override - public PathEndNode[] getPathEndNodes() { - return pathEndNodes; + boolean shouldFlush = isStreamMode(); + if ( memory.getAndDecCounter() == 1 ) { + if ( stagedDeleteWasEmpty ) { + memory.setNodeDirtyWithoutNotify(); + } + shouldFlush = memory.unlinkNode(reteEvaluator) | shouldFlush; + } else if ( stagedDeleteWasEmpty ) { + // nothing staged before, notify rule, so it can evaluate network + shouldFlush = memory.setNodeDirty( betaNode, reteEvaluator ) | shouldFlush; + } + + if (shouldFlush) { + flushLeftTupleIfNecessary( reteEvaluator, memory.getOrCreateSegmentMemory( betaNode, reteEvaluator ), isStreamMode() ); + } } - public LeftTupleSource getStartTupleSource() { - return startTupleSource; + public void doUpdateRightTuple(final TupleImpl rightTuple, + final ReteEvaluator reteEvaluator, + final BetaMemory memory) { + TupleSets stagedRightTuples = memory.getStagedRightTuples(); + + boolean stagedUpdateWasEmpty = stagedRightTuples.addUpdate( rightTuple ); + + boolean shouldFlush = isStreamMode(); + if ( stagedUpdateWasEmpty ) { + shouldFlush = memory.setNodeDirty( betaNode, reteEvaluator ) | shouldFlush; + } + + if (shouldFlush) { + flushLeftTupleIfNecessary( reteEvaluator, memory.getOrCreateSegmentMemory( betaNode, reteEvaluator ), isStreamMode() ); + } } - public int getPathIndex() { - return tupleSource.getPathIndex() + 1; + public static BetaMemory getBetaMemoryFromRightInput(BetaNode betaNode, ReteEvaluator reteEvaluator) { + return NodeTypeEnums.AccumulateNode == betaNode.getType() ? + ((AccumulateMemory)reteEvaluator.getNodeMemory(betaNode)).getBetaMemory() : + (BetaMemory) reteEvaluator.getNodeMemory( betaNode ); } - public int getObjectCount() { - return objectCount; + + public RightTuple createRightTuple(InternalFactHandle handle, + RightTupleSink sink, + PropagationContext context) { + RightTuple rightTuple = new RightTuple(handle, sink ); + rightTuple.setPropagationContext( context ); + return rightTuple; } - public void setObjectCount(int count) { - objectCount = count; + public void initDeclaredMask(BuildContext context) { + if (context == null || context.getLastBuiltPatterns() == null) { + // only happens during unit tests + declaredMask = AllSetBitMask.get(); + return; + } + + Pattern pattern = context.getLastBuiltPatterns()[0]; // right input pattern + inputIsPassive = pattern.isPassive(); + + if (!inputIsTupleToObjectNode()) { + ObjectType objectType = pattern.getObjectType(); + + if (isPropertyReactive(context.getRuleBase(), objectType)) { + listenedProperties = pattern.getListenedProperties(); + List accessibleProperties = pattern.getAccessibleProperties( context.getRuleBase() ); + declaredMask = pattern.getPositiveWatchMask(accessibleProperties); + declaredMask = declaredMask.setAll(betaNode.getRawConstraints().getListenedPropertyMask(pattern, objectType, accessibleProperties)); + negativeMask = pattern.getNegativeWatchMask(accessibleProperties); + } else { + // if property reactive is not on, then accept all modification propagations + declaredMask = AllSetBitMask.get(); + } + } else { + declaredMask = AllSetBitMask.get(); + // There would have been no right input pattern, so swap current to first, so leftInput can still work + context.setLastBuiltPattern( context.getLastBuiltPatterns()[0] ); + } } - /** - * Creates and return the node memory - */ - public RiaPathMemory createMemory(final RuleBaseConfiguration config, ReteEvaluator reteEvaluator) { - return (RiaPathMemory) AbstractTerminalNode.initPathMemory( this, new RiaPathMemory(this, reteEvaluator) ); + protected void initInferredMask() { + BaseNode unwrappedRight = getParent(); + if ( unwrappedRight.getType() == NodeTypeEnums.AlphaNode ) { + AlphaNode alphaNode = (AlphaNode) unwrappedRight; + inferredMask = alphaNode.updateMask(declaredMask); + } else { + inferredMask = declaredMask; + } + inferredMask = inferredMask.resetAll(negativeMask); } - public void doAttach( BuildContext context ) { - this.tupleSource.addTupleSink( this, context ); + @Override + public boolean inputIsTupleToObjectNode() { + return inputIsTupleToObjectNode; } - public void networkUpdated(UpdateContext updateContext) { - this.tupleSource.networkUpdated(updateContext); + @Override + public void byPassModifyToBetaNode (final InternalFactHandle factHandle, + final ModifyPreviousTuples modifyPreviousTuples, + final PropagationContext context, + final ReteEvaluator reteEvaluator) { + modifyObject( factHandle, modifyPreviousTuples, context, reteEvaluator ); } - protected boolean doRemove(final RuleRemovalContext context, - final ReteooBuilder builder) { - if ( !isInUse() ) { - tupleSource.removeTupleSink(this); - return true; - } - return false; + public BitMask calculateDeclaredMask(ObjectType modifiedType, List settableProperties) { + return null; } - public boolean isLeftTupleMemoryEnabled() { - return tupleMemoryEnabled; + + public void updateSink(ObjectSink sink, PropagationContext context, InternalWorkingMemory workingMemory) { + source.updateSink(this, context, workingMemory ); } + @Override + public abstract void retractRightTuple(TupleImpl rightTuple, PropagationContext context, ReteEvaluator reteEvaluator); + + + @Override + public abstract void modifyRightTuple(TupleImpl rightTuple, PropagationContext context, ReteEvaluator reteEvaluator); + /** * Returns the next node * @return - * The next TupleSinkNode + * The next ObjectSinkNode */ - public LeftTupleSinkNode getNextLeftTupleSinkNode() { - return this.nextTupleSinkNode; + public ObjectSinkNode getNextObjectSinkNode() { + return this.nextObjectSinkNode; } /** * Sets the next node * @param next - * The next TupleSinkNode + * The next ObjectSinkNode */ - public void setNextLeftTupleSinkNode(final LeftTupleSinkNode next) { - this.nextTupleSinkNode = next; + public void setNextObjectSinkNode(final ObjectSinkNode next) { + this.nextObjectSinkNode = next; } /** * Returns the previous node * @return - * The previous TupleSinkNode + * The previous ObjectSinkNode */ - public LeftTupleSinkNode getPreviousLeftTupleSinkNode() { - return this.previousTupleSinkNode; + public ObjectSinkNode getPreviousObjectSinkNode() { + return this.previousObjectSinkNode; } /** * Sets the previous node * @param previous - * The previous TupleSinkNode + * The previous ObjectSinkNode */ - public void setPreviousLeftTupleSinkNode(final LeftTupleSinkNode previous) { - this.previousTupleSinkNode = previous; - } - - public int getType() { - return NodeTypeEnums.RightInputAdapterNode; - } - - private int calculateHashCode() { - return this.tupleSource.hashCode() * 17 + ((this.tupleMemoryEnabled) ? 1234 : 4321); + public void setPreviousObjectSinkNode(final ObjectSinkNode previous) { + this.previousObjectSinkNode = previous; } - @Override - public boolean equals(Object object) { - if (this == object) { - return true; - } - - return ((NetworkNode)object).getType() == NodeTypeEnums.RightInputAdapterNode && this.hashCode() == object.hashCode() && - this.tupleSource.getId() == ((RightInputAdapterNode)object).tupleSource.getId() && - this.tupleMemoryEnabled == ( (RightInputAdapterNode) object ).tupleMemoryEnabled; + void disablePropertyReactivity() { + inferredMask = AllSetBitMask.get(); } - @Override - public String toString() { - return "RightInputAdapterNode(" + id + ")[ tupleMemoryEnabled=" + tupleMemoryEnabled + ", tupleSource=" + tupleSource + ", source=" - + source + ", associations=" + associations + ", partitionId=" + partitionId + "]"; + public BitMask getNegativeMask() { + return negativeMask; } - public LeftTupleSource getLeftTupleSource() { - return this.tupleSource; + public ObjectTypeNodeId getInputOtnId() { + return inputOtnId; } - public void setTupleSource( LeftTupleSource tupleSource ) { - this.tupleSource = tupleSource; + public void setInputOtnId(ObjectTypeNodeId inputOtnId) { + this.inputOtnId = inputOtnId; } - public ObjectTypeNodeId getLeftInputOtnId() { - throw new UnsupportedOperationException(); + public boolean isRightInputPassive() { + return inputIsPassive; } - public void setLeftInputOtnId(ObjectTypeNodeId leftInputOtnId) { - throw new UnsupportedOperationException(); - } - @Override - public BitMask calculateDeclaredMask(Pattern pattern, ObjectType modifiedType, List settableProperties) { - throw new UnsupportedOperationException(); - } - - public static class RiaPathMemory extends PathMemory implements Memory { - private List rules; - - public RiaPathMemory(PathEndNode pathEndNode, ReteEvaluator reteEvaluator) { - super(pathEndNode, reteEvaluator); - } - - @Override - protected boolean initDataDriven( ReteEvaluator reteEvaluator ) { - for (PathEndNode pnode : getPathEndNode().getPathEndNodes()) { - if (NodeTypeEnums.isTerminalNode(pnode)) { - RuleImpl rule = ( (TerminalNode) pnode ).getRule(); - if ( isRuleDataDriven( reteEvaluator, rule ) ) { - return true; - } + public ObjectTypeNode getObjectTypeNode() { + if (objectTypeNode == null) { + ObjectSource source = this.source; + while ( source != null ) { + if ( NodeTypeEnums.ObjectTypeNode == source.getType()) { + objectTypeNode = (ObjectTypeNode) source; + break; } + source = source.source; } - return false; - } - - public RightInputAdapterNode getRightInputAdapterNode() { - return (RightInputAdapterNode) getPathEndNode(); - } - - @Override - public void doLinkRule(ReteEvaluator reteEvaluator) { - getRightInputAdapterNode().getObjectSinkPropagator().doLinkRiaNode( reteEvaluator ); - } - - @Override - public void doLinkRule(ActivationsManager activationsManager) { - doLinkRule(activationsManager.getReteEvaluator()); - } - - @Override - public void doUnlinkRule(ReteEvaluator reteEvaluator) { - getRightInputAdapterNode().getObjectSinkPropagator().doUnlinkRiaNode( reteEvaluator ); } + return objectTypeNode; + } - private void updateRuleTerminalNodes() { - rules = new ArrayList<>(); - for ( ObjectSink osink : getRightInputAdapterNode().getObjectSinkPropagator().getSinks() ) { - for ( LeftTupleSink ltsink : ((BetaNode)osink).getSinkPropagator().getSinks() ) { - findAndAddTN(ltsink, rules ); - } - } - } + @Override + public void doAttach(BuildContext context) { + super.doAttach(context); + this.source.addObjectSink(this); + } - private void findAndAddTN( LeftTupleSink ltsink, List terminalNodes) { - if ( NodeTypeEnums.isTerminalNode(ltsink)) { - terminalNodes.add( ((TerminalNode)ltsink).getRule() ); - } else if ( ltsink.getType() == NodeTypeEnums.RightInputAdapterNode) { - for ( NetworkNode childSink : ( ltsink).getSinks() ) { - findAndAddTN((LeftTupleSink)childSink, terminalNodes); - } - } else { - for ( LeftTupleSink childLtSink : (ltsink).getSinkPropagator().getSinks() ) { - findAndAddTN(childLtSink, terminalNodes); - } - } + @Override + public boolean doRemove(RuleRemovalContext context, ReteooBuilder builder) { + if ( !isInUse() ) { + source.removeObjectSink(this); + return true; } + return false; + } - public List getAssociatedRules() { - if ( rules == null ) { - updateRuleTerminalNodes(); - } - return rules; - } + @Override + public boolean isInUse() { + return betaNode.isInUse(); + } - public String getRuleNames() { - Set ruleNames = new HashSet<>(); - for (RuleImpl rule : getAssociatedRules()) { - ruleNames.add(rule.getName()); - } - return ruleNames.toString(); + protected int calculateHashCode() { + int hash = 29 * source.hashCode(); + if (listenedProperties != null) { + hash += 41 * listenedProperties.hashCode(); } + return hash + (inputIsPassive ? 43 : 0); + } - @Override - public int getNodeType() { - return NodeTypeEnums.RightInputAdapterNode; + @Override + public boolean equals(Object object) { + if (this == object) { + return true; } - public String toString() { - return "RiaMem(" + getRightInputAdapterNode().getId() + ") [" +getRuleNames() + "]"; + if ( //!NodeTypeEnums.isBetaNode((NetworkNode)object) || + this.hashCode() != object.hashCode()) { + return false; } - } - public BitMask getLeftInferredMask() { - throw new UnsupportedOperationException(); + RightInputAdapterNode other = (RightInputAdapterNode) object; + return this.getClass() == other.getClass() && + this.inputIsPassive == other.inputIsPassive && + Objects.equals(this.listenedProperties, other.listenedProperties) && + this.source.getId() == other.source.getId(); } @Override - public void updateSink(ObjectSink sink, PropagationContext context, InternalWorkingMemory wm) { - throw new UnsupportedOperationException(); - } - - public LeftTupleNode[] getPathNodes() { - if (pathNodes == null) { - pathNodes = AbstractTerminalNode.getPathNodes( this ); - } - return pathNodes; + public String toString() { + return "RightInputAdapterNode(" + id + ")[ source=" + + source + ", associations=" + associations + ", partitionId=" + partitionId + "]"; } - public boolean hasPathNode(LeftTupleNode node) { - for (LeftTupleNode pathNode : getPathNodes()) { - if (node.getId() == pathNode.getId()) { - return true; - } - } - return false; + public void networkUpdated(UpdateContext updateContext) { + this.source.networkUpdated(updateContext); } - public LeftTupleSinkPropagator getSinkPropagator() { - return EmptyLeftTupleSinkAdapter.getInstance(); + public final void setPartitionIdWithSinks( RuleBasePartitionId partitionId) { + this.partitionId = partitionId; } - @Override - public void addAssociation( BuildContext context, Rule rule ) { - super.addAssociation(context, rule); - context.addPathEndNode( this ); + public BitMask getDeclaredMask() { + return declaredMask; } - @Override - public boolean removeAssociation( Rule rule, RuleRemovalContext context ) { - boolean result = super.associations.remove(rule); - if (getAssociationsSize() == 0) { - // avoid to recalculate the pathEndNodes if this node is going to be removed - return result; - } - - List remainingPathNodes = new ArrayList<>(); - for (PathEndNode pathEndNode : pathEndNodes) { - if (pathEndNode.getAssociatedTerminalsSize() > 0) { - remainingPathNodes.add(pathEndNode); - } - } - pathEndNodes = remainingPathNodes.toArray( new PathEndNode[remainingPathNodes.size()] ); - return result; + public BitMask getInferredMask() { + return inferredMask; } - } diff --git a/drools-core/src/main/java/org/drools/core/reteoo/RightTuple.java b/drools-core/src/main/java/org/drools/core/reteoo/RightTuple.java index 7339010899a..4f43608398c 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/RightTuple.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/RightTuple.java @@ -189,7 +189,7 @@ public void setExpired( ReteEvaluator reteEvaluator, PropagationContext pctx ) { super.setExpired(); // events expired at firing time should have a chance to produce a join (DROOLS-1329) // but shouldn't participate to an accumulate (DROOLS-4393) - if (this.getSink().getType() == NodeTypeEnums.AccumulateNode) { + if (this.getSink().getType() == NodeTypeEnums.AccumulateRightAdapterNode) { retractTuple( pctx, reteEvaluator ); } } diff --git a/drools-core/src/main/java/org/drools/core/reteoo/RightTupleSink.java b/drools-core/src/main/java/org/drools/core/reteoo/RightTupleSink.java index be79eb3fd5f..6f4ad29f117 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/RightTupleSink.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/RightTupleSink.java @@ -31,7 +31,7 @@ void modifyRightTuple(final TupleImpl rightTuple, final PropagationContext context, final ReteEvaluator reteEvaluator); - default ObjectTypeNodeId getRightInputOtnId() { + default ObjectTypeNodeId getInputOtnId() { return null; } diff --git a/drools-core/src/main/java/org/drools/core/reteoo/RuleTerminalNode.java b/drools-core/src/main/java/org/drools/core/reteoo/RuleTerminalNode.java index 097cd7aa947..52ddbcbee1a 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/RuleTerminalNode.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/RuleTerminalNode.java @@ -98,7 +98,7 @@ public String toString() { public void doAttach( BuildContext context ) { super.doAttach(context); getLeftTupleSource().addTupleSink(this, context); - addAssociation( context, context.getRule() ); + addAssociation(context.getRule(), context); } void initDeclarations(Map decls, final BuildContext context) { @@ -160,11 +160,11 @@ public int getType() { return NodeTypeEnums.RuleTerminalNode; } - public ObjectTypeNodeId getLeftInputOtnId() { + public ObjectTypeNodeId getInputOtnId() { return leftInputOtnId; } - public void setLeftInputOtnId(ObjectTypeNodeId leftInputOtnId) { + public void setInputOtnId(ObjectTypeNodeId leftInputOtnId) { this.leftInputOtnId = leftInputOtnId; } diff --git a/drools-core/src/main/java/org/drools/core/reteoo/SegmentMemory.java b/drools-core/src/main/java/org/drools/core/reteoo/SegmentMemory.java index 90968320ee9..34ec420b68c 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/SegmentMemory.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/SegmentMemory.java @@ -34,7 +34,7 @@ import org.drools.core.phreak.RuntimeSegmentUtilities; import org.drools.core.reteoo.AsyncReceiveNode.AsyncReceiveMemory; import org.drools.core.reteoo.QueryElementNode.QueryElementNodeMemory; -import org.drools.core.reteoo.RightInputAdapterNode.RiaPathMemory; +import org.drools.core.reteoo.TupleToObjectNode.SubnetworkPathMemory; import org.drools.core.reteoo.TimerNode.TimerNodeMemory; import org.drools.core.util.LinkedList; import org.drools.core.util.DoubleLinkedEntry; @@ -291,7 +291,7 @@ public void mergePathMemories(SegmentMemory segmentMemory) { } private boolean isAssociatedWith( PathMemory pmem ) { - if (NodeTypeEnums.RightInputAdapterNode == pmem.getNodeType()) { + if (NodeTypeEnums.TupleToObjectNode == pmem.getNodeType()) { for (PathEndNode endNode : pmem.getPathEndNode().getPathEndNodes() ) { if (NodeTypeEnums.isTerminalNode(endNode)) { if ( proto.getRootNode().hasAssociatedTerminal((AbstractTerminalNode)endNode)) { @@ -611,7 +611,7 @@ public abstract static class MemoryPrototype { public static MemoryPrototype get(Memory memory) { if (memory instanceof BetaMemory) { BetaMemory betaMemory = (BetaMemory)memory; - return new BetaMemoryPrototype(betaMemory.getNodePosMaskBit(), betaMemory.getRiaRuleMemory() != null ? betaMemory.getRiaRuleMemory().getRightInputAdapterNode() : null); + return new BetaMemoryPrototype(betaMemory.getNodePosMaskBit(), betaMemory.getSubnetworkPathMemory() != null ? betaMemory.getSubnetworkPathMemory().getTupleToObjectNode() : null); } if (memory instanceof LeftInputAdapterNode.LiaNodeMemory) { return new LiaMemoryPrototype(((LeftInputAdapterNode.LiaNodeMemory)memory).getNodePosMaskBit()); @@ -625,7 +625,7 @@ public static MemoryPrototype get(Memory memory) { } if (memory instanceof AccumulateNode.AccumulateMemory) { BetaMemory betaMemory = ((AccumulateNode.AccumulateMemory)memory).getBetaMemory(); - return new AccumulateMemoryPrototype(new BetaMemoryPrototype( betaMemory.getNodePosMaskBit(), betaMemory.getRiaRuleMemory() != null ? betaMemory.getRiaRuleMemory().getRightInputAdapterNode() : null) ); + return new AccumulateMemoryPrototype(new BetaMemoryPrototype( betaMemory.getNodePosMaskBit(), betaMemory.getSubnetworkPathMemory() != null ? betaMemory.getSubnetworkPathMemory().getTupleToObjectNode() : null) ); } if (memory instanceof ReactiveFromNode.ReactiveFromMemory) { return new ReactiveFromMemoryPrototype(((ReactiveFromNode.ReactiveFromMemory)memory).getNodePosMaskBit()); @@ -645,23 +645,23 @@ public long getNodePosMaskBit() { } public static class BetaMemoryPrototype extends MemoryPrototype { - private final RightInputAdapterNode riaNode; + private final TupleToObjectNode tton; - public BetaMemoryPrototype(long nodePosMaskBit, RightInputAdapterNode riaNode) { + public BetaMemoryPrototype(long nodePosMaskBit, TupleToObjectNode tton) { this.nodePosMaskBit = nodePosMaskBit; - this.riaNode = riaNode; + this.tton = tton; } @Override public void populateMemory(ReteEvaluator reteEvaluator, Memory memory) { BetaMemory betaMemory = (BetaMemory)memory; betaMemory.setNodePosMaskBit(nodePosMaskBit); - if (riaNode != null) { - RiaPathMemory riaMem = (RiaPathMemory) reteEvaluator.getNodeMemories().peekNodeMemory(riaNode); + if (tton != null) { + SubnetworkPathMemory riaMem = (SubnetworkPathMemory) reteEvaluator.getNodeMemories().peekNodeMemory(tton); if (riaMem == null) { - riaMem = ( RiaPathMemory) RuntimeSegmentUtilities.initializePathMemory(reteEvaluator, riaNode); + riaMem = (SubnetworkPathMemory) RuntimeSegmentUtilities.initializePathMemory(reteEvaluator, tton); } - betaMemory.setRiaRuleMemory(riaMem); + betaMemory.setSubnetworkPathMemory(riaMem); } } } diff --git a/drools-core/src/main/java/org/drools/core/reteoo/SingleObjectSinkAdapter.java b/drools-core/src/main/java/org/drools/core/reteoo/SingleObjectSinkAdapter.java index b6a93ad781b..b2c09470618 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/SingleObjectSinkAdapter.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/SingleObjectSinkAdapter.java @@ -87,47 +87,46 @@ public void byPassModifyToBetaNode (final InternalFactHandle factHandle, sink.byPassModifyToBetaNode( factHandle, modifyPreviousTuples, context, reteEvaluator ); } - public void doLinkRiaNode(ReteEvaluator reteEvaluator) { - staticDoLinkRiaNode( sink, reteEvaluator ); + public void doLinkSubnetwork(ReteEvaluator reteEvaluator) { + staticDoLinkSubnetwork(sink, reteEvaluator); } - public static void staticDoLinkRiaNode(ObjectSink sink, ReteEvaluator reteEvaluator) { + public static void staticDoLinkSubnetwork(ObjectSink sink, ReteEvaluator reteEvaluator) { BetaMemory bm; - if ( sink.getType() == NodeTypeEnums.AccumulateNode ) { - AccumulateNode accnode = ( AccumulateNode ) sink; - AccumulateMemory accMem = ( AccumulateMemory ) reteEvaluator.getNodeMemory( accnode ); + BetaNode betaNode; + if ( sink.getType() == NodeTypeEnums.AccumulateRightAdapterNode ) { + AccumulateRight accnode = ( AccumulateRight ) sink; + betaNode = accnode.getBetaNode(); + AccumulateMemory accMem = ( AccumulateMemory ) reteEvaluator.getNodeMemory( betaNode ); bm = accMem.getBetaMemory(); - } else if ( NodeTypeEnums.isBetaNode( sink ) ) { - BetaNode betaNode = ( BetaNode ) sink; - bm = (BetaMemory) BetaNode.getBetaMemoryFromRightInput(betaNode, reteEvaluator); } else { - throw new RuntimeException( "Should not be possible to have link into a node of type" + sink); + RightInputAdapterNode betaRight = (RightInputAdapterNode) sink; + betaNode = betaRight.getBetaNode(); + bm = RightInputAdapterNode.getBetaMemoryFromRightInput(betaNode, reteEvaluator); } if ( bm.getStagedRightTuples().isEmpty() ) { if ( bm.getRightTupleMemory().size() == 0 ) { - bm.linkNode( ( BetaNode ) sink, reteEvaluator ); + bm.linkNode( betaNode, reteEvaluator ); } else { - bm.setNodeDirty( ( BetaNode ) sink, reteEvaluator ); + bm.setNodeDirty( betaNode, reteEvaluator ); } } } - public void doUnlinkRiaNode( ReteEvaluator reteEvaluator) { - staticDoUnlinkRiaNode( sink, reteEvaluator ); + public void doUnlinkSubnetwork(ReteEvaluator reteEvaluator) { + staticDoUnlinkSubnetwork(sink, reteEvaluator); } - public static void staticDoUnlinkRiaNode(ObjectSink sink, ReteEvaluator reteEvaluator) { + public static void staticDoUnlinkSubnetwork(ObjectSink sink, ReteEvaluator reteEvaluator) { BetaMemory bm; - if ( sink.getType() == NodeTypeEnums.AccumulateNode ) { - AccumulateNode accnode = ( AccumulateNode ) sink; + if ( sink.getType() == NodeTypeEnums.AccumulateRightAdapterNode ) { + AccumulateNode accnode = ((AccumulateRight)sink).getBetaNode(); AccumulateMemory accMem = ( AccumulateMemory ) reteEvaluator.getNodeMemory( accnode ); bm = accMem.getBetaMemory(); - } else if ( NodeTypeEnums.isBetaNode( sink ) ) { - BetaNode betaNode = ( BetaNode ) sink; - bm = (BetaMemory) BetaNode.getBetaMemoryFromRightInput(betaNode, reteEvaluator); - } else { - throw new RuntimeException( "Should not be possible to have link into a node of type" + sink); + } else { + BetaNode betaNode = ((RightInputAdapterNode) sink).getBetaNode(); + bm = RightInputAdapterNode.getBetaMemoryFromRightInput(betaNode, reteEvaluator); } if (sink.getType() == NodeTypeEnums.NotNode) { diff --git a/drools-core/src/main/java/org/drools/core/reteoo/TimerNode.java b/drools-core/src/main/java/org/drools/core/reteoo/TimerNode.java index 41a63759824..e0bf8207fc4 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/TimerNode.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/TimerNode.java @@ -70,7 +70,7 @@ public TimerNode(final int id, this.startEndDeclarations = startEndDeclarations; this.tupleMemoryEnabled = context.isTupleMemoryEnabled(); - initMasks(context, tupleSource); + initMasks(context); hashcode = calculateHashCode(); diff --git a/drools-core/src/main/java/org/drools/core/reteoo/TupleFactory.java b/drools-core/src/main/java/org/drools/core/reteoo/TupleFactory.java index f0f9d7a1c6b..fc4dc2c5f10 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/TupleFactory.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/TupleFactory.java @@ -45,7 +45,7 @@ public static TupleImpl createPeer(Sink n, TupleImpl original) { case NodeTypeEnums.ReactiveFromNode: peer = new ReactiveFromNodeLeftTuple(); break; - case NodeTypeEnums.RightInputAdapterNode: + case NodeTypeEnums.TupleToObjectNode: peer = new SubnetworkTuple(); break; case NodeTypeEnums.QueryTerminalNode: @@ -82,7 +82,7 @@ public static TupleImpl createLeftTuple(Sink s, return new EvalNodeLeftTuple(factHandle, s, leftTupleMemoryEnabled); case NodeTypeEnums.ReactiveFromNode: return new ReactiveFromNodeLeftTuple(factHandle, s, leftTupleMemoryEnabled); - case NodeTypeEnums.RightInputAdapterNode: + case NodeTypeEnums.TupleToObjectNode: return new SubnetworkTuple(factHandle, s, leftTupleMemoryEnabled); case NodeTypeEnums.QueryTerminalNode: case NodeTypeEnums.RuleTerminalNode: @@ -112,7 +112,7 @@ public static TupleImpl createLeftTuple(final InternalFactHandle factHandle, return new EvalNodeLeftTuple(factHandle, leftTuple, s); case NodeTypeEnums.ReactiveFromNode: return new ReactiveFromNodeLeftTuple(factHandle, leftTuple, s); - case NodeTypeEnums.RightInputAdapterNode: + case NodeTypeEnums.TupleToObjectNode: return new SubnetworkTuple(factHandle, leftTuple, s); case NodeTypeEnums.QueryTerminalNode: case NodeTypeEnums.RuleTerminalNode: @@ -143,7 +143,7 @@ public static TupleImpl createLeftTuple(TupleImpl leftTuple, return new EvalNodeLeftTuple(leftTuple, s, pctx, leftTupleMemoryEnabled); case NodeTypeEnums.ReactiveFromNode: throw new IllegalStateException("ReactFromNode does not implement this constructor."); - case NodeTypeEnums.RightInputAdapterNode: + case NodeTypeEnums.TupleToObjectNode: return new SubnetworkTuple(leftTuple, s, pctx, leftTupleMemoryEnabled); case NodeTypeEnums.QueryTerminalNode: case NodeTypeEnums.RuleTerminalNode: @@ -173,7 +173,7 @@ public static TupleImpl createLeftTuple(TupleImpl leftTuple, return new EvalNodeLeftTuple(leftTuple, rightTuple, s); case NodeTypeEnums.ReactiveFromNode: throw new IllegalStateException("ReactFromNode does not implement this constructor."); - case NodeTypeEnums.RightInputAdapterNode: + case NodeTypeEnums.TupleToObjectNode: return new SubnetworkTuple(leftTuple, rightTuple, s); case NodeTypeEnums.QueryTerminalNode: case NodeTypeEnums.RuleTerminalNode: @@ -206,7 +206,7 @@ public static TupleImpl createLeftTuple(TupleImpl leftTuple, return new EvalNodeLeftTuple(leftTuple, rightTuple, currentLeftChild, currentRightChild, s, leftTupleMemoryEnabled); case NodeTypeEnums.ReactiveFromNode: return new ReactiveFromNodeLeftTuple(leftTuple, rightTuple, currentLeftChild, currentRightChild, s, leftTupleMemoryEnabled); - case NodeTypeEnums.RightInputAdapterNode: + case NodeTypeEnums.TupleToObjectNode: return new SubnetworkTuple(leftTuple, rightTuple, currentLeftChild, currentRightChild, s, leftTupleMemoryEnabled); case NodeTypeEnums.QueryTerminalNode: case NodeTypeEnums.RuleTerminalNode: diff --git a/drools-core/src/main/java/org/drools/core/reteoo/TupleToObjectNode.java b/drools-core/src/main/java/org/drools/core/reteoo/TupleToObjectNode.java new file mode 100644 index 00000000000..6712dc63bd0 --- /dev/null +++ b/drools-core/src/main/java/org/drools/core/reteoo/TupleToObjectNode.java @@ -0,0 +1,437 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.drools.core.reteoo; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.drools.base.base.ObjectType; +import org.drools.base.common.NetworkNode; +import org.drools.base.definitions.rule.impl.RuleImpl; +import org.drools.base.reteoo.NodeTypeEnums; +import org.drools.base.rule.Pattern; +import org.drools.core.RuleBaseConfiguration; +import org.drools.core.common.ActivationsManager; +import org.drools.core.common.InternalWorkingMemory; +import org.drools.core.common.Memory; +import org.drools.core.common.PropagationContext; +import org.drools.core.common.ReteEvaluator; +import org.drools.core.common.UpdateContext; +import org.drools.core.reteoo.SegmentMemory.SegmentPrototype; +import org.drools.core.reteoo.builder.BuildContext; +import org.drools.util.bitmask.BitMask; +import org.kie.api.definition.rule.Rule; + +/** + * When joining a subnetwork into the main network again, TupleToObjectNode adapts the + * subnetwork's tuple into a fact in order right join it with the tuple being propagated in + * the main network. + */ +public class TupleToObjectNode extends ObjectSource + implements + LeftTupleSinkNode, + PathEndNode { + + private static final long serialVersionUID = 510l; + + private LeftTupleSource tupleSource; + + /** + * This is first node inside of the subnetwork. The split, with two outs, would be the parent node. + */ + private LeftTupleSource startTupleSource; + + private boolean tupleMemoryEnabled; + + private LeftTupleSinkNode previousTupleSinkNode; + private LeftTupleSinkNode nextTupleSinkNode; + + private LeftTupleNode[] pathNodes; + + private PathEndNode[] pathEndNodes; + + private PathMemSpec pathMemSpec; + + private SegmentPrototype[] segmentPrototypes; + + private SegmentPrototype[] eagerSegmentPrototypes; + + private int objectCount; + + public TupleToObjectNode() { + } + + /** + * Constructor specifying the unique id of the node in the Rete network, the position of the propagating FactHandleImpl in + * ReteTuple and the source that propagates the receive ReteTuples. + * + * @param id + * Unique id + * @param source + * The TupleSource which propagates the received ReteTuple + */ + public TupleToObjectNode(final int id, + final LeftTupleSource source, + final LeftTupleSource startTupleSource, + final BuildContext context) { + super( id, context.getPartitionId() ); + this.tupleSource = source; + this.tupleMemoryEnabled = context.isTupleMemoryEnabled(); + this.startTupleSource = startTupleSource; + + hashcode = calculateHashCode(); + initMemoryId( context ); + } + + @Override + public PathMemSpec getPathMemSpec() { + return getPathMemSpec(null); + } + + + /** + * used during network build time, potentially during rule removal time. + * @param removingTN + * @return + */ + @Override + public PathMemSpec getPathMemSpec(TerminalNode removingTN) { + if (pathMemSpec == null) { + pathMemSpec = calculatePathMemSpec( startTupleSource, removingTN ); + } + return pathMemSpec; + } + + + @Override + public void nullPathMemSpec() { + pathMemSpec = null; + } + + @Override + public void setPathMemSpec(PathMemSpec pathMemSpec) { + this.pathMemSpec = pathMemSpec; + } + + @Override + public void resetPathMemSpec(TerminalNode removingTN) { + nullPathMemSpec(); + pathMemSpec = getPathMemSpec(removingTN); + } + + @Override + public void setSegmentPrototypes(SegmentPrototype[] smems) { + this.segmentPrototypes = smems; + } + + @Override + public SegmentPrototype[] getSegmentPrototypes() { + return segmentPrototypes; + } + + @Override + public SegmentPrototype[] getEagerSegmentPrototypes() { + return eagerSegmentPrototypes; + } + + @Override + public void setEagerSegmentPrototypes(SegmentPrototype[] eagerSegmentPrototypes) { + this.eagerSegmentPrototypes = eagerSegmentPrototypes; + } + + @Override + public void setPathEndNodes(PathEndNode[] pathEndNodes) { + this.pathEndNodes = pathEndNodes; + } + + @Override + public PathEndNode[] getPathEndNodes() { + return pathEndNodes; + } + + public LeftTupleSource getStartTupleSource() { + return startTupleSource; + } + + public int getPathIndex() { + return tupleSource.getPathIndex() + 1; + } + + public int getObjectCount() { + return objectCount; + } + + public void setObjectCount(int count) { + objectCount = count; + } + + /** + * Creates and return the node memory + */ + public SubnetworkPathMemory createMemory(final RuleBaseConfiguration config, ReteEvaluator reteEvaluator) { + return (SubnetworkPathMemory) AbstractTerminalNode.initPathMemory(this, new SubnetworkPathMemory(this, reteEvaluator)); + } + + public void doAttach( BuildContext context ) { + this.tupleSource.addTupleSink( this, context ); + } + + public void networkUpdated(UpdateContext updateContext) { + this.tupleSource.networkUpdated(updateContext); + } + + + protected boolean doRemove(final RuleRemovalContext context, + final ReteooBuilder builder) { + if ( !isInUse() ) { + tupleSource.removeTupleSink(this); + return true; + } + return false; + } + + public boolean isLeftTupleMemoryEnabled() { + return tupleMemoryEnabled; + } + + /** + * Returns the next node + * @return + * The next TupleSinkNode + */ + public LeftTupleSinkNode getNextLeftTupleSinkNode() { + return this.nextTupleSinkNode; + } + + /** + * Sets the next node + * @param next + * The next TupleSinkNode + */ + public void setNextLeftTupleSinkNode(final LeftTupleSinkNode next) { + this.nextTupleSinkNode = next; + } + + /** + * Returns the previous node + * @return + * The previous TupleSinkNode + */ + public LeftTupleSinkNode getPreviousLeftTupleSinkNode() { + return this.previousTupleSinkNode; + } + + /** + * Sets the previous node + * @param previous + * The previous TupleSinkNode + */ + public void setPreviousLeftTupleSinkNode(final LeftTupleSinkNode previous) { + this.previousTupleSinkNode = previous; + } + + public int getType() { + return NodeTypeEnums.TupleToObjectNode; + } + + private int calculateHashCode() { + return this.tupleSource.hashCode() * 17 + ((this.tupleMemoryEnabled) ? 1234 : 4321); + } + + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + + return ((NetworkNode)object).getType() == NodeTypeEnums.TupleToObjectNode && this.hashCode() == object.hashCode() && + this.tupleSource.getId() == ((TupleToObjectNode)object).tupleSource.getId() && + this.tupleMemoryEnabled == ( (TupleToObjectNode) object ).tupleMemoryEnabled; + } + + @Override + public String toString() { + return "RightInputAdapterNode(" + id + ")[ tupleMemoryEnabled=" + tupleMemoryEnabled + ", tupleSource=" + tupleSource + ", source=" + + source + ", associations=" + associations + ", partitionId=" + partitionId + "]"; + } + + public LeftTupleSource getLeftTupleSource() { + return this.tupleSource; + } + + public void setTupleSource( LeftTupleSource tupleSource ) { + this.tupleSource = tupleSource; + } + + public ObjectTypeNodeId getInputOtnId() { + throw new UnsupportedOperationException(); + } + + public void setInputOtnId(ObjectTypeNodeId leftInputOtnId) { + throw new UnsupportedOperationException(); + } + + @Override + public BitMask calculateDeclaredMask(Pattern pattern, ObjectType modifiedType, List settableProperties) { + throw new UnsupportedOperationException(); + } + + public static class SubnetworkPathMemory extends PathMemory implements Memory { + private List rules; + + public SubnetworkPathMemory(PathEndNode pathEndNode, ReteEvaluator reteEvaluator) { + super(pathEndNode, reteEvaluator); + } + + @Override + protected boolean initDataDriven( ReteEvaluator reteEvaluator ) { + for (PathEndNode pnode : getPathEndNode().getPathEndNodes()) { + if (NodeTypeEnums.isTerminalNode(pnode)) { + RuleImpl rule = ( (TerminalNode) pnode ).getRule(); + if ( isRuleDataDriven( reteEvaluator, rule ) ) { + return true; + } + } + } + return false; + } + + public TupleToObjectNode getTupleToObjectNode() { + return (TupleToObjectNode) getPathEndNode(); + } + + @Override + public void doLinkRule(ReteEvaluator reteEvaluator) { + getTupleToObjectNode().getObjectSinkPropagator().doLinkSubnetwork(reteEvaluator); + } + + @Override + public void doLinkRule(ActivationsManager activationsManager) { + doLinkRule(activationsManager.getReteEvaluator()); + } + + @Override + public void doUnlinkRule(ReteEvaluator reteEvaluator) { + getTupleToObjectNode().getObjectSinkPropagator().doUnlinkSubnetwork(reteEvaluator); + } + + private void updateRuleTerminalNodes() { + rules = new ArrayList<>(); + for ( ObjectSink osink : getTupleToObjectNode().getObjectSinkPropagator().getSinks() ) { + for ( LeftTupleSink ltsink : ((BetaNode)osink).getSinkPropagator().getSinks() ) { + findAndAddTN(ltsink, rules ); + } + } + } + + private void findAndAddTN( LeftTupleSink ltsink, List terminalNodes) { + if ( NodeTypeEnums.isTerminalNode(ltsink)) { + terminalNodes.add( ((TerminalNode)ltsink).getRule() ); + } else if ( ltsink.getType() == NodeTypeEnums.TupleToObjectNode) { + for ( NetworkNode childSink : ( ltsink).getSinks() ) { + findAndAddTN((LeftTupleSink)childSink, terminalNodes); + } + } else { + for ( LeftTupleSink childLtSink : (ltsink).getSinkPropagator().getSinks() ) { + findAndAddTN(childLtSink, terminalNodes); + } + } + } + + public List getAssociatedRules() { + if ( rules == null ) { + updateRuleTerminalNodes(); + } + return rules; + } + + public String getRuleNames() { + Set ruleNames = new HashSet<>(); + for (RuleImpl rule : getAssociatedRules()) { + ruleNames.add(rule.getName()); + } + return ruleNames.toString(); + } + + @Override + public int getNodeType() { + return NodeTypeEnums.TupleToObjectNode; + } + + public String toString() { + return "TupleToObjectNodeMem(" + getTupleToObjectNode().getId() + ") [" + getRuleNames() + "]"; + } + } + + public BitMask getInferredMask() { + throw new UnsupportedOperationException(); + } + + @Override + public void updateSink(ObjectSink sink, PropagationContext context, InternalWorkingMemory wm) { + throw new UnsupportedOperationException(); + } + + public LeftTupleNode[] getPathNodes() { + if (pathNodes == null) { + pathNodes = AbstractTerminalNode.getPathNodes( this ); + } + return pathNodes; + } + + public boolean hasPathNode(LeftTupleNode node) { + for (LeftTupleNode pathNode : getPathNodes()) { + if (node.getId() == pathNode.getId()) { + return true; + } + } + return false; + } + + public LeftTupleSinkPropagator getSinkPropagator() { + return EmptyLeftTupleSinkAdapter.getInstance(); + } + + @Override + public void addAssociation(Rule rule, BuildContext context) { + super.addAssociation(rule, context); + context.addPathEndNode( this ); + } + + @Override + public boolean removeAssociation( Rule rule, RuleRemovalContext context ) { + boolean result = super.associations.remove(rule); + if (getAssociationsSize() == 0) { + // avoid to recalculate the pathEndNodes if this node is going to be removed + return result; + } + + List remainingPathNodes = new ArrayList<>(); + for (PathEndNode pathEndNode : pathEndNodes) { + if (pathEndNode.getAssociatedTerminalsSize() > 0) { + remainingPathNodes.add(pathEndNode); + } + } + pathEndNodes = remainingPathNodes.toArray( new PathEndNode[remainingPathNodes.size()] ); + return result; + } + +} diff --git a/drools-core/src/main/java/org/drools/core/reteoo/WindowNode.java b/drools-core/src/main/java/org/drools/core/reteoo/WindowNode.java index d4edd37b8fa..d3f54b76df5 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/WindowNode.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/WindowNode.java @@ -197,7 +197,7 @@ public void modifyObject(InternalFactHandle factHandle, TupleImpl rightTuple = modifyPreviousTuples.peekRightTuple(partitionId); // if the peek is for a different OTN we assume that it is after the current one and then this is an assert - while ( rightTuple != null && rightTuple.getInputOtnId().before(getRightInputOtnId()) ) { + while ( rightTuple != null && rightTuple.getInputOtnId().before(getInputOtnId()) ) { modifyPreviousTuples.removeRightTuple(partitionId); // we skipped this node, due to alpha hashing, so retract now @@ -206,7 +206,7 @@ public void modifyObject(InternalFactHandle factHandle, rightTuple = modifyPreviousTuples.peekRightTuple(partitionId); } - if ( rightTuple != null && rightTuple.getInputOtnId().equals(getRightInputOtnId()) ) { + if ( rightTuple != null && rightTuple.getInputOtnId().equals(getInputOtnId()) ) { modifyPreviousTuples.removeRightTuple(partitionId); rightTuple.reAdd(); modifyRightTuple( rightTuple, context, reteEvaluator ); @@ -354,7 +354,7 @@ public Collection getFactHandles() { } } - public ObjectTypeNodeId getRightInputOtnId() { + public ObjectTypeNodeId getInputOtnId() { return rightInputOtnId; } diff --git a/drools-core/src/main/java/org/drools/core/reteoo/builder/AccumulateBuilder.java b/drools-core/src/main/java/org/drools/core/reteoo/builder/AccumulateBuilder.java index f5c9b2ac48d..5ebbfce3660 100755 --- a/drools-core/src/main/java/org/drools/core/reteoo/builder/AccumulateBuilder.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/builder/AccumulateBuilder.java @@ -29,7 +29,7 @@ import org.drools.core.reteoo.AccumulateNode; import org.drools.core.reteoo.CoreComponentFactory; import org.drools.core.reteoo.LeftTupleSource; -import org.drools.core.reteoo.RightInputAdapterNode; +import org.drools.core.reteoo.TupleToObjectNode; import org.drools.base.rule.constraint.BetaConstraint; public class AccumulateBuilder @@ -70,13 +70,13 @@ public void build(final BuildContext context, // if object source is null, then we need to adapt tuple source into a subnetwork if ( context.getObjectSource() == null ) { // attach right input adapter node to convert tuple source into an object source - RightInputAdapterNode riaNode = CoreComponentFactory.get().getNodeFactoryService().buildRightInputNode( context.getNextNodeId(), - context.getTupleSource(), - tupleSource, - context ); + TupleToObjectNode tton = CoreComponentFactory.get().getNodeFactoryService().buildRightInputNode(context.getNextNodeId(), + context.getTupleSource(), + tupleSource, + context); // attach right input adapter node to convert tuple source into an object source - context.setObjectSource( utils.attachNode( context, riaNode ) ); + context.setObjectSource( utils.attachNode( context, tton ) ); // restore tuple source from before the start of the sub network context.setTupleSource( tupleSource ); diff --git a/drools-core/src/main/java/org/drools/core/reteoo/builder/BuildUtils.java b/drools-core/src/main/java/org/drools/core/reteoo/builder/BuildUtils.java index aedd6b4e120..6a5b8be78eb 100755 --- a/drools-core/src/main/java/org/drools/core/reteoo/builder/BuildUtils.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/builder/BuildUtils.java @@ -135,7 +135,7 @@ public T attachNode(BuildContext context, T candidate) { } partition = context.getPartitionId(); } - // set node whit the actual partition label + // set node with the actual partition label node.setPartitionId( context, partition ); node.attach(context); } else { @@ -151,7 +151,7 @@ public T attachNode(BuildContext context, T candidate) { } // adds the node to the context list to track all added nodes context.getNodes().add( node ); - node.addAssociation( context, context.getRule() ); + node.addAssociation(context.getRule(), context); return (T)node; } @@ -184,7 +184,7 @@ private boolean isSharingEnabledForNode(BuildContext context, BaseNode node) { } private boolean areNodesCompatibleForSharing(BuildContext context, BaseNode node) { - if ( node.getType() == NodeTypeEnums.RightInputAdapterNode) { + if ( node.getType() == NodeTypeEnums.TupleToObjectNode) { // avoid subnetworks sharing when they belong to 2 different agenda-groups String agendaGroup = context.getRule().getAgendaGroup(); for (Rule associatedRule : node.getAssociatedRules()) { diff --git a/drools-core/src/main/java/org/drools/core/reteoo/builder/CollectBuilder.java b/drools-core/src/main/java/org/drools/core/reteoo/builder/CollectBuilder.java index da62bed442f..6ce56a83d2d 100755 --- a/drools-core/src/main/java/org/drools/core/reteoo/builder/CollectBuilder.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/builder/CollectBuilder.java @@ -33,7 +33,7 @@ import org.drools.core.reteoo.AccumulateNode; import org.drools.core.reteoo.CoreComponentFactory; import org.drools.core.reteoo.LeftTupleSource; -import org.drools.core.reteoo.RightInputAdapterNode; +import org.drools.core.reteoo.TupleToObjectNode; import org.drools.base.rule.constraint.BetaConstraint; public class CollectBuilder @@ -69,13 +69,13 @@ public void build(final BuildContext context, // if object source is null, then we need to adapt tuple source into a subnetwork if ( context.getObjectSource() == null ) { - RightInputAdapterNode riaNode = CoreComponentFactory.get().getNodeFactoryService().buildRightInputNode( context.getNextNodeId(), - context.getTupleSource(), - tupleSource, - context ); + TupleToObjectNode tton = CoreComponentFactory.get().getNodeFactoryService().buildRightInputNode(context.getNextNodeId(), + context.getTupleSource(), + tupleSource, + context); // attach right input adapter node to convert tuple source into an object source - context.setObjectSource( utils.attachNode( context, riaNode ) ); + context.setObjectSource( utils.attachNode( context, tton ) ); // restore tuple source from before the start of the sub network context.setTupleSource( tupleSource ); diff --git a/drools-core/src/main/java/org/drools/core/reteoo/builder/GroupElementBuilder.java b/drools-core/src/main/java/org/drools/core/reteoo/builder/GroupElementBuilder.java index 9b2eca4ded0..61f8474a432 100755 --- a/drools-core/src/main/java/org/drools/core/reteoo/builder/GroupElementBuilder.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/builder/GroupElementBuilder.java @@ -30,6 +30,7 @@ import org.drools.base.rule.Pattern; import org.drools.base.rule.RuleConditionElement; import org.drools.core.RuleBaseConfiguration; +import org.drools.core.common.BaseNode; import org.drools.core.common.BetaConstraints; import org.drools.core.common.TupleStartEqualsConstraint; import org.drools.core.reteoo.CoreComponentFactory; @@ -37,9 +38,8 @@ import org.drools.core.reteoo.JoinNode; import org.drools.core.reteoo.LeftTupleSource; import org.drools.core.reteoo.NotNode; -import org.drools.core.reteoo.ObjectSource; import org.drools.core.reteoo.ObjectTypeNode; -import org.drools.core.reteoo.RightInputAdapterNode; +import org.drools.core.reteoo.TupleToObjectNode; import org.drools.base.rule.constraint.BetaConstraint; import org.kie.api.definition.rule.Propagation; @@ -140,9 +140,9 @@ public static void buildTupleSource(BuildContext context, BuildUtils utils, bool // if a previous object source was bound, but no tuple source if (context.getObjectSource() != null && context.getTupleSource() == null) { // we know this is the root OTN, so record it - ObjectSource source = context.getObjectSource(); + BaseNode source = context.getObjectSource(); while ( !(source.getType() == NodeTypeEnums.ObjectTypeNode ) ) { - source = source.getParentObjectSource(); + source = source.getParent(); } context.setRootObjectTypeNode( (ObjectTypeNode) source ); @@ -247,13 +247,13 @@ public void build(final BuildContext context, // if it is a subnetwork if ( context.getObjectSource() == null && context.getTupleSource() != null ) { - RightInputAdapterNode riaNode = CoreComponentFactory.get().getNodeFactoryService().buildRightInputNode(context.getNextNodeId(), - context.getTupleSource(), - tupleSource, - context); + TupleToObjectNode tton = CoreComponentFactory.get().getNodeFactoryService().buildRightInputNode(context.getNextNodeId(), + context.getTupleSource(), + tupleSource, + context); // attach right input adapter node to convert tuple source into an object source - context.setObjectSource( utils.attachNode( context, riaNode ) ); + context.setObjectSource( utils.attachNode( context, tton ) ); // restore tuple source from before the start of the sub network context.setTupleSource( tupleSource ); @@ -326,13 +326,13 @@ public void build(final BuildContext context, // if it is a subnetwork if ( context.getObjectSource() == null && context.getTupleSource() != null ) { - RightInputAdapterNode riaNode = CoreComponentFactory.get().getNodeFactoryService().buildRightInputNode( context.getNextNodeId(), - context.getTupleSource(), - tupleSource, - context ); + TupleToObjectNode tton = CoreComponentFactory.get().getNodeFactoryService().buildRightInputNode(context.getNextNodeId(), + context.getTupleSource(), + tupleSource, + context); // attach right input adapter node to convert tuple source into an object source - context.setObjectSource( utils.attachNode( context, riaNode ) ); + context.setObjectSource( utils.attachNode( context, tton ) ); // restore tuple source from before the start of the sub network context.setTupleSource( tupleSource ); diff --git a/drools-core/src/main/java/org/drools/core/reteoo/builder/NodeFactory.java b/drools-core/src/main/java/org/drools/core/reteoo/builder/NodeFactory.java index c02d6a8fa65..a5510919f6f 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/builder/NodeFactory.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/builder/NodeFactory.java @@ -55,7 +55,7 @@ import org.drools.core.reteoo.ObjectTypeNode; import org.drools.core.reteoo.QueryElementNode; import org.drools.core.reteoo.ReactiveFromNode; -import org.drools.core.reteoo.RightInputAdapterNode; +import org.drools.core.reteoo.TupleToObjectNode; import org.drools.core.reteoo.TerminalNode; import org.drools.core.reteoo.TimerNode; import org.drools.core.reteoo.WindowNode; @@ -96,10 +96,10 @@ EvalConditionNode buildEvalNode( int id, BuildContext context); - RightInputAdapterNode buildRightInputNode( int id, - LeftTupleSource leftInput, - LeftTupleSource startTupleSource, - BuildContext context ); + TupleToObjectNode buildRightInputNode(int id, + LeftTupleSource leftInput, + LeftTupleSource startTupleSource, + BuildContext context); JoinNode buildJoinNode( int id, LeftTupleSource leftInput, diff --git a/drools-core/src/main/java/org/drools/core/reteoo/builder/PhreakNodeFactory.java b/drools-core/src/main/java/org/drools/core/reteoo/builder/PhreakNodeFactory.java index 9a912664d98..f266f51b359 100644 --- a/drools-core/src/main/java/org/drools/core/reteoo/builder/PhreakNodeFactory.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/builder/PhreakNodeFactory.java @@ -39,6 +39,7 @@ import org.drools.base.time.impl.Timer; import org.drools.core.common.BetaConstraints; import org.drools.core.reteoo.AccumulateNode; +import org.drools.core.reteoo.AccumulateRight; import org.drools.core.reteoo.AlphaNode; import org.drools.core.reteoo.AlphaTerminalNode; import org.drools.core.reteoo.AsyncReceiveNode; @@ -48,17 +49,20 @@ import org.drools.core.reteoo.EntryPointNode; import org.drools.core.reteoo.EvalConditionNode; import org.drools.core.reteoo.ExistsNode; +import org.drools.core.reteoo.ExistsRight; import org.drools.core.reteoo.FromNode; import org.drools.core.reteoo.JoinNode; +import org.drools.core.reteoo.JoinRightAdapterNode; import org.drools.core.reteoo.LeftInputAdapterNode; import org.drools.core.reteoo.LeftTupleSource; import org.drools.core.reteoo.NotNode; +import org.drools.core.reteoo.NotRight; import org.drools.core.reteoo.ObjectSource; import org.drools.core.reteoo.ObjectTypeNode; import org.drools.core.reteoo.QueryElementNode; import org.drools.core.reteoo.QueryTerminalNode; import org.drools.core.reteoo.ReactiveFromNode; -import org.drools.core.reteoo.RightInputAdapterNode; +import org.drools.core.reteoo.TupleToObjectNode; import org.drools.core.reteoo.RuleTerminalNode; import org.drools.core.reteoo.TerminalNode; import org.drools.core.reteoo.TimerNode; @@ -101,31 +105,35 @@ public EvalConditionNode buildEvalNode(final int id, return new EvalConditionNode( id, tupleSource, eval, context ); } - public RightInputAdapterNode buildRightInputNode( int id, LeftTupleSource leftInput, LeftTupleSource splitStart, BuildContext context ) { + public TupleToObjectNode buildRightInputNode(int id, LeftTupleSource leftInput, LeftTupleSource splitStart, BuildContext context) { LeftTupleSource startTupleSource = leftInput; while (startTupleSource.getLeftTupleSource() != splitStart) { startTupleSource = startTupleSource.getLeftTupleSource(); } - return new RightInputAdapterNode( id, leftInput, startTupleSource, context ); + return new TupleToObjectNode(id, leftInput, startTupleSource, context ); } public JoinNode buildJoinNode( int id, LeftTupleSource leftInput, ObjectSource rightInput, BetaConstraints binder, BuildContext context ) { - return new JoinNode( id, leftInput, rightInput, binder, context ); + JoinRightAdapterNode joinRight = new JoinRightAdapterNode(id, rightInput, context); + return new JoinNode(context.getNextNodeId(), leftInput, joinRight, binder, context ); } public NotNode buildNotNode( int id, LeftTupleSource leftInput, ObjectSource rightInput, BetaConstraints binder, BuildContext context ) { - return new NotNode( id, leftInput, rightInput, binder, context ); + NotRight notRight = new NotRight(id, rightInput, context); + return new NotNode(context.getNextNodeId(), leftInput, notRight, binder, context ); } public ExistsNode buildExistsNode( int id, LeftTupleSource leftInput, ObjectSource rightInput, BetaConstraints binder, BuildContext context ) { - return new ExistsNode( id, leftInput, rightInput, binder, context ); + ExistsRight existsRight = new ExistsRight(id, rightInput, context); + return new ExistsNode(context.getNextNodeId(), leftInput, existsRight, binder, context ); } public AccumulateNode buildAccumulateNode(int id, LeftTupleSource leftInput, ObjectSource rightInput, AlphaNodeFieldConstraint[] resultConstraints, BetaConstraints sourceBinder, BetaConstraints resultBinder, Accumulate accumulate, BuildContext context) { - return new AccumulateNode(id, leftInput, rightInput, resultConstraints, sourceBinder, resultBinder, accumulate, context ); + AccumulateRight accRight = new AccumulateRight(id, rightInput, context); + return new AccumulateNode(context.getNextNodeId(), leftInput, accRight, resultConstraints, sourceBinder, resultBinder, accumulate, context ); } public LeftInputAdapterNode buildLeftInputAdapterNode( int id, ObjectSource objectSource, BuildContext context, boolean terminal ) { diff --git a/drools-core/src/main/java/org/drools/core/reteoo/builder/ReteooRuleBuilder.java b/drools-core/src/main/java/org/drools/core/reteoo/builder/ReteooRuleBuilder.java index ebb53112a7d..bb3209edd41 100755 --- a/drools-core/src/main/java/org/drools/core/reteoo/builder/ReteooRuleBuilder.java +++ b/drools-core/src/main/java/org/drools/core/reteoo/builder/ReteooRuleBuilder.java @@ -51,7 +51,6 @@ import org.drools.core.impl.InternalRuleBase; import org.drools.core.phreak.PhreakBuilder; import org.drools.core.reteoo.PathEndNode; -import org.drools.core.reteoo.RightInputAdapterNode; import org.drools.core.reteoo.RuleBuilder; import org.drools.core.reteoo.TerminalNode; import org.drools.core.reteoo.WindowNode; @@ -230,11 +229,11 @@ private static void setPathEndNodes(BuildContext context, TerminalNode terminalN for ( int i = 0; i < pathEndNodes.length; i++ ) { PathEndNode node = context.getPathEndNodes().get(pathEndNodes.length-1-i); pathEndNodes[i] = node; - if (node.getType() == NodeTypeEnums.RightInputAdapterNode && node.getPathEndNodes() != null) { - PathEndNode[] riaPathEndNodes = new PathEndNode[node.getPathEndNodes().length + i]; - System.arraycopy( pathEndNodes, 0, riaPathEndNodes, 0, i ); - System.arraycopy( node.getPathEndNodes(), 0, riaPathEndNodes, i, node.getPathEndNodes().length ); - node.setPathEndNodes( riaPathEndNodes ); + if (node.getType() == NodeTypeEnums.TupleToObjectNode && node.getPathEndNodes() != null) { + PathEndNode[] SubnetworkNodes = new PathEndNode[node.getPathEndNodes().length + i]; + System.arraycopy( pathEndNodes, 0, SubnetworkNodes, 0, i ); + System.arraycopy( node.getPathEndNodes(), 0, SubnetworkNodes, i, node.getPathEndNodes().length ); + node.setPathEndNodes( SubnetworkNodes ); } else { node.setPathEndNodes( pathEndNodes ); } diff --git a/drools-core/src/test/java/org/drools/core/reteoo/BaseNodeTest.java b/drools-core/src/test/java/org/drools/core/reteoo/BaseNodeTest.java index dabc5b72d8b..551b5142d9f 100644 --- a/drools-core/src/test/java/org/drools/core/reteoo/BaseNodeTest.java +++ b/drools-core/src/test/java/org/drools/core/reteoo/BaseNodeTest.java @@ -24,6 +24,7 @@ import org.drools.core.common.PropagationContext; import org.drools.core.common.UpdateContext; import org.drools.core.reteoo.builder.BuildContext; +import org.drools.util.bitmask.BitMask; import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -65,6 +66,11 @@ protected boolean doRemove(final RuleRemovalContext context, return true; } + @Override + public BaseNode getParent() { + return null; + } + public boolean isInUse() { return true; } @@ -81,5 +87,15 @@ public void networkUpdated(UpdateContext updateContext) { public int getType() { return 0; } + + @Override + public BitMask getDeclaredMask() { + return null; + } + + @Override + public BitMask getInferredMask() { + return null; + } } } diff --git a/drools-core/src/test/java/org/drools/core/reteoo/BetaNodeTest.java b/drools-core/src/test/java/org/drools/core/reteoo/BetaNodeTest.java index f416955594e..a683ac9665b 100755 --- a/drools-core/src/test/java/org/drools/core/reteoo/BetaNodeTest.java +++ b/drools-core/src/test/java/org/drools/core/reteoo/BetaNodeTest.java @@ -37,26 +37,27 @@ public void testEqualsObject() { BuildContext buildContext = new BuildContext( kBase, Collections.emptyList() ); final LeftTupleSource ts = new MockTupleSource( 1, buildContext ); - final ObjectSource os = new MockObjectSource( 2, buildContext ); + final ObjectSource os = new MockObjectSource( 2, buildContext ); + RightInputAdapterNode right = new JoinRightAdapterNode(5, os, buildContext); final BetaNode j1 = new JoinNode( 1, ts, - os, + right, EmptyBetaConstraints.getInstance(), buildContext ); final BetaNode j2 = new JoinNode( 2, ts, - os, + right, EmptyBetaConstraints.getInstance(), buildContext ); final BetaNode n1 = new NotNode( 3, ts, - os, + right, EmptyBetaConstraints.getInstance(), buildContext ); final BetaNode n2 = new NotNode( 4, ts, - os, + right, EmptyBetaConstraints.getInstance(), buildContext ); diff --git a/drools-core/src/test/java/org/drools/core/reteoo/MockLeftTupleSink.java b/drools-core/src/test/java/org/drools/core/reteoo/MockLeftTupleSink.java index c086a27578e..bd7ee9185fe 100644 --- a/drools-core/src/test/java/org/drools/core/reteoo/MockLeftTupleSink.java +++ b/drools-core/src/test/java/org/drools/core/reteoo/MockLeftTupleSink.java @@ -46,6 +46,10 @@ public MockLeftTupleSink(BuildContext buildContext) { super( 0, buildContext ); } + public MockLeftTupleSink(final int id, BuildContext buildContext) { + super( id, buildContext ); + } + public MockLeftTupleSink(final int id) { super(id, null); } @@ -133,6 +137,19 @@ public int getType() { }; } + public LeftTupleSource getParent() { + if ( super.getLeftTupleSource() != null) { + return super.getLeftTupleSource(); + } + + return new MockLeftTupleSink(null) { + @Override + public int getType() { + return NodeTypeEnums.LeftInputAdapterNode; + } + }; + } + @Override public ObjectTypeNode getObjectTypeNode() { return null; diff --git a/drools-core/src/test/java/org/drools/core/reteoo/NodeTypeEnumTest.java b/drools-core/src/test/java/org/drools/core/reteoo/NodeTypeEnumTest.java index 719e49f436c..2bee35417aa 100644 --- a/drools-core/src/test/java/org/drools/core/reteoo/NodeTypeEnumTest.java +++ b/drools-core/src/test/java/org/drools/core/reteoo/NodeTypeEnumTest.java @@ -34,7 +34,7 @@ public class NodeTypeEnumTest { AlphaNode alphaNode = new AlphaNode(); WindowNode winNode = new WindowNode(); - RightInputAdapterNode riaNode = new RightInputAdapterNode(); + TupleToObjectNode ttoNode = new TupleToObjectNode(); RuleTerminalNode rtNode = new RuleTerminalNode(); QueryTerminalNode qtNode = new QueryTerminalNode(); @@ -58,7 +58,7 @@ public void tesObjectSource() { assertThat(isObjectSource(otNode)).isTrue(); assertThat(isObjectSource(alphaNode)).isTrue(); - assertThat(isObjectSource(riaNode)).isTrue(); + assertThat(isObjectSource(ttoNode)).isTrue(); assertThat(isObjectSource(rtNode)).isFalse(); assertThat(isObjectSource(qtNode)).isFalse(); @@ -83,7 +83,7 @@ public void tesObjectSink() { assertThat(isObjectSink(otNode)).isTrue(); assertThat(isObjectSink(alphaNode)).isTrue(); - assertThat(isObjectSink(riaNode)).isFalse(); + assertThat(isObjectSink(ttoNode)).isFalse(); assertThat(isObjectSink(rtNode)).isFalse(); assertThat(isObjectSink(qtNode)).isFalse(); @@ -107,7 +107,7 @@ public void tesLeftTupleSource() { assertThat(isLeftTupleSource(reteNod)).isFalse(); assertThat(isLeftTupleSource(otNode)).isFalse(); assertThat(isLeftTupleSource(alphaNode)).isFalse(); - assertThat(isLeftTupleSource(riaNode)).isFalse(); + assertThat(isLeftTupleSource(ttoNode)).isFalse(); assertThat(isLeftTupleSource(rtNode)).isFalse(); assertThat(isLeftTupleSource(qtNode)).isFalse(); @@ -132,7 +132,7 @@ public void tesLeftTupleSink() { assertThat(isLeftTupleSink(otNode)).isFalse(); assertThat(isLeftTupleSink(alphaNode)).isFalse(); - assertThat(isLeftTupleSink(riaNode)).isTrue(); + assertThat(isLeftTupleSink(ttoNode)).isTrue(); assertThat(isLeftTupleSink(rtNode)).isTrue(); assertThat(isLeftTupleSink(qtNode)).isTrue(); @@ -157,7 +157,7 @@ public void testBetaNode() { assertThat(isBetaNode(otNode)).isFalse(); assertThat(isBetaNode(alphaNode)).isFalse(); - assertThat(isBetaNode(riaNode)).isFalse(); + assertThat(isBetaNode(ttoNode)).isFalse(); assertThat(isBetaNode(rtNode)).isFalse(); assertThat(isBetaNode(qtNode)).isFalse(); diff --git a/drools-core/src/test/java/org/drools/core/util/RightTupleListTest.java b/drools-core/src/test/java/org/drools/core/util/RightTupleListTest.java index b992a9b7e7f..238e06b2874 100644 --- a/drools-core/src/test/java/org/drools/core/util/RightTupleListTest.java +++ b/drools-core/src/test/java/org/drools/core/util/RightTupleListTest.java @@ -20,13 +20,17 @@ import org.drools.core.common.DefaultFactHandle; import org.drools.core.common.InternalFactHandle; +import org.drools.core.impl.KnowledgeBaseImpl; import org.drools.core.reteoo.LeftTuple; import org.drools.core.reteoo.MockLeftTupleSink; import org.drools.core.reteoo.MockObjectSink; +import org.drools.core.reteoo.builder.BuildContext; import org.drools.core.test.model.Cheese; import org.drools.core.util.index.TupleList; import org.junit.Test; +import java.util.Collections; + import static org.assertj.core.api.Assertions.assertThat; public class RightTupleListTest { @@ -38,6 +42,7 @@ public void testEmptyIterator() { final InternalFactHandle h1 = new DefaultFactHandle( 1, stilton1 ); - assertThat(map.getFirst(new LeftTuple(h1, new MockLeftTupleSink(0), true ))).isNull(); + BuildContext bctx = new BuildContext(new KnowledgeBaseImpl("1"), Collections.emptyList()); + assertThat(map.getFirst(new LeftTuple(h1, new MockLeftTupleSink(0, bctx), true ))).isNull(); } } diff --git a/drools-kiesession/src/main/java/org/drools/kiesession/debug/BetaRightAdapterNodeVisitor.java b/drools-kiesession/src/main/java/org/drools/kiesession/debug/BetaRightAdapterNodeVisitor.java new file mode 100755 index 00000000000..fe50749c2cc --- /dev/null +++ b/drools-kiesession/src/main/java/org/drools/kiesession/debug/BetaRightAdapterNodeVisitor.java @@ -0,0 +1,60 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.drools.kiesession.debug; + +import org.drools.base.common.NetworkNode; +import org.drools.base.reteoo.NodeTypeEnums; +import org.drools.core.common.Memory; +import org.drools.core.reteoo.AccumulateNode.AccumulateMemory; +import org.drools.core.reteoo.BetaMemory; +import org.drools.core.reteoo.BetaNode; +import org.drools.core.reteoo.RightInputAdapterNode; + +import java.util.Collection; + +public class BetaRightAdapterNodeVisitor extends AbstractNetworkNodeVisitor { + + public static final BetaRightAdapterNodeVisitor INSTANCE = new BetaRightAdapterNodeVisitor(); + + protected BetaRightAdapterNodeVisitor() { + } + + @Override + protected void doVisit(NetworkNode node, + Collection nodeStack, + StatefulKnowledgeSessionInfo info) { + RightInputAdapterNode an = (RightInputAdapterNode) node; + DefaultNodeInfo ni = info.getNodeInfo( node ); + + BetaNode betaNode = an.getBetaNode(); + + Memory childMemory = info.getSession().getNodeMemory( betaNode ); + + BetaMemory bm; + if ( betaNode.getType() == NodeTypeEnums.AccumulateNode ) { + bm = ((AccumulateMemory) childMemory).getBetaMemory(); + } else { + bm = (BetaMemory) childMemory; + } + + ni.setTupleMemorySize( bm.getRightTupleMemory().size() ); + ni.setCreatedFactHandles( bm.getRightTupleMemory().size() ); + } + +} diff --git a/drools-kiesession/src/main/java/org/drools/kiesession/debug/RightInputAdapterNodeVisitor.java b/drools-kiesession/src/main/java/org/drools/kiesession/debug/RightInputAdapterNodeVisitor.java index 7bcd7ac9027..cd5189267d3 100755 --- a/drools-kiesession/src/main/java/org/drools/kiesession/debug/RightInputAdapterNodeVisitor.java +++ b/drools-kiesession/src/main/java/org/drools/kiesession/debug/RightInputAdapterNodeVisitor.java @@ -25,6 +25,7 @@ import org.drools.core.reteoo.BetaMemory; import org.drools.core.reteoo.BetaNode; import org.drools.core.reteoo.RightInputAdapterNode; +import org.drools.core.reteoo.TupleToObjectNode; import java.util.Collection; @@ -39,10 +40,10 @@ protected RightInputAdapterNodeVisitor() { protected void doVisit(NetworkNode node, Collection nodeStack, StatefulKnowledgeSessionInfo info) { - RightInputAdapterNode an = (RightInputAdapterNode) node; - DefaultNodeInfo ni = info.getNodeInfo( node ); + TupleToObjectNode an = (TupleToObjectNode) node; + DefaultNodeInfo ni = info.getNodeInfo( node ); - BetaNode betaNode = (BetaNode) an.getObjectSinkPropagator().getSinks()[0]; + BetaNode betaNode = ((RightInputAdapterNode)an.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); Memory childMemory = info.getSession().getNodeMemory( betaNode ); diff --git a/drools-kiesession/src/main/java/org/drools/kiesession/debug/SessionInspector.java b/drools-kiesession/src/main/java/org/drools/kiesession/debug/SessionInspector.java index 3998deb3d33..2396abf4be9 100755 --- a/drools-kiesession/src/main/java/org/drools/kiesession/debug/SessionInspector.java +++ b/drools-kiesession/src/main/java/org/drools/kiesession/debug/SessionInspector.java @@ -36,6 +36,7 @@ import org.drools.core.reteoo.ObjectTypeNode; import org.drools.core.reteoo.QueryTerminalNode; import org.drools.core.reteoo.Rete; +import org.drools.core.reteoo.RightInputAdapterNode; import org.drools.core.reteoo.RuleTerminalNode; import org.drools.kiesession.session.StatefulKnowledgeSessionImpl; import org.kie.api.runtime.KieSession; @@ -66,9 +67,19 @@ public class SessionInspector { ObjectTypeNodeVisitor.INSTANCE ); this.visitors.put( NodeTypeEnums.AlphaNode, AlphaNodeVisitor.INSTANCE ); - this.visitors.put( NodeTypeEnums.RightInputAdapterNode, + this.visitors.put( NodeTypeEnums.TupleToObjectNode, RightInputAdapterNodeVisitor.INSTANCE ); + + this.visitors.put( NodeTypeEnums.JoinRightAdapterNode, + BetaRightAdapterNodeVisitor.INSTANCE ); + this.visitors.put( NodeTypeEnums.ExistsRightAdapterNode, + BetaRightAdapterNodeVisitor.INSTANCE ); + this.visitors.put( NodeTypeEnums.NotRightAdapterNode, + BetaRightAdapterNodeVisitor.INSTANCE ); + this.visitors.put( NodeTypeEnums.AccumulateRightAdapterNode, + BetaRightAdapterNodeVisitor.INSTANCE ); + // left tuple source nodes this.visitors.put( NodeTypeEnums.JoinNode, BetaNodeVisitor.INSTANCE ); @@ -171,7 +182,9 @@ protected void visitChildren(NetworkNode parent, nodeStack, info ); } - } else if ( parent instanceof RuleTerminalNode || parent instanceof QueryTerminalNode ) { + } else if (parent instanceof RightInputAdapterNode ) { + // no children to visit + } else if ( parent instanceof RuleTerminalNode || parent instanceof QueryTerminalNode ) { // no children to visit } else { // did we forget any node type? diff --git a/drools-kiesession/src/test/java/org/drools/kiesession/NodeSegmentUnlinkingTest.java b/drools-kiesession/src/test/java/org/drools/kiesession/NodeSegmentUnlinkingTest.java index 9693d65b11c..0113e7349a9 100644 --- a/drools-kiesession/src/test/java/org/drools/kiesession/NodeSegmentUnlinkingTest.java +++ b/drools-kiesession/src/test/java/org/drools/kiesession/NodeSegmentUnlinkingTest.java @@ -31,6 +31,10 @@ import org.drools.base.definitions.rule.impl.RuleImpl; import org.drools.core.phreak.BuildtimeSegmentUtilities; import org.drools.core.reteoo.BetaMemory; +import org.drools.core.reteoo.RightInputAdapterNode; +import org.drools.core.reteoo.ExistsRight; +import org.drools.core.reteoo.JoinRightAdapterNode; +import org.drools.core.reteoo.NotRight; import org.drools.core.reteoo.PathEndNode; import org.drools.core.reteoo.SegmentMemory.SegmentPrototype; import org.drools.core.reteoo.TerminalNode; @@ -88,15 +92,18 @@ private BetaNode createBetaNode(int id, BetaNode betaNode = null; switch ( type ) { case JOIN_NODE : { - betaNode = new JoinNode( id, leftTupleSource, mockObjectSource, new EmptyBetaConstraints(), buildContext ); + RightInputAdapterNode right = new JoinRightAdapterNode(9, mockObjectSource, buildContext); + betaNode = new JoinNode( id, leftTupleSource, right, new EmptyBetaConstraints(), buildContext ); break; } case EXISTS_NODE : { - betaNode = new ExistsNode( id, leftTupleSource, mockObjectSource, new EmptyBetaConstraints(), buildContext ); + RightInputAdapterNode right = new ExistsRight(9, mockObjectSource, buildContext); + betaNode = new ExistsNode( id, leftTupleSource, right, new EmptyBetaConstraints(), buildContext ); break; } case NOT_NODE : { - betaNode = new NotNode( id, leftTupleSource, mockObjectSource, new EmptyBetaConstraints(), buildContext ); + RightInputAdapterNode right = new NotRight(9, mockObjectSource, buildContext); + betaNode = new NotNode( id, leftTupleSource, right, new EmptyBetaConstraints(), buildContext ); break; } } @@ -167,25 +174,25 @@ public void setUp(int... type) { // \ // n7 -> n8 -> r3 - n1.addAssociation( rule1 ); - n1.addAssociation( rule2 ); - n1.addAssociation( rule3 ); - n2.addAssociation( rule1 ); - n2.addAssociation( rule2 ); - n2.addAssociation( rule3 ); - - n3.addAssociation( rule2 ); - n3.addAssociation( rule3 ); - - n4.addAssociation( rule2 ); - n4.addAssociation( rule3 ); - n5.addAssociation( rule2 ); - n5.addAssociation( rule3 ); - n6.addAssociation( rule2 ); - n6.addAssociation( rule3 ); - - n7.addAssociation( rule3 ); - n8.addAssociation( rule3 ); + n1.addAssociation(rule1, null); + n1.addAssociation(rule2, null); + n1.addAssociation(rule3, null); + n2.addAssociation(rule1, null); + n2.addAssociation(rule2, null); + n2.addAssociation(rule3, null); + + n3.addAssociation(rule2, null); + n3.addAssociation(rule3, null); + + n4.addAssociation(rule2, null); + n4.addAssociation(rule3, null); + n5.addAssociation(rule2, null); + n5.addAssociation(rule3, null); + n6.addAssociation(rule2, null); + n6.addAssociation(rule3, null); + + n7.addAssociation(rule3, null); + n8.addAssociation(rule3, null); // assumes no subnetworks for (TerminalNode tn : new TerminalNode[] {rtn1, rtn2, rtn3}) { @@ -208,29 +215,35 @@ public void testSingleNodeinSegment() { MockObjectSource mockObjectSource = new MockObjectSource( 8 ); MockTupleSource mockTupleSource = new MockTupleSource(9, buildContext); + RightInputAdapterNode right1 = new JoinRightAdapterNode(10, mockObjectSource, buildContext); + RightInputAdapterNode right2 = new JoinRightAdapterNode(11, mockObjectSource, buildContext); + RightInputAdapterNode right3 = new JoinRightAdapterNode(12, mockObjectSource, buildContext); + RightInputAdapterNode right4 = new JoinRightAdapterNode(12, mockObjectSource, buildContext); + RightInputAdapterNode right5 = new JoinRightAdapterNode(12, mockObjectSource, buildContext); + // n2 is only node in it's segment ObjectTypeNode otn = new ObjectTypeNode( 2, null, new ClassObjectType( String.class ), buildContext ); - BetaNode n1 = new JoinNode( 10, new LeftInputAdapterNode(3, otn, buildContext ), mockObjectSource, + BetaNode n1 = new JoinNode( 10, new LeftInputAdapterNode(3, otn, buildContext ), right1, new EmptyBetaConstraints(), buildContext ); - BetaNode n2 = new JoinNode( 11, n1, mockObjectSource, + BetaNode n2 = new JoinNode( 11, n1, right2, new EmptyBetaConstraints(), buildContext ); - BetaNode n3 = new JoinNode( 12, n1, mockObjectSource, + BetaNode n3 = new JoinNode( 12, n1, right3, new EmptyBetaConstraints(), buildContext ); - BetaNode n4 = new JoinNode( 13, n2, mockObjectSource, + BetaNode n4 = new JoinNode( 13, n2, right4, new EmptyBetaConstraints(), buildContext ); - BetaNode n5 = new JoinNode( 14, n2, mockObjectSource, + BetaNode n5 = new JoinNode( 14, n2, right5, new EmptyBetaConstraints(), buildContext ); - n1.addAssociation( rule1 ); - n1.addAssociation( rule2 ); - n1.addAssociation( rule3 ); + n1.addAssociation(rule1, null); + n1.addAssociation(rule2, null); + n1.addAssociation(rule3, null); - n2.addAssociation( rule2 ); - n2.addAssociation( rule3 ); + n2.addAssociation(rule2, null); + n2.addAssociation(rule3, null); - n3.addAssociation( rule1 ); - n4.addAssociation( rule2 ); - n5.addAssociation( rule3 ); + n3.addAssociation(rule1, null); + n4.addAssociation(rule2, null); + n5.addAssociation(rule3, null); mockObjectSource.attach(buildContext); mockTupleSource.attach(buildContext); @@ -287,7 +300,7 @@ public void testLiaNodeInitialisation() { // Initialise from n1 ksession = (StatefulKnowledgeSessionImpl)kBase.newKieSession(); - n1.assertObject( (InternalFactHandle) ksession.insert( "str" ), context, ksession ); + n1.getRightInput().assertObject( (InternalFactHandle) ksession.insert( "str" ), context, ksession ); liaMem = ksession.getNodeMemory(liaNode); @@ -308,7 +321,7 @@ public void testLiaNodeLinking() { RuntimeSegmentUtilities.getOrCreateSegmentMemory(liaNode, ksession); InternalFactHandle fh1 = (InternalFactHandle) ksession.insert( "str1" ); - n1.assertObject( fh1, context, ksession ); + n1.getRightInput().assertObject( fh1, context, ksession ); LiaNodeMemory liaMem = ksession.getNodeMemory(liaNode); assertThat(liaMem.getNodePosMaskBit()).isEqualTo(1); @@ -454,18 +467,18 @@ public void testAllLinkedInWithJoinNodesOnly() { StatefulKnowledgeSessionImpl ksession = (StatefulKnowledgeSessionImpl)kBase.newKieSession(); DefaultFactHandle f1 = (DefaultFactHandle) ksession.insert( "test1" ); - n3.assertObject( f1, context, ksession ); + n3.getRightInput().assertObject( f1, context, ksession ); BetaMemory bm = (BetaMemory) ksession.getNodeMemory(n3); assertThat(bm.getSegmentMemory().isSegmentLinked()).isFalse(); - n4.assertObject( f1, context, ksession ); + n4.getRightInput().assertObject( f1, context, ksession ); assertThat(bm.getSegmentMemory().isSegmentLinked()).isFalse(); - n5.assertObject( f1, context, ksession ); + n5.getRightInput().assertObject( f1, context, ksession ); assertThat(bm.getSegmentMemory().isSegmentLinked()).isFalse(); - n6.assertObject( f1, context, ksession ); + n6.getRightInput().assertObject( f1, context, ksession ); assertThat(bm.getSegmentMemory().isSegmentLinked()).isTrue(); // only after all 4 nodes are populated, is the segment linked in } @@ -478,18 +491,18 @@ public void testAllLinkedInWithExistsNodesOnly() { StatefulKnowledgeSessionImpl ksession = (StatefulKnowledgeSessionImpl)kBase.newKieSession(); DefaultFactHandle f1 = (DefaultFactHandle) ksession.insert( "test1" ); - n3.assertObject( f1, context, ksession ); + n3.getRightInput().assertObject( f1, context, ksession ); BetaMemory bm = (BetaMemory) ksession.getNodeMemory(n3); assertThat(bm.getSegmentMemory().isSegmentLinked()).isFalse(); - n4.assertObject( f1, context, ksession ); + n4.getRightInput().assertObject( f1, context, ksession ); assertThat(bm.getSegmentMemory().isSegmentLinked()).isFalse(); - n5.assertObject( f1, context, ksession ); + n5.getRightInput().assertObject( f1, context, ksession ); assertThat(bm.getSegmentMemory().isSegmentLinked()).isFalse(); - n6.assertObject( f1, context, ksession ); + n6.getRightInput().assertObject( f1, context, ksession ); assertThat(bm.getSegmentMemory().isSegmentLinked()).isTrue(); // only after all 4 nodes are populated, is the segment linked in } @@ -516,13 +529,13 @@ public void testAllLinkedInWithNotNodesOnly() { assertThat(bm.getSegmentMemory().isSegmentLinked()).isTrue(); // not nodes start off linked DefaultFactHandle f1 = (DefaultFactHandle) ksession.insert( "test1" ); // unlinked after first assertion - n3.assertObject( f1, context, ksession ); + n3.getRightInput().assertObject( f1, context, ksession ); // this doesn't unlink on the assertObject, as the node's memory must be processed. So use the helper method the main network evaluator uses. PhreakNotNode.unlinkNotNodeOnRightInsert( (NotNode) n3, bm, ksession ); assertThat(bm.getSegmentMemory().isSegmentLinked()).isFalse(); - n3.retractRightTuple( f1.getFirstRightTuple(), context, ksession ); + n3.getRightInput().retractRightTuple( f1.getFirstRightTuple(), context, ksession ); assertThat(bm.getSegmentMemory().isSegmentLinked()).isTrue(); //assertFalse( bm.getSegmentMemory().isSigmentLinked() ); // check retraction unlinks again } diff --git a/drools-kiesession/src/test/java/org/drools/kiesession/RuleUnlinkingTest.java b/drools-kiesession/src/test/java/org/drools/kiesession/RuleUnlinkingTest.java index 9fbafbdcdff..81908b156d4 100644 --- a/drools-kiesession/src/test/java/org/drools/kiesession/RuleUnlinkingTest.java +++ b/drools-kiesession/src/test/java/org/drools/kiesession/RuleUnlinkingTest.java @@ -31,6 +31,10 @@ import org.drools.base.definitions.rule.impl.RuleImpl; import org.drools.core.phreak.BuildtimeSegmentUtilities; import org.drools.core.reteoo.BetaMemory; +import org.drools.core.reteoo.RightInputAdapterNode; +import org.drools.core.reteoo.ExistsRight; +import org.drools.core.reteoo.JoinRightAdapterNode; +import org.drools.core.reteoo.NotRight; import org.drools.core.reteoo.PathEndNode; import org.drools.core.reteoo.TerminalNode; import org.drools.kiesession.rulebase.InternalKnowledgeBase; @@ -91,20 +95,23 @@ private NetworkNode createNetworkNode(int id, int type, LeftTupleSource leftTupleSource, RuleImpl rule) { - MockObjectSource mockObjectSource = new MockObjectSource( 8 ); + MockObjectSource mockObjectSource = new MockObjectSource( 8 ); LeftTupleSink networkNode = null; switch ( type ) { case JOIN_NODE : { - networkNode = new JoinNode( id, leftTupleSource, mockObjectSource, new EmptyBetaConstraints(), buildContext ); + RightInputAdapterNode right = new JoinRightAdapterNode(9, mockObjectSource, buildContext); + networkNode = new JoinNode( id, leftTupleSource, right, new EmptyBetaConstraints(), buildContext ); break; } case EXISTS_NODE : { - networkNode = new ExistsNode( id, leftTupleSource, mockObjectSource, new EmptyBetaConstraints(), buildContext ); + RightInputAdapterNode right = new ExistsRight(9, mockObjectSource, buildContext); + networkNode = new ExistsNode( id, leftTupleSource, right, new EmptyBetaConstraints(), buildContext ); break; } case NOT_NODE : { - networkNode = new NotNode( id, leftTupleSource, mockObjectSource, new EmptyBetaConstraints(), buildContext ); + RightInputAdapterNode right = new NotRight(9, mockObjectSource, buildContext); + networkNode = new NotNode( id, leftTupleSource, right, new EmptyBetaConstraints(), buildContext ); break; } case RULE_TERMINAL_NODE : { @@ -159,29 +166,29 @@ public void setUp(int type) { // \ // n6 -> n7 -> n8 -> r3 - liaNode.addAssociation( rule1 ); - liaNode.addAssociation( rule2 ); - liaNode.addAssociation( rule3 ); - - n1.addAssociation( rule1 ); - n1.addAssociation( rule2 ); - n1.addAssociation( rule3 ); - n2.addAssociation( rule1 ); - n2.addAssociation( rule2 ); - n2.addAssociation( rule3 ); - - n3.addAssociation( rule1 ); - n3.addAssociation( rule2 ); - n3.addAssociation( rule3 ); - - n4.addAssociation( rule2 ); - n4.addAssociation( rule3 ); - n5.addAssociation( rule2 ); - n5.addAssociation( rule3 ); - - n6.addAssociation( rule3 ); - n7.addAssociation( rule3 ); - n8.addAssociation( rule3 ); + liaNode.addAssociation(rule1, null); + liaNode.addAssociation(rule2, null); + liaNode.addAssociation(rule3, null); + + n1.addAssociation(rule1, null); + n1.addAssociation(rule2, null); + n1.addAssociation(rule3, null); + n2.addAssociation(rule1, null); + n2.addAssociation(rule2, null); + n2.addAssociation(rule3, null); + + n3.addAssociation(rule1, null); + n3.addAssociation(rule2, null); + n3.addAssociation(rule3, null); + + n4.addAssociation(rule2, null); + n4.addAssociation(rule3, null); + n5.addAssociation(rule2, null); + n5.addAssociation(rule3, null); + + n6.addAssociation(rule3, null); + n7.addAssociation(rule3, null); + n8.addAssociation(rule3, null); // assumes no subnetworks for (TerminalNode tn : new TerminalNode[] {rtn1, rtn2, rtn3}) { @@ -323,10 +330,10 @@ public void testRuleSegmentLinking() { RuntimeSegmentUtilities.getOrCreateSegmentMemory(liaNode, wm); liaNode.assertObject( f1, context, wm ); - n1.assertObject( f1, context, wm ); - n3.assertObject( f1, context, wm ); - n4.assertObject( f1, context, wm ); - n8.assertObject( f1, context, wm ); + n1.getRightInput().assertObject( f1, context, wm ); + n3.getRightInput().assertObject( f1, context, wm ); + n4.getRightInput().assertObject( f1, context, wm ); + n8.getRightInput().assertObject( f1, context, wm ); assertThat(rtn1Rs.isRuleLinked()).isFalse(); assertThat(rtn2Rs.isRuleLinked()).isFalse(); @@ -337,7 +344,7 @@ public void testRuleSegmentLinking() { assertThat(bm.getSegmentMemory().isSegmentLinked()).isFalse(); DefaultFactHandle f2 = (DefaultFactHandle) wm.insert( "test2" ); - n2.assertObject( f2, context, wm ); + n2.getRightInput().assertObject( f2, context, wm ); assertThat(bm.getSegmentMemory().isSegmentLinked()).isTrue(); assertThat(rtn1Rs.isRuleLinked()).isTrue(); @@ -348,7 +355,7 @@ public void testRuleSegmentLinking() { bm = (BetaMemory) wm.getNodeMemory(n5); assertThat(bm.getSegmentMemory().isSegmentLinked()).isFalse(); - n5.assertObject( f1, context, wm ); + n5.getRightInput().assertObject( f1, context, wm ); assertThat(bm.getSegmentMemory().isSegmentLinked()).isTrue(); assertThat(rtn1Rs.isRuleLinked()).isTrue(); @@ -356,8 +363,8 @@ public void testRuleSegmentLinking() { assertThat(rtn3Rs.isRuleLinked()).isFalse(); // Link in Rule3 - n6.assertObject( f1, context, wm ); - n7.assertObject( f1, context, wm ); + n6.getRightInput().assertObject( f1, context, wm ); + n7.getRightInput().assertObject( f1, context, wm ); assertThat(bm.getSegmentMemory().isSegmentLinked()).isTrue(); assertThat(rtn1Rs.isRuleLinked()).isTrue(); @@ -365,7 +372,7 @@ public void testRuleSegmentLinking() { assertThat(rtn3Rs.isRuleLinked()).isTrue(); // retract n2, should unlink all rules - n2.retractRightTuple( f2.getFirstRightTuple(), context, wm ); + n2.getRightInput().retractRightTuple( f2.getFirstRightTuple(), context, wm ); assertThat(rtn1Rs.isRuleLinked()).isFalse(); assertThat(rtn2Rs.isRuleLinked()).isFalse(); assertThat(rtn3Rs.isRuleLinked()).isFalse(); diff --git a/drools-kiesession/src/test/java/org/drools/kiesession/RuleUnlinkingWithSegmentMemoryTest.java b/drools-kiesession/src/test/java/org/drools/kiesession/RuleUnlinkingWithSegmentMemoryTest.java index fcd51e7d00c..07678fe96be 100644 --- a/drools-kiesession/src/test/java/org/drools/kiesession/RuleUnlinkingWithSegmentMemoryTest.java +++ b/drools-kiesession/src/test/java/org/drools/kiesession/RuleUnlinkingWithSegmentMemoryTest.java @@ -33,14 +33,18 @@ import org.drools.core.phreak.BuildtimeSegmentUtilities; import org.drools.core.reteoo.BetaMemory; import org.drools.core.reteoo.BetaNode; +import org.drools.core.reteoo.RightInputAdapterNode; import org.drools.core.reteoo.ExistsNode; +import org.drools.core.reteoo.ExistsRight; import org.drools.core.reteoo.JoinNode; +import org.drools.core.reteoo.JoinRightAdapterNode; import org.drools.core.reteoo.LeftInputAdapterNode; import org.drools.core.reteoo.LeftTupleSink; import org.drools.core.reteoo.LeftTupleSource; import org.drools.core.reteoo.MockObjectSource; import org.drools.base.reteoo.NodeTypeEnums; import org.drools.core.reteoo.NotNode; +import org.drools.core.reteoo.NotRight; import org.drools.core.reteoo.ObjectTypeNode; import org.drools.core.reteoo.PathEndNode; import org.drools.core.reteoo.PathMemory; @@ -97,15 +101,18 @@ private NetworkNode createNetworkNode(int id, LeftTupleSink networkNode = null; switch ( type ) { case JOIN_NODE : { - networkNode = new JoinNode( id, leftTupleSource, mockObjectSource, new EmptyBetaConstraints(), buildContext ); + RightInputAdapterNode right = new JoinRightAdapterNode(9, mockObjectSource, buildContext); + networkNode = new JoinNode( id, leftTupleSource, right, new EmptyBetaConstraints(), buildContext ); break; } case EXISTS_NODE : { - networkNode = new ExistsNode( id, leftTupleSource, mockObjectSource, new EmptyBetaConstraints(), buildContext ); + RightInputAdapterNode right = new ExistsRight(9, mockObjectSource, buildContext); + networkNode = new ExistsNode( id, leftTupleSource, right, new EmptyBetaConstraints(), buildContext ); break; } case NOT_NODE : { - networkNode = new NotNode( id, leftTupleSource, mockObjectSource, new EmptyBetaConstraints(), buildContext ); + RightInputAdapterNode right = new NotRight(9, mockObjectSource, buildContext); + networkNode = new NotNode( id, leftTupleSource, right, new EmptyBetaConstraints(), buildContext ); break; } case RULE_TERMINAL_NODE : { @@ -158,27 +165,27 @@ public void setUp(int type) { rule3.setActivationListener( "agenda" ); rtn3 = ( RuleTerminalNode ) createNetworkNode( 20, RULE_TERMINAL_NODE, n8, rule3 ); - lian.addAssociation( rule1 ); - lian.addAssociation( rule2 ); - lian.addAssociation( rule3 ); - n1.addAssociation( rule1 ); - n1.addAssociation( rule2 ); - n1.addAssociation( rule3 ); - n2.addAssociation( rule1 ); - n2.addAssociation( rule2 ); - n2.addAssociation( rule3 ); - n3.addAssociation( rule1 ); - n3.addAssociation( rule2 ); - n3.addAssociation( rule3 ); + lian.addAssociation(rule1, null); + lian.addAssociation(rule2, null); + lian.addAssociation(rule3, null); + n1.addAssociation(rule1, null); + n1.addAssociation(rule2, null); + n1.addAssociation(rule3, null); + n2.addAssociation(rule1, null); + n2.addAssociation(rule2, null); + n2.addAssociation(rule3, null); + n3.addAssociation(rule1, null); + n3.addAssociation(rule2, null); + n3.addAssociation(rule3, null); - n4.addAssociation( rule2 ); - n4.addAssociation( rule3 ); - n5.addAssociation( rule2 ); - n5.addAssociation( rule3 ); + n4.addAssociation(rule2, null); + n4.addAssociation(rule3, null); + n5.addAssociation(rule2, null); + n5.addAssociation(rule3, null); - n6.addAssociation( rule3 ); - n7.addAssociation( rule3 ); - n8.addAssociation( rule3 ); + n6.addAssociation(rule3, null); + n7.addAssociation(rule3, null); + n8.addAssociation(rule3, null); // assumes no subnetworks for (TerminalNode tn : new TerminalNode[] {rtn1, rtn2, rtn3}) { @@ -327,10 +334,10 @@ public void testRuleSegmentLinking() { DefaultFactHandle f1 = (DefaultFactHandle) wm.insert( "test1" ); lian.assertObject( f1, context, wm ); - n1.assertObject( f1, context, wm ); - n3.assertObject( f1, context, wm ); - n4.assertObject( f1, context, wm ); - n8.assertObject( f1, context, wm ); + n1.getRightInput().assertObject( f1, context, wm ); + n3.getRightInput().assertObject( f1, context, wm ); + n4.getRightInput().assertObject( f1, context, wm ); + n8.getRightInput().assertObject( f1, context, wm ); assertThat(rtn1Rs.isRuleLinked()).isFalse(); assertThat(rtn2Rs.isRuleLinked()).isFalse(); @@ -342,7 +349,7 @@ public void testRuleSegmentLinking() { assertThat(bm.getSegmentMemory().isSegmentLinked()).isFalse(); DefaultFactHandle f2 = (DefaultFactHandle) wm.insert( "test2" ); - n2.assertObject( f2, context, wm ); + n2.getRightInput().assertObject( f2, context, wm ); assertThat(bm.getSegmentMemory().isSegmentLinked()).isTrue(); assertThat(rtn1Rs.isRuleLinked()).isTrue(); @@ -353,7 +360,7 @@ public void testRuleSegmentLinking() { bm = (BetaMemory) wm.getNodeMemory(n5); assertThat(bm.getSegmentMemory().isSegmentLinked()).isFalse(); - n5.assertObject( f1, context, wm ); + n5.getRightInput().assertObject( f1, context, wm ); assertThat(bm.getSegmentMemory().isSegmentLinked()).isTrue(); assertThat(rtn1Rs.isRuleLinked()).isTrue(); @@ -361,8 +368,8 @@ public void testRuleSegmentLinking() { assertThat(rtn3Rs.isRuleLinked()).isFalse(); // Link in Rule3 - n6.assertObject( f1, context, wm ); - n7.assertObject( f1, context, wm ); + n6.getRightInput().assertObject( f1, context, wm ); + n7.getRightInput().assertObject( f1, context, wm ); assertThat(bm.getSegmentMemory().isSegmentLinked()).isTrue(); assertThat(rtn1Rs.isRuleLinked()).isTrue(); @@ -370,7 +377,7 @@ public void testRuleSegmentLinking() { assertThat(rtn3Rs.isRuleLinked()).isTrue(); // retract n2, should unlink all rules - n2.retractRightTuple( f2.getFirstRightTuple(), context, wm ); + n2.getRightInput().retractRightTuple( f2.getFirstRightTuple(), context, wm ); assertThat(rtn1Rs.isRuleLinked()).isFalse(); assertThat(rtn2Rs.isRuleLinked()).isFalse(); assertThat(rtn3Rs.isRuleLinked()).isFalse(); diff --git a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/IndexTest.java b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/IndexTest.java index 67b8177bd58..1c2f0f29b63 100644 --- a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/IndexTest.java +++ b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/IndexTest.java @@ -23,6 +23,7 @@ import org.drools.base.base.ClassObjectType; import org.drools.core.reteoo.AlphaNode; import org.drools.core.reteoo.BetaNode; +import org.drools.core.reteoo.RightInputAdapterNode; import org.drools.core.reteoo.CompositeObjectSinkAdapter; import org.drools.core.reteoo.EntryPointNode; import org.drools.core.reteoo.ObjectSink; @@ -58,7 +59,7 @@ public void testBetaIndexOnDeclaration() { KieSession ksession = getKieSession( str ); ObjectTypeNode otn = getObjectTypeNodeForClass( ksession, Person.class ); - BetaNode beta = (BetaNode) otn.getObjectSinkPropagator().getSinks()[0]; + BetaNode beta = ((RightInputAdapterNode)otn.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); IndexableConstraint betaConstraint = (IndexableConstraint) beta.getConstraints()[0]; assertThat(betaConstraint.getLeftIndexExtractor()).isNotNull(); @@ -222,7 +223,7 @@ public void testBetaIndexOn2ValuesOnLeftTuple() { KieSession ksession = getKieSession( str ); ObjectTypeNode otn = getObjectTypeNodeForClass( ksession, Person.class ); - BetaNode beta = (BetaNode) otn.getObjectSinkPropagator().getSinks()[0]; + BetaNode beta = ((RightInputAdapterNode)otn.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); // this beta index is only supported by executable model assertThat(beta.getRawConstraints().isIndexed()).isEqualTo(this.testRunType.isExecutableModel()); @@ -327,7 +328,7 @@ public void testBetaIndexOn3ValuesOnLeftTuple() { KieSession ksession = getKieSession( str ); ObjectTypeNode otn = getObjectTypeNodeForClass( ksession, Person.class ); - BetaNode beta = (BetaNode) otn.getObjectSinkPropagator().getSinks()[0]; + BetaNode beta = ((RightInputAdapterNode)otn.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); // this beta index is only supported by executable model assertThat(beta.getRawConstraints().isIndexed()).isEqualTo(this.testRunType.isExecutableModel()); @@ -356,7 +357,7 @@ public void testBetaIndexOn4ValuesOnLeftTuple() { KieSession ksession = getKieSession( str ); ObjectTypeNode otn = getObjectTypeNodeForClass( ksession, Person.class ); - BetaNode beta = (BetaNode) otn.getObjectSinkPropagator().getSinks()[0]; + BetaNode beta = ((RightInputAdapterNode)otn.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); // this beta index is only supported by executable model assertThat(beta.getRawConstraints().isIndexed()).isEqualTo(this.testRunType.isExecutableModel()); diff --git a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/PropertyReactivityTest.java b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/PropertyReactivityTest.java index 66b9b8549c4..6de087c7858 100644 --- a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/PropertyReactivityTest.java +++ b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/PropertyReactivityTest.java @@ -322,7 +322,7 @@ public void testImmutableField() { } - @Test(timeout = 5000L) + @Test //(timeout = 5000L) public void testPRAfterAccumulate() { // DROOLS-2427 final String str = diff --git a/drools-mvel/src/test/java/org/drools/mvel/compiler/rule/builder/dialect/mvel/MVELConsequenceBuilderTest.java b/drools-mvel/src/test/java/org/drools/mvel/compiler/rule/builder/dialect/mvel/MVELConsequenceBuilderTest.java index 6e63fa9aac5..c0c8abf5822 100644 --- a/drools-mvel/src/test/java/org/drools/mvel/compiler/rule/builder/dialect/mvel/MVELConsequenceBuilderTest.java +++ b/drools-mvel/src/test/java/org/drools/mvel/compiler/rule/builder/dialect/mvel/MVELConsequenceBuilderTest.java @@ -26,42 +26,29 @@ import java.util.Map.Entry; import java.util.Properties; -import org.drools.base.base.ValueResolver; import org.drools.compiler.builder.impl.KnowledgeBuilderConfigurationImpl; import org.drools.compiler.builder.impl.KnowledgeBuilderImpl; import org.drools.compiler.compiler.Dialect; import org.drools.compiler.compiler.DialectCompiletimeRegistry; +import org.drools.core.impl.KnowledgeBaseImpl; import org.drools.core.reteoo.MockLeftTupleSink; import org.drools.core.reteoo.RuleTerminalNodeLeftTuple; import org.drools.core.reteoo.TupleFactory; -import org.drools.core.reteoo.TupleImpl; import org.drools.drl.parser.DrlParser; import org.drools.drl.parser.DroolsParserException; import org.drools.compiler.compiler.PackageRegistry; import org.drools.compiler.rule.builder.RuleBuildContext; import org.drools.compiler.rule.builder.RuleBuilder; -import org.drools.core.RuleBaseConfiguration; import org.drools.base.base.ClassObjectType; -import org.drools.core.common.EmptyBetaConstraints; import org.drools.core.common.InternalFactHandle; -import org.drools.core.common.Memory; import org.drools.core.common.PropagationContextFactory; -import org.drools.core.common.ReteEvaluator; import org.drools.base.definitions.InternalKnowledgePackage; import org.drools.base.definitions.rule.impl.RuleImpl; -import org.drools.core.reteoo.BetaNode; import org.drools.core.reteoo.CoreComponentFactory; import org.drools.core.reteoo.LeftTuple; -import org.drools.core.reteoo.LeftTuple; -import org.drools.core.reteoo.LeftTupleSource; import org.drools.core.reteoo.MockTupleSource; -import org.drools.core.reteoo.ModifyPreviousTuples; -import org.drools.core.reteoo.ObjectSource; -import org.drools.core.reteoo.ReteooBuilder; -import org.drools.core.reteoo.RuleRemovalContext; import org.drools.core.reteoo.RuleTerminalNode; import org.drools.core.reteoo.RuntimeComponentFactory; -import org.drools.core.reteoo.Sink; import org.drools.core.reteoo.builder.BuildContext; import org.drools.base.rule.Declaration; import org.drools.base.rule.GroupElement; @@ -214,8 +201,9 @@ public void testImperativeCodeError() throws Exception { final Cheese cheddar = new Cheese( "cheddar", 10 ); final InternalFactHandle f0 = (InternalFactHandle) ksession.insert( cheddar ); + BuildContext bctx = new BuildContext(new KnowledgeBaseImpl("id0"), Collections.emptyList()); final LeftTuple tuple = new LeftTuple( f0, - new MockLeftTupleSink(0), + new MockLeftTupleSink(0, bctx), true ); RuleTerminalNode rtn = new RuleTerminalNode(); @@ -452,65 +440,4 @@ public void testDefaultConsequenceWithMultipleNamedConsequenceCompilation() { assertThat(context.getRule().getNamedConsequence("name2")).isNotSameAs(context.getRule().getConsequence()); assertThat(context.getRule().getNamedConsequence("name2")).isNotSameAs(context.getRule().getNamedConsequence( "name1")); } - - public static class MockBetaNode extends BetaNode { - - public MockBetaNode() { - - } - - @Override - protected boolean doRemove( RuleRemovalContext context, ReteooBuilder builder) { - return true; - } - - MockBetaNode(final int id, - final LeftTupleSource leftInput, - final ObjectSource rightInput, - BuildContext buildContext) { - super( id, - leftInput, - rightInput, - EmptyBetaConstraints.getInstance(), - buildContext ); - } - - MockBetaNode(final int id, - final LeftTupleSource leftInput, - final ObjectSource rightInput) { - super( id, - leftInput, - rightInput, - EmptyBetaConstraints.getInstance(), - null ); - } - - public void assertObject(final InternalFactHandle factHandle, - final PropagationContext pctx, - final ValueResolver valueResolver) { - } - - @Override - public void modifyObject( InternalFactHandle factHandle, ModifyPreviousTuples modifyPreviousTuples, PropagationContext context, ReteEvaluator reteEvaluator) { - } - - public void retractRightTuple(final TupleImpl rightTuple, - final PropagationContext context, - final ReteEvaluator reteEvaluator) { - } - - public int getType() { - return 0; - } - - public void modifyRightTuple(TupleImpl rightTuple, - PropagationContext context, - ReteEvaluator reteEvaluator) { - } - - public Memory createMemory(RuleBaseConfiguration config, ReteEvaluator reteEvaluator) { - return super.createMemory( config, reteEvaluator); - } - - } } diff --git a/drools-retediagram/src/main/java/org/drools/retediagram/ReteDiagram.java b/drools-retediagram/src/main/java/org/drools/retediagram/ReteDiagram.java index 105723ce0ce..6b69f3a248e 100644 --- a/drools-retediagram/src/main/java/org/drools/retediagram/ReteDiagram.java +++ b/drools-retediagram/src/main/java/org/drools/retediagram/ReteDiagram.java @@ -53,7 +53,7 @@ import org.drools.core.reteoo.ObjectSource; import org.drools.core.reteoo.ObjectTypeNode; import org.drools.core.reteoo.Rete; -import org.drools.core.reteoo.RightInputAdapterNode; +import org.drools.core.reteoo.TupleToObjectNode; import org.drools.core.reteoo.RuleTerminalNode; import org.drools.core.reteoo.Sink; import org.drools.base.rule.constraint.BetaConstraint; @@ -245,7 +245,7 @@ private static void printNodeMap(HashMap, ListLeftInputAdapterNode.class.isAssignableFrom( kv.getKey() )) .flatMap(kv->kv.getValue().stream()).collect(toList()); printNodeMapNodes(l3, out); - printNodeMapNodes(nodeMap.getOrDefault(RightInputAdapterNode.class, Collections.emptyList()), out); + printNodeMapNodes(nodeMap.getOrDefault(TupleToObjectNode.class, Collections.emptyList()), out); // Level 4: BN List l4 = nodeMap.entrySet().stream() .filter(kv->BetaNode.class.isAssignableFrom( kv.getKey() )) @@ -304,7 +304,7 @@ private void printLevelMap(HashMap, Set> lev // RIA Set lria = levelMap.entrySet().stream() - .filter(kv->RightInputAdapterNode.class.isAssignableFrom( kv.getKey() )) + .filter(kv-> TupleToObjectNode.class.isAssignableFrom(kv.getKey())) .flatMap(kv->kv.getValue().stream()).collect(toSet()); printLevelMapLevel("lria", lria, out); @@ -425,7 +425,7 @@ private static String printNodeId(BaseNode node) { return "AN"+node.getId(); } else if (node instanceof LeftInputAdapterNode ) { return "LIA"+node.getId(); - } else if (node instanceof RightInputAdapterNode ) { + } else if (node instanceof TupleToObjectNode) { return "RIA"+node.getId(); } else if (node instanceof BetaNode ) { return "BN"+node.getId(); @@ -450,7 +450,7 @@ private static String printNodeAttributes(BaseNode node) { escapeDot(n.getConstraint().toString())); } else if (node instanceof LeftInputAdapterNode ) { return "[shape=house orientation=-90]"; - } else if (node instanceof RightInputAdapterNode ) { + } else if (node instanceof TupleToObjectNode) { return "[shape=house orientation=90]"; } else if (node instanceof JoinNode ) { BetaNode n = (BetaNode) node; diff --git a/drools-serialization-protobuf/src/main/java/org/drools/serialization/protobuf/iterators/LeftTupleIterator.java b/drools-serialization-protobuf/src/main/java/org/drools/serialization/protobuf/iterators/LeftTupleIterator.java index e94d74455e7..e865089074c 100644 --- a/drools-serialization-protobuf/src/main/java/org/drools/serialization/protobuf/iterators/LeftTupleIterator.java +++ b/drools-serialization-protobuf/src/main/java/org/drools/serialization/protobuf/iterators/LeftTupleIterator.java @@ -18,6 +18,7 @@ */ package org.drools.serialization.protobuf.iterators; +import org.drools.core.common.BaseNode; import org.drools.core.common.InternalFactHandle; import org.drools.core.common.InternalWorkingMemory; import org.drools.core.common.MemoryFactory; @@ -149,9 +150,9 @@ public TupleImpl getFirstLeftTuple(LeftTupleSource source, } case NodeTypeEnums.LeftInputAdapterNode: case NodeTypeEnums.AlphaTerminalNode: { - ObjectSource os = ((LeftInputAdapterNode) source).getParentObjectSource(); + BaseNode os = ((LeftInputAdapterNode) source).getParentObjectSource(); while ( !(os instanceof ObjectTypeNode) ) { - os = os.getParentObjectSource(); + os = os.getParent(); } ObjectTypeNode otn = (ObjectTypeNode) os; diff --git a/drools-serialization-protobuf/src/main/java/org/drools/serialization/protobuf/iterators/PhreakActivationIterator.java b/drools-serialization-protobuf/src/main/java/org/drools/serialization/protobuf/iterators/PhreakActivationIterator.java index 8af734daaa9..198207dabd6 100644 --- a/drools-serialization-protobuf/src/main/java/org/drools/serialization/protobuf/iterators/PhreakActivationIterator.java +++ b/drools-serialization-protobuf/src/main/java/org/drools/serialization/protobuf/iterators/PhreakActivationIterator.java @@ -22,6 +22,10 @@ import java.util.List; import org.drools.base.reteoo.NodeTypeEnums; +import org.drools.core.common.BaseNode; +import org.drools.core.common.InternalFactHandle; +import org.drools.core.common.InternalWorkingMemory; +import org.drools.core.common.Memory; import org.drools.core.common.ReteEvaluator; import org.drools.core.impl.InternalRuleBase; import org.drools.core.phreak.RuleExecutor; diff --git a/drools-serialization-protobuf/src/main/java/org/drools/serialization/protobuf/marshalling/RuleBaseNodes.java b/drools-serialization-protobuf/src/main/java/org/drools/serialization/protobuf/marshalling/RuleBaseNodes.java index bd72d40cc49..7a95425b102 100644 --- a/drools-serialization-protobuf/src/main/java/org/drools/serialization/protobuf/marshalling/RuleBaseNodes.java +++ b/drools-serialization-protobuf/src/main/java/org/drools/serialization/protobuf/marshalling/RuleBaseNodes.java @@ -23,6 +23,7 @@ import org.drools.core.common.BaseNode; import org.drools.core.impl.InternalRuleBase; +import org.drools.core.reteoo.RightInputAdapterNode; import org.drools.core.reteoo.LeftTupleSink; import org.drools.core.reteoo.LeftTupleSource; import org.drools.core.reteoo.ObjectSink; @@ -61,6 +62,10 @@ private static void addObjectSink(InternalRuleBase kBase, leftTupleSink, nodes); } + } else if ( sink instanceof RightInputAdapterNode) { + RightInputAdapterNode node = (RightInputAdapterNode) sink; + nodes.put( sink.getId(), ((BaseNode)sink) ); + addLeftTupleSink(kBase, node.getBetaNode(), nodes); } else if ( sink instanceof WindowNode ) { WindowNode node = (WindowNode) sink; nodes.put( sink.getId(), ((BaseNode)sink) ); diff --git a/drools-serialization-protobuf/src/test/java/org/drools/serialization/protobuf/MarshallingTest.java b/drools-serialization-protobuf/src/test/java/org/drools/serialization/protobuf/MarshallingTest.java index 3258b90b1f8..04f5f61d405 100644 --- a/drools-serialization-protobuf/src/test/java/org/drools/serialization/protobuf/MarshallingTest.java +++ b/drools-serialization-protobuf/src/test/java/org/drools/serialization/protobuf/MarshallingTest.java @@ -54,6 +54,8 @@ import org.drools.core.impl.RuleBaseFactory; import org.drools.core.marshalling.ClassObjectMarshallingStrategyAcceptor; import org.drools.core.reteoo.CoreComponentFactory; +import org.drools.core.reteoo.JoinNode; +import org.drools.core.reteoo.JoinRightAdapterNode; import org.drools.core.reteoo.MockTupleSource; import org.drools.core.reteoo.ObjectTypeNode; import org.drools.core.reteoo.RuleTerminalNode; @@ -1057,11 +1059,12 @@ public void testSingleRuleSingleJoinNodePattern() throws Exception { // Make sure the rete node map is created correctly Map nodes = RuleBaseNodes.getNodeMap( (InternalKnowledgeBase) kBase); - assertThat(nodes.size()).isEqualTo(5); + assertThat(nodes.size()).isEqualTo(6); assertThat(((ClassObjectType) ((ObjectTypeNode) nodes.get(3)).getObjectType()).getClassType().getSimpleName()).isEqualTo("Cheese"); assertThat(((ClassObjectType) ((ObjectTypeNode) nodes.get(5)).getObjectType()).getClassType().getSimpleName()).isEqualTo("Person"); - assertThat(nodes.get(6).getClass().getSimpleName().endsWith("JoinNode")).as("Should end with JoinNode").isTrue(); - assertThat(((RuleTerminalNode) nodes.get(7)).getRule().getName()).isEqualTo("Rule 1"); + assertThat(nodes.get(6).getClass() == JoinRightAdapterNode.class).as("Should end with JoinNode").isTrue(); + assertThat(nodes.get(7).getClass() == JoinNode.class).as("Should end with JoinNode").isTrue(); + assertThat(((RuleTerminalNode) nodes.get(8)).getRule().getName()).isEqualTo("Rule 1"); KieSession session = kBase.newKieSession(); diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/AccumulateMvelDialectTest.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/AccumulateMvelDialectTest.java index 654e28c72c0..8ba6cceb00e 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/AccumulateMvelDialectTest.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/AccumulateMvelDialectTest.java @@ -25,11 +25,11 @@ import java.util.List; import java.util.Map; -import org.drools.core.reteoo.JoinNode; +import org.drools.core.reteoo.JoinRightAdapterNode; import org.drools.core.reteoo.LeftTupleSink; import org.drools.core.reteoo.ObjectSink; import org.drools.core.reteoo.ObjectTypeNode; -import org.drools.core.reteoo.RightInputAdapterNode; +import org.drools.core.reteoo.TupleToObjectNode; import org.drools.testcoverage.common.model.Cheese; import org.drools.testcoverage.common.model.Person; import org.drools.testcoverage.common.util.KieBaseTestConfiguration; @@ -310,11 +310,11 @@ public void testAccumulateWithSameSubnetwork() { final ObjectSink[] oSinks = cheeseOtn.getObjectSinkPropagator().getSinks(); assertThat(oSinks.length).isEqualTo(1); - final JoinNode cheeseJoin = (JoinNode) oSinks[0]; - final LeftTupleSink[] ltSinks = cheeseJoin.getSinkPropagator().getSinks(); + final JoinRightAdapterNode cheeseJoin = (JoinRightAdapterNode ) oSinks[0]; + final LeftTupleSink[] ltSinks = cheeseJoin.getBetaNode().getSinkPropagator().getSinks(); assertThat(ltSinks.length).isEqualTo(1); - final RightInputAdapterNode rian = (RightInputAdapterNode) ltSinks[0]; + final TupleToObjectNode rian = (TupleToObjectNode) ltSinks[0]; assertThat(rian.getObjectSinkPropagator().size()).isEqualTo(2); // RiaNode is shared, if this has two outputs wm.insert(new Cheese("stilton", 10)); diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/AlphaNetworkModifyTest.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/AlphaNetworkModifyTest.java index 95779125b12..9842319802e 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/AlphaNetworkModifyTest.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/AlphaNetworkModifyTest.java @@ -169,8 +169,8 @@ public void testModifyWithLiaToFrom() { final LeftTupleSink[] sinks = liaNode.getSinkPropagator().getSinks(); assertThat(sinks.length).isEqualTo(2); - assertThat(sinks[0].getLeftInputOtnId().getId()).isEqualTo(0); - assertThat(sinks[1].getLeftInputOtnId().getId()).isEqualTo(1); + assertThat(sinks[0].getInputOtnId().getId()).isEqualTo(0); + assertThat(sinks[1].getInputOtnId().getId()).isEqualTo(1); } finally { wm.dispose(); } @@ -224,9 +224,9 @@ public void testModifyWithLiaToAcc() { final LeftTupleSink[] sinks = liaNode.getSinkPropagator().getSinks(); - assertThat(sinks[0].getLeftInputOtnId().getId()).isEqualTo(0); - assertThat(sinks[1].getLeftInputOtnId().getId()).isEqualTo(1); - assertThat(sinks[2].getLeftInputOtnId().getId()).isEqualTo(2); + assertThat(sinks[0].getInputOtnId().getId()).isEqualTo(0); + assertThat(sinks[1].getInputOtnId().getId()).isEqualTo(1); + assertThat(sinks[2].getInputOtnId().getId()).isEqualTo(2); final ObjectTypeNode otnPerson = getObjectTypeNode(kbase, "Person" ); final ObjectTypeNode otnCheese = getObjectTypeNode(kbase, "Cheese" ); diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/BackwardChainingTest.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/BackwardChainingTest.java index a0fd4c1212f..6fb0ac8ad92 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/BackwardChainingTest.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/BackwardChainingTest.java @@ -37,14 +37,18 @@ import org.drools.core.common.InternalWorkingMemory; import org.drools.core.impl.InternalRuleBase; import org.drools.core.reteoo.AccumulateNode; +import org.drools.core.reteoo.AccumulateRight; import org.drools.core.reteoo.BetaMemory; import org.drools.core.reteoo.BetaNode; import org.drools.core.reteoo.ExistsNode; +import org.drools.core.reteoo.ExistsRight; import org.drools.core.reteoo.FromNode; +import org.drools.core.reteoo.JoinRightAdapterNode; import org.drools.core.reteoo.NotNode; +import org.drools.core.reteoo.NotRight; import org.drools.core.reteoo.ObjectTypeNode; import org.drools.core.reteoo.QueryElementNode; -import org.drools.core.reteoo.RightInputAdapterNode; +import org.drools.core.reteoo.TupleToObjectNode; import org.drools.kiesession.rulebase.InternalKnowledgeBase; import org.drools.kiesession.session.StatefulKnowledgeSessionImpl; import org.drools.testcoverage.common.model.Address; @@ -2232,19 +2236,19 @@ public void testSubNetworksAndQueries() { } assertThat(node).isNotNull(); - final BetaNode stringBetaNode = (BetaNode) node.getObjectSinkPropagator().getSinks()[0]; - final QueryElementNode queryElementNode1 = (QueryElementNode) stringBetaNode.getSinkPropagator().getSinks()[0]; - final RightInputAdapterNode riaNode1 = (RightInputAdapterNode) queryElementNode1.getSinkPropagator().getSinks()[0]; - final AccumulateNode accNode = (AccumulateNode) riaNode1.getObjectSinkPropagator().getSinks()[0]; + final BetaNode stringBetaNode = ((JoinRightAdapterNode) node.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + final QueryElementNode queryElementNode1 = (QueryElementNode) stringBetaNode.getSinkPropagator().getSinks()[0]; + final TupleToObjectNode riaNode1 = (TupleToObjectNode) queryElementNode1.getSinkPropagator().getSinks()[0]; + final AccumulateNode accNode =((AccumulateRight) riaNode1.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); - final QueryElementNode queryElementNode2 = (QueryElementNode) accNode.getSinkPropagator().getSinks()[0]; - final RightInputAdapterNode riaNode2 = (RightInputAdapterNode) queryElementNode2.getSinkPropagator().getSinks()[0]; - final ExistsNode existsNode = (ExistsNode) riaNode2.getObjectSinkPropagator().getSinks()[0]; + final QueryElementNode queryElementNode2 = (QueryElementNode) accNode.getSinkPropagator().getSinks()[0]; + final TupleToObjectNode riaNode2 = (TupleToObjectNode) queryElementNode2.getSinkPropagator().getSinks()[0]; + final ExistsNode existsNode = ((ExistsRight)riaNode2.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); final QueryElementNode queryElementNode3 = (QueryElementNode) existsNode.getSinkPropagator().getSinks()[0]; - final FromNode fromNode = (FromNode) queryElementNode3.getSinkPropagator().getSinks()[0]; - final RightInputAdapterNode riaNode3 = (RightInputAdapterNode) fromNode.getSinkPropagator().getSinks()[0]; - final NotNode notNode = (NotNode) riaNode3.getObjectSinkPropagator().getSinks()[0]; + final FromNode fromNode = (FromNode) queryElementNode3.getSinkPropagator().getSinks()[0]; + final TupleToObjectNode riaNode3 = (TupleToObjectNode) fromNode.getSinkPropagator().getSinks()[0]; + final NotNode notNode = ((NotRight)riaNode3.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); final KieSession ksession = kbase.newKieSession(); try { diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/CepEspTest.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/CepEspTest.java index 9e5795baf7c..f96856f19da 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/CepEspTest.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/CepEspTest.java @@ -5728,13 +5728,14 @@ public void testCollectExpiredEvent() { SessionPseudoClock clock = ksession.getSessionClock(); - ksession.insert(1); + FactHandle fh1 = ksession.insert(1); clock.advanceTime(2, TimeUnit.HOURS); - ksession.insert(2L); + FactHandle fh2 = ksession.insert(2L); assertThat(ksession.fireAllRules()).isEqualTo(0); clock.advanceTime(2, TimeUnit.HOURS); // Should expire first event - ksession.insert(1L); + + FactHandle fh3 = ksession.insert(1L); assertThat(ksession.fireAllRules()).isEqualTo(0); } finally { diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/JoinNodeRangeIndexingTest.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/JoinNodeRangeIndexingTest.java index d1616208a80..fba7c68d7a1 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/JoinNodeRangeIndexingTest.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/JoinNodeRangeIndexingTest.java @@ -30,6 +30,7 @@ import org.drools.ancompiler.CompiledNetwork; import org.drools.core.common.BetaConstraints; import org.drools.core.reteoo.JoinNode; +import org.drools.core.reteoo.JoinRightAdapterNode; import org.drools.core.reteoo.ObjectSink; import org.drools.core.reteoo.ObjectSinkPropagator; import org.drools.core.reteoo.ObjectTypeNode; @@ -118,8 +119,8 @@ private void assertIndexed(KieBase kbase, Class factClass, boolean isIndexed) boolean isPassedForJoinNode = false; ObjectSink[] sinks = objectSinkPropagator.getSinks(); for (ObjectSink sink : sinks) { - if (sink instanceof JoinNode) { - JoinNode join = (JoinNode) sink; + if (sink instanceof JoinRightAdapterNode) { + JoinNode join = ((JoinRightAdapterNode) sink).getBetaNode(); BetaConstraints betaConstraints = join.getRawConstraints(); assertThat(betaConstraints.isIndexed()).isEqualTo(isIndexed); isPassedForJoinNode = true; diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/NegativePatternsTest.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/NegativePatternsTest.java index 6aa38d2258a..f0eb0928d24 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/NegativePatternsTest.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/NegativePatternsTest.java @@ -51,7 +51,7 @@ @RunWith(Parameterized.class) public class NegativePatternsTest { - private static final int LOOPS = 300; + private static final int LOOPS = 2; private static final int SHORT_SLEEP_TIME = 20; private static final int LONG_SLEEP_TIME = 30; @@ -217,12 +217,15 @@ public void testMultipleEvents() { final FactHandle handle = entryPoint.insert(new TestEvent(-1, "EventB")); advanceTime(SHORT_SLEEP_TIME); ksession.fireAllRules(); + assertThat(firedRulesListener.ruleFiredCount("MultipleEvents")).isEqualTo(count); entryPoint.delete(handle); ksession.fireAllRules(); + assertThat(firedRulesListener.ruleFiredCount("MultipleEvents")).isEqualTo(count); // it shouldn't fire because of the duration advanceTime(SHORT_SLEEP_TIME); ksession.fireAllRules(); + assertThat(firedRulesListener.ruleFiredCount("MultipleEvents")).isEqualTo(count); // it shouldn't fire because event A is gone out of window while (count < LOOPS) { diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/operators/NotTest.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/operators/NotTest.java index 6416b6e48c8..1a49e8738d5 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/operators/NotTest.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/operators/NotTest.java @@ -29,6 +29,7 @@ import org.drools.core.impl.InternalRuleBase; import org.drools.core.reteoo.BetaMemory; import org.drools.core.reteoo.BetaNode; +import org.drools.core.reteoo.NotRight; import org.drools.core.reteoo.ObjectTypeNode; import org.drools.core.reteoo.RightTuple; import org.drools.core.reteoo.TupleImpl; @@ -207,7 +208,7 @@ public void testMissingRootBlockerEquality() { private InternalFactHandle getBlockerFactHandle(KieSession ksession) { ObjectTypeNode otn = getObjectTypeNode(ksession.getKieBase(), Person.class); - BetaNode notNode = (BetaNode) otn.getSinks()[0].getSinks()[0]; + BetaNode notNode = ((NotRight)otn.getSinks()[0].getSinks()[0]).getBetaNode(); StatefulKnowledgeSessionImpl ksessionImpl = (StatefulKnowledgeSessionImpl) ksession; NodeMemories nodeMemories = ksessionImpl.getNodeMemories(); diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/CompositeObjectSinkAdapterTest.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/CompositeObjectSinkAdapterTest.java index afd7692759a..11955fa27f3 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/CompositeObjectSinkAdapterTest.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/CompositeObjectSinkAdapterTest.java @@ -27,9 +27,11 @@ import org.drools.core.base.ClassFieldAccessorCache; import org.drools.core.common.InternalFactHandle; import org.drools.core.reteoo.AlphaNode; -import org.drools.core.reteoo.BetaNode; +import org.drools.core.reteoo.RightInputAdapterNode; import org.drools.core.reteoo.CompositeObjectSinkAdapter; import org.drools.core.reteoo.CompositeObjectSinkAdapter.HashKey; +import org.drools.core.reteoo.JoinRightAdapterNode; +import org.drools.core.reteoo.MockObjectSink; import org.drools.core.reteoo.ObjectSink; import org.drools.core.reteoo.ReteooFactHandleFactory; import org.drools.core.reteoo.builder.BuildContext; @@ -94,8 +96,8 @@ public void setUp() throws Exception { @Test public void testAddBeta() { - final MockBetaNode beta = createBetaNode(); - + RightInputAdapterNode beta = new JoinRightAdapterNode(0, new MockObjectSink(), buildContext); + ad.addObjectSink( beta ); sinksAre(beta); @@ -107,7 +109,7 @@ public void testAddBeta() { @Test public void testAddBetaRemoveBeta() { - final MockBetaNode beta = createBetaNode(); + RightInputAdapterNode beta = new JoinRightAdapterNode(0, new MockObjectSink(), buildContext); ad.addObjectSink( beta ); ad.removeObjectSink( beta ); @@ -183,7 +185,7 @@ public void testAddTwoAlphasAddOneBeta() { ad.addObjectSink( al ); final AlphaNode al2 = createAlphaNode(cheeseTypeEqualsTo("cheddar")); ad.addObjectSink( al2 ); - final BetaNode beta = createBetaNode(); + RightInputAdapterNode beta = new JoinRightAdapterNode(0, new MockObjectSink(), buildContext); ad.addObjectSink( beta ); @@ -198,7 +200,8 @@ public void testAddTwoAlphasAddOneBetaRemoveOneBeta() { ad.addObjectSink( al ); final AlphaNode al2 = createAlphaNode(cheeseTypeEqualsTo("cheddar")); ad.addObjectSink( al2 ); - final BetaNode beta = createBetaNode(); + RightInputAdapterNode beta = new JoinRightAdapterNode(0, new MockObjectSink(), buildContext); + ad.addObjectSink( beta ); ad.removeObjectSink( beta ); @@ -475,7 +478,7 @@ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundExcept private MockBetaNode createBetaNode() { return new MockBetaNode( buildContext.getNextNodeId(), new MockBetaNode( ), - new MockObjectSource(), + new JoinRightAdapterNode(0, new MockObjectSink(), buildContext), buildContext ); } diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/LeftTupleIndexHashTableIteratorTest.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/LeftTupleIndexHashTableIteratorTest.java index cb4d2bbdc9f..73ed977990e 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/LeftTupleIndexHashTableIteratorTest.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/LeftTupleIndexHashTableIteratorTest.java @@ -19,12 +19,14 @@ package org.drools.mvel; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import org.drools.core.RuleBaseConfiguration; import org.drools.core.common.BetaConstraints; import org.drools.core.common.InternalFactHandle; import org.drools.core.common.SingleBetaConstraints; +import org.drools.core.impl.KnowledgeBaseImpl; import org.drools.core.impl.RuleBaseFactory; import org.drools.core.reteoo.BetaMemory; import org.drools.core.reteoo.LeftTuple; @@ -32,6 +34,7 @@ import org.drools.base.rule.constraint.BetaConstraint; import org.drools.core.reteoo.MockLeftTupleSink; import org.drools.core.reteoo.TupleImpl; +import org.drools.core.reteoo.builder.BuildContext; import org.drools.core.util.FastIterator; import org.drools.core.util.index.TupleIndexHashTable; import org.drools.core.util.index.TupleIndexHashTable.FieldIndexHashTableFullIterator; @@ -81,25 +84,28 @@ public void test1() { InternalFactHandle fh12 = (InternalFactHandle) ss.insert(new Foo("snicker", 0)); InternalFactHandle fh13 = (InternalFactHandle) ss.insert(new Foo("snicker", 0)); - betaMemory.getLeftTupleMemory().add(new LeftTuple(fh1, new MockLeftTupleSink(0), true)); - betaMemory.getLeftTupleMemory().add(new LeftTuple(fh2, new MockLeftTupleSink(0), true)); - betaMemory.getLeftTupleMemory().add(new LeftTuple(fh3, new MockLeftTupleSink(0), true)); - betaMemory.getLeftTupleMemory().add(new LeftTuple(fh4, new MockLeftTupleSink(0), true)); - betaMemory.getLeftTupleMemory().add(new LeftTuple(fh5, new MockLeftTupleSink(0), true)); - betaMemory.getLeftTupleMemory().add(new LeftTuple(fh6, new MockLeftTupleSink(0), true)); - betaMemory.getLeftTupleMemory().add(new LeftTuple(fh7, new MockLeftTupleSink(0), true)); - betaMemory.getLeftTupleMemory().add(new LeftTuple(fh8, new MockLeftTupleSink(0), true)); - betaMemory.getLeftTupleMemory().add(new LeftTuple(fh9, new MockLeftTupleSink(0), true)); + BuildContext bctx = new BuildContext(new KnowledgeBaseImpl("01"), Collections.emptyList()); + MockLeftTupleSink sink = new MockLeftTupleSink(0, bctx); + + betaMemory.getLeftTupleMemory().add(new LeftTuple(fh1, sink, true)); + betaMemory.getLeftTupleMemory().add(new LeftTuple(fh2, sink, true)); + betaMemory.getLeftTupleMemory().add(new LeftTuple(fh3, sink, true)); + betaMemory.getLeftTupleMemory().add(new LeftTuple(fh4, sink, true)); + betaMemory.getLeftTupleMemory().add(new LeftTuple(fh5, sink, true)); + betaMemory.getLeftTupleMemory().add(new LeftTuple(fh6, sink, true)); + betaMemory.getLeftTupleMemory().add(new LeftTuple(fh7, sink, true)); + betaMemory.getLeftTupleMemory().add(new LeftTuple(fh8, sink, true)); + betaMemory.getLeftTupleMemory().add(new LeftTuple(fh9, sink, true)); TupleIndexHashTable hashTable = (TupleIndexHashTable) betaMemory.getLeftTupleMemory(); // can't create a 0 hashCode, so forcing TupleList leftTupleList = new TupleList(); - leftTupleList.add(new LeftTuple(fh10, new MockLeftTupleSink(0), true)); + leftTupleList.add(new LeftTuple(fh10, sink, true)); hashTable.getTable()[0] = leftTupleList; leftTupleList = new TupleList(); - leftTupleList.add(new LeftTuple(fh11, new MockLeftTupleSink(0), true)); - leftTupleList.add(new LeftTuple(fh12, new MockLeftTupleSink(0), true)); - leftTupleList.add(new LeftTuple(fh13, new MockLeftTupleSink(0), true)); + leftTupleList.add(new LeftTuple(fh11, sink, true)); + leftTupleList.add(new LeftTuple(fh12, sink, true)); + leftTupleList.add(new LeftTuple(fh13, sink, true)); hashTable.getTable()[0].setNext(leftTupleList); List tableIndexList = createTableIndexListForAssertion(hashTable); diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/MockBetaNode.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/MockBetaNode.java index 5bdf8ac4f74..b2e04fee79d 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/MockBetaNode.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/MockBetaNode.java @@ -24,15 +24,8 @@ import org.drools.core.common.Memory; import org.drools.core.common.ReteEvaluator; import org.drools.core.reteoo.BetaNode; -import org.drools.core.reteoo.LeftTuple; -import org.drools.core.reteoo.LeftTuple; +import org.drools.core.reteoo.RightInputAdapterNode; import org.drools.core.reteoo.LeftTupleSource; -import org.drools.core.reteoo.ModifyPreviousTuples; -import org.drools.core.reteoo.ObjectSource; -import org.drools.core.reteoo.ReteooBuilder; -import org.drools.core.reteoo.RuleRemovalContext; -import org.drools.core.reteoo.Sink; -import org.drools.core.reteoo.TupleImpl; import org.drools.core.reteoo.builder.BuildContext; import org.drools.core.common.PropagationContext; @@ -42,14 +35,9 @@ public MockBetaNode() { } - @Override - protected boolean doRemove( RuleRemovalContext context, ReteooBuilder builder) { - return true; - } - MockBetaNode(final int id, final LeftTupleSource leftInput, - final ObjectSource rightInput, + final RightInputAdapterNode rightInput, BuildContext buildContext) { super( id, leftInput, @@ -60,7 +48,7 @@ protected boolean doRemove( RuleRemovalContext context, ReteooBuilder builder) { MockBetaNode(final int id, final LeftTupleSource leftInput, - final ObjectSource rightInput) { + final RightInputAdapterNode rightInput) { super( id, leftInput, rightInput, @@ -73,24 +61,11 @@ public void assertObject(final InternalFactHandle factHandle, final ReteEvaluator reteEvaluator) { } - @Override - public void modifyObject( InternalFactHandle factHandle, ModifyPreviousTuples modifyPreviousTuples, PropagationContext context, ReteEvaluator reteEvaluator) { - } - - public void retractRightTuple(final TupleImpl rightTuple, - final PropagationContext context, - final ReteEvaluator reteEvaluator) { - } public int getType() { return 0; } - public void modifyRightTuple(TupleImpl rightTuple, - PropagationContext context, - ReteEvaluator reteEvaluator) { - } - public Memory createMemory(RuleBaseConfiguration config, ReteEvaluator reteEvaluator) { return super.createMemory( config, reteEvaluator); } diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/compiler/MemoryLeakTest.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/compiler/MemoryLeakTest.java index ecee4e74f76..22766f07f65 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/compiler/MemoryLeakTest.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/compiler/MemoryLeakTest.java @@ -37,6 +37,7 @@ import org.drools.core.reteoo.AlphaNode; import org.drools.core.reteoo.BetaMemory; import org.drools.core.reteoo.JoinNode; +import org.drools.core.reteoo.JoinRightAdapterNode; import org.drools.core.reteoo.LeftInputAdapterNode; import org.drools.core.reteoo.ObjectTypeNode; import org.drools.core.reteoo.Rete; @@ -112,7 +113,7 @@ public void testStagedTupleLeak() throws Exception { JoinNode joinNode = null; for ( ObjectTypeNode otn : rete.getObjectTypeNodes() ) { if ( String.class == otn.getObjectType().getValueType().getClassType() ) { - joinNode = (JoinNode) otn.getObjectSinkPropagator().getSinks()[0]; + joinNode = ((JoinRightAdapterNode)otn.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); break; } } diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/compiler/util/debug/SessionInspectorTest.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/compiler/util/debug/SessionInspectorTest.java index c76b87225f9..569ce9042c4 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/compiler/util/debug/SessionInspectorTest.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/compiler/util/debug/SessionInspectorTest.java @@ -103,15 +103,15 @@ public void testGetSessionInfo() { ksession.insert( new Cheese( "Stilton", 10 ) ); ksession.insert( new Cheese( "Stilton", 10 ) ); ksession.insert( new Cheese( "Stilton", 10 ) ); - ksession.insert( new Double( 10 ) ); - ksession.insert( new Double( 11 ) ); - ksession.insert( new Double( 12 ) ); - ksession.insert( new Double( 13 ) ); - ksession.insert( new Double( 14 ) ); - ksession.insert( new Integer( 15 ) ); - ksession.insert( new Integer( 16 ) ); - ksession.insert( new Integer( 17 ) ); - ksession.insert( new Integer( 18 ) ); + ksession.insert( Double.valueOf( 10 ) ); + ksession.insert( Double.valueOf(( 11 ) ) ); + ksession.insert( Double.valueOf(( 12 ) ) ); + ksession.insert( Double.valueOf(( 13 ) ) ); + ksession.insert( Double.valueOf(( 14 ) ) ); + ksession.insert( Integer.valueOf(( 15 ) ) ); + ksession.insert( Integer.valueOf(( 16 ) ) ); + ksession.insert( Integer.valueOf(( 17 ) ) ); + ksession.insert( Integer.valueOf(( 18 ) ) ); FactHandle handle = ksession.insert( new Worker( ) ); ksession.retract( handle ); @@ -177,15 +177,15 @@ public void testGetSessionInfoWithCustomTemplate() { ksession.insert( new Cheese( "Stilton", 10 ) ); ksession.insert( new Cheese( "Stilton", 10 ) ); ksession.insert( new Cheese( "Stilton", 10 ) ); - ksession.insert( new Double( 10 ) ); - ksession.insert( new Double( 11 ) ); - ksession.insert( new Double( 12 ) ); - ksession.insert( new Double( 13 ) ); - ksession.insert( new Double( 14 ) ); - ksession.insert( new Integer( 15 ) ); - ksession.insert( new Integer( 16 ) ); - ksession.insert( new Integer( 17 ) ); - ksession.insert( new Integer( 18 ) ); + ksession.insert( Double.valueOf(( 10 ) ) ); + ksession.insert( Double.valueOf(( 11 ) ) ); + ksession.insert( Double.valueOf(( 12 ) ) ); + ksession.insert( Double.valueOf(( 13 ) ) ); + ksession.insert( Double.valueOf(( 14 ) ) ); + ksession.insert( Integer.valueOf(( 15 ) ) ); + ksession.insert( Integer.valueOf(( 16 ) ) ); + ksession.insert( Integer.valueOf(( 17 ) ) ); + ksession.insert( Integer.valueOf(( 18 ) ) ); FactHandle handle = ksession.insert( new Worker( ) ); ksession.retract( handle ); diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/LinkingTest.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/LinkingTest.java index 8630aaffed3..10a5598bd76 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/LinkingTest.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/LinkingTest.java @@ -29,7 +29,8 @@ import org.drools.core.common.MemoryFactory; import org.drools.core.impl.InternalRuleBase; import org.drools.core.reteoo.BetaMemory; -import org.drools.core.reteoo.RightInputAdapterNode.RiaPathMemory; +import org.drools.core.reteoo.RightInputAdapterNode; +import org.drools.core.reteoo.TupleToObjectNode.SubnetworkPathMemory; import org.drools.kiesession.session.StatefulKnowledgeSessionImpl; import org.drools.core.phreak.RuleAgendaItem; import org.drools.core.phreak.RuleExecutor; @@ -42,7 +43,7 @@ import org.drools.core.reteoo.NotNode; import org.drools.core.reteoo.ObjectTypeNode; import org.drools.core.reteoo.PathMemory; -import org.drools.core.reteoo.RightInputAdapterNode; +import org.drools.core.reteoo.TupleToObjectNode; import org.drools.core.reteoo.RuleTerminalNode; import org.drools.core.reteoo.SegmentMemory; import org.drools.core.reteoo.Tuple; @@ -261,20 +262,20 @@ public void testSubNetworkSharing() throws Exception { ExistsNode existsNode3 = ( ExistsNode) liaNode.getSinkPropagator().getSinks()[2]; JoinNode joinNodeB = ( JoinNode) liaNode.getSinkPropagator().getSinks()[0]; - assertThat(getObjectTypeNode(kbase, B.class)).isSameAs(joinNodeB.getRightInput()); + assertThat(getObjectTypeNode(kbase, B.class)).isSameAs(joinNodeB.getRightInput().getParent()); JoinNode joinNodeC = ( JoinNode) joinNodeB.getSinkPropagator().getSinks()[0]; - assertThat(getObjectTypeNode(kbase, C.class)).isSameAs(joinNodeC.getRightInput()); + assertThat(getObjectTypeNode(kbase, C.class)).isSameAs(joinNodeC.getRightInput().getParent()); assertThat(joinNodeC.getSinkPropagator().size()).isEqualTo(2); JoinNode joinNodeD = ( JoinNode) joinNodeC.getSinkPropagator().getSinks()[0]; - assertThat(getObjectTypeNode(kbase, X.class)).isSameAs(joinNodeD.getRightInput()); + assertThat(getObjectTypeNode(kbase, X.class)).isSameAs(joinNodeD.getRightInput().getParent()); assertThat(joinNodeD.getSinkPropagator().size()).isEqualTo(2); - assertThat(((RightInputAdapterNode) joinNodeC.getSinkPropagator().getSinks()[1]).getObjectSinkPropagator().getSinks()[0]).isSameAs(existsNode2); + assertThat(((RightInputAdapterNode)((TupleToObjectNode) joinNodeC.getSinkPropagator().getSinks()[1]).getObjectSinkPropagator().getSinks()[0]).getBetaNode()).isSameAs(existsNode2); - assertThat(((RightInputAdapterNode) joinNodeD.getSinkPropagator().getSinks()[1]).getObjectSinkPropagator().getSinks()[0]).isSameAs(existsNode3); + assertThat(((RightInputAdapterNode)((TupleToObjectNode) joinNodeD.getSinkPropagator().getSinks()[1]).getObjectSinkPropagator().getSinks()[0]).getBetaNode()).isSameAs(existsNode3); } @Test @@ -423,7 +424,7 @@ public void testSubNetworkRiaLinking() throws Exception { JoinNode dNode = ( JoinNode) cNode.getSinkPropagator().getSinks()[0]; assertThat(dNode.getSinkPropagator().size()).isEqualTo(1); - RightInputAdapterNode riaNode1 = ( RightInputAdapterNode ) dNode.getSinkPropagator().getSinks()[0]; + TupleToObjectNode riaNode1 = (TupleToObjectNode) dNode.getSinkPropagator().getSinks()[0]; JoinNode eNode = ( JoinNode ) exists1n.getSinkPropagator().getSinks()[0]; @@ -571,14 +572,14 @@ public void testNonReactiveSubNetworkOwnSegmentMasks() throws Exception { assertThat(pmem.getSegmentMemories().length).isEqualTo(4); assertThat(pmem.getAllLinkedMaskTest()).isEqualTo(11); // the exists eval segment does not need to be linked in - RiaPathMemory riaMem = (RiaPathMemory) wm.getNodeMemory((MemoryFactory) exists1n.getRightInput()); + SubnetworkPathMemory riaMem = (SubnetworkPathMemory) wm.getNodeMemory((MemoryFactory) exists1n.getRightInput().getParent()); assertThat(riaMem.getAllLinkedMaskTest()).isEqualTo(2); // second segment must be linked in wm.insert( new B() ); wm.insert( new C() ); assertThat(riaMem.getSegmentMemories().length).isEqualTo(2); - riaMem = (RiaPathMemory) wm.getNodeMemory((MemoryFactory) exists2n.getRightInput()); + riaMem = (SubnetworkPathMemory) wm.getNodeMemory((MemoryFactory) exists2n.getRightInput().getParent()); assertThat(riaMem.getAllLinkedMaskTest()).isEqualTo(0); // no segments to be linked in } @@ -625,11 +626,11 @@ public void testNestedSubNetwork() throws Exception { JoinNode eNode = ( JoinNode) dNode.getSinkPropagator().getSinks()[0]; JoinNode fNode = ( JoinNode) eNode.getSinkPropagator().getSinks()[0]; - RightInputAdapterNode riaNode2 = ( RightInputAdapterNode ) fNode.getSinkPropagator().getSinks()[0]; - assertThat(riaNode2.getObjectSinkPropagator().getSinks()[0]).isEqualTo(exists2n); + TupleToObjectNode riaNode2 = (TupleToObjectNode) fNode.getSinkPropagator().getSinks()[0]; + assertThat(((RightInputAdapterNode)riaNode2.getObjectSinkPropagator().getSinks()[0]).getBetaNode()).isEqualTo(exists2n); - RightInputAdapterNode riaNode1 = ( RightInputAdapterNode ) exists2n.getSinkPropagator().getSinks()[0]; - assertThat(riaNode1.getObjectSinkPropagator().getSinks()[0]).isEqualTo(exists1n); + TupleToObjectNode riaNode1 = (TupleToObjectNode) exists2n.getSinkPropagator().getSinks()[0]; + assertThat(((RightInputAdapterNode)riaNode1.getObjectSinkPropagator().getSinks()[0]).getBetaNode()).isEqualTo(exists1n); JoinNode gNode = ( JoinNode) exists1n.getSinkPropagator().getSinks()[0]; RuleTerminalNode rtn = ( RuleTerminalNode) gNode.getSinkPropagator().getSinks()[0]; @@ -697,8 +698,8 @@ public void testNestedSubNetworkMasks() throws Exception { JoinNode eNode = ( JoinNode) dNode.getSinkPropagator().getSinks()[0]; JoinNode fNode = ( JoinNode) eNode.getSinkPropagator().getSinks()[0]; - RightInputAdapterNode riaNode2 = ( RightInputAdapterNode ) fNode.getSinkPropagator().getSinks()[0]; - RightInputAdapterNode riaNode1 = ( RightInputAdapterNode ) exists2n.getSinkPropagator().getSinks()[0]; + TupleToObjectNode riaNode2 = (TupleToObjectNode) fNode.getSinkPropagator().getSinks()[0]; + TupleToObjectNode riaNode1 = (TupleToObjectNode) exists2n.getSinkPropagator().getSinks()[0]; JoinNode gNode = ( JoinNode) exists1n.getSinkPropagator().getSinks()[0]; RuleTerminalNode rtn = ( RuleTerminalNode) gNode.getSinkPropagator().getSinks()[0]; @@ -720,8 +721,8 @@ public void testNestedSubNetworkMasks() throws Exception { BetaMemory fMem = (BetaMemory) wm.getNodeMemory(fNode); BetaMemory gMem = (BetaMemory) wm.getNodeMemory(gNode); - RiaPathMemory riaMem1 = (RiaPathMemory) wm.getNodeMemory(riaNode1); - RiaPathMemory riaMem2 = (RiaPathMemory) wm.getNodeMemory(riaNode2); + SubnetworkPathMemory riaMem1 = (SubnetworkPathMemory) wm.getNodeMemory(riaNode1); + SubnetworkPathMemory riaMem2 = (SubnetworkPathMemory) wm.getNodeMemory(riaNode2); PathMemory rs = wm.getNodeMemory(rtn); diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/NodePositionInPathTest.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/NodePositionInPathTest.java index dec094bab13..35adaa30a55 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/NodePositionInPathTest.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/NodePositionInPathTest.java @@ -30,7 +30,7 @@ import org.drools.core.reteoo.ObjectTypeNode; import org.drools.core.reteoo.Rete; import org.drools.core.reteoo.ReteDumper; -import org.drools.core.reteoo.RightInputAdapterNode; +import org.drools.core.reteoo.TupleToObjectNode; import org.drools.core.reteoo.RuleTerminalNode; import org.drools.testcoverage.common.util.KieBaseTestConfiguration; import org.drools.testcoverage.common.util.KieBaseUtil; @@ -104,12 +104,12 @@ public void test() { BetaNode join3 = (BetaNode) join1.getSinkPropagator().getSinks()[0]; assertThat(join3.getPathIndex()).isEqualTo(2); - RightInputAdapterNode ria1 = (RightInputAdapterNode) join3.getSinkPropagator().getSinks()[0]; + TupleToObjectNode ria1 = (TupleToObjectNode) join3.getSinkPropagator().getSinks()[0]; assertThat(ria1.getPathIndex()).isEqualTo(3); BetaNode join4 = (BetaNode) join1.getSinkPropagator().getSinks()[1]; assertThat(join4.getPathIndex()).isEqualTo(2); - RightInputAdapterNode ria2 = (RightInputAdapterNode) join4.getSinkPropagator().getSinks()[0]; + TupleToObjectNode ria2 = (TupleToObjectNode) join4.getSinkPropagator().getSinks()[0]; assertThat(ria2.getPathIndex()).isEqualTo(3); LeftTupleNode[] rtn1PathNodes = rtn1.getPathNodes(); diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/NodesPartitioningTest.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/NodesPartitioningTest.java index 4c2fc022dab..65e55e1eb47 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/NodesPartitioningTest.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/NodesPartitioningTest.java @@ -86,7 +86,9 @@ private void traverse(BaseNode node ) { NetworkNode[] sinks = node.getSinks(); if (sinks != null) { for (NetworkNode sink : sinks) { - if (sink instanceof BaseNode) { + if (sink instanceof RightInputAdapterNode) { + traverse(((RightInputAdapterNode)sink).getBetaNode()); + } else if (sink instanceof BaseNode) { traverse((BaseNode)sink); } } @@ -99,13 +101,15 @@ private void checkNode(NetworkNode node) { } else if (node instanceof ObjectTypeNode) { assertThat(node.getPartitionId()).isSameAs(RuleBasePartitionId.MAIN_PARTITION); checkPartitionedSinks((ObjectTypeNode) node); - } else if (node instanceof ObjectSource ) { - ObjectSource source = ( (ObjectSource) node ).getParentObjectSource(); + } else if (node instanceof RightInputAdapterNode){ + assertThat(node.getPartitionId()).isSameAs(((RightInputAdapterNode)node).getBetaNode().getPartitionId()); + } if (node instanceof ObjectSource ) { + BaseNode source = ( (ObjectSource) node ).getParent(); if ( !(source instanceof ObjectTypeNode) ) { assertThat(node.getPartitionId()).isSameAs(source.getPartitionId()); } } else if (node instanceof BetaNode ) { - ObjectSource rightInput = ( (BetaNode) node ).getRightInput(); + ObjectSource rightInput = ( (BetaNode) node ).getRightInput().getParent(); if ( !(rightInput instanceof ObjectTypeNode) ) { assertThat(node.getPartitionId()).isSameAs(rightInput.getPartitionId()); } diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/PathEndNodeTest.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/PathEndNodeTest.java index a42bdef04fe..c6dee81f547 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/PathEndNodeTest.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/PathEndNodeTest.java @@ -21,12 +21,13 @@ import java.util.Collection; import org.drools.base.base.ClassObjectType; +import org.drools.core.reteoo.RightInputAdapterNode; import org.drools.kiesession.rulebase.InternalKnowledgeBase; import org.drools.core.reteoo.BetaNode; import org.drools.core.reteoo.EntryPointNode; import org.drools.core.reteoo.LeftTupleSink; import org.drools.core.reteoo.ObjectTypeNode; -import org.drools.core.reteoo.RightInputAdapterNode; +import org.drools.core.reteoo.TupleToObjectNode; import org.drools.core.reteoo.RuleTerminalNode; import org.drools.base.rule.EntryPointId; import org.drools.testcoverage.common.util.KieBaseTestConfiguration; @@ -74,9 +75,9 @@ public void testSubNetworkSharing() throws Exception { EntryPointNode epn = kbase.getRete().getEntryPointNode( EntryPointId.DEFAULT ); ObjectTypeNode otn = epn.getObjectTypeNodes().get( new ClassObjectType( Long.class) ); - BetaNode beta1 = (BetaNode) otn.getObjectSinkPropagator().getSinks()[0]; - RightInputAdapterNode rian = (RightInputAdapterNode) beta1.getSinkPropagator().getSinks()[0]; - BetaNode beta2 = (BetaNode) rian.getObjectSinkPropagator().getSinks()[0]; + BetaNode beta1 = ((RightInputAdapterNode)otn.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + TupleToObjectNode rian = (TupleToObjectNode) beta1.getSinkPropagator().getSinks()[0]; + BetaNode beta2 = ((RightInputAdapterNode)rian.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); LeftTupleSink[] sinks = beta2.getSinkPropagator().getSinks(); RuleTerminalNode rtn1 = (RuleTerminalNode) sinks[0]; RuleTerminalNode rtn2 = (RuleTerminalNode) sinks[1]; diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/PropertySpecificTest.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/PropertySpecificTest.java index b2f09b3de22..dc35df236eb 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/PropertySpecificTest.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/PropertySpecificTest.java @@ -33,6 +33,7 @@ import org.drools.core.impl.InternalRuleBase; import org.drools.core.reteoo.AlphaNode; import org.drools.core.reteoo.BetaNode; +import org.drools.core.reteoo.RightInputAdapterNode; import org.drools.core.reteoo.LeftInputAdapterNode; import org.drools.core.reteoo.ObjectTypeNode; import org.drools.base.reteoo.PropertySpecificUtil; @@ -186,10 +187,10 @@ public void testBetaNodeNoConstraintsNoPropertySpecific() { ObjectTypeNode otn = getObjectTypeNode(kbase, "Cheese" ); assertThat(otn).isNotNull(); - BetaNode betaNode = ( BetaNode ) otn.getObjectSinkPropagator().getSinks()[0]; + BetaNode betaNode = ((RightInputAdapterNode)otn.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); - assertThat(betaNode.getRightDeclaredMask()).isEqualTo(AllSetBitMask.get()); - assertThat(betaNode.getRightInferredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNode.getRightInput().getDeclaredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNode.getRightInput().getInferredMask()).isEqualTo(AllSetBitMask.get()); } @Test @@ -217,10 +218,10 @@ public void testBetaNodeWithConstraintsNoPropertySpecific() { assertThat(alphaNode.getDeclaredMask()).isEqualTo(AllSetBitMask.get()); assertThat(alphaNode.getInferredMask()).isEqualTo(AllSetBitMask.get()); - BetaNode betaNode = ( BetaNode ) alphaNode.getObjectSinkPropagator().getSinks()[0]; + BetaNode betaNode = ((RightInputAdapterNode)alphaNode.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); - assertThat(betaNode.getRightDeclaredMask()).isEqualTo(AllSetBitMask.get()); - assertThat(betaNode.getRightInferredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNode.getRightInput().getDeclaredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNode.getRightInput().getInferredMask()).isEqualTo(AllSetBitMask.get()); } @Test @@ -242,10 +243,10 @@ public void testInitialFactBetaNodeWithRightInputAdapter() { LeftInputAdapterNode liaNode = ( LeftInputAdapterNode ) otn.getObjectSinkPropagator().getSinks()[0]; BetaNode betaNode = ( BetaNode ) liaNode.getSinkPropagator().getSinks()[1]; - assertThat(betaNode.getLeftDeclaredMask()).isEqualTo(AllSetBitMask.get()); - assertThat(betaNode.getLeftInferredMask()).isEqualTo(AllSetBitMask.get()); - assertThat(betaNode.getRightDeclaredMask()).isEqualTo(AllSetBitMask.get()); - assertThat(betaNode.getRightInferredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNode.getDeclaredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNode.getInferredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNode.getRightInput().getDeclaredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNode.getRightInput().getInferredMask()).isEqualTo(AllSetBitMask.get()); } @Test @@ -275,10 +276,10 @@ public void testPersonFactBetaNodeWithRightInputAdapter() { LeftInputAdapterNode liaNode = ( LeftInputAdapterNode ) otn.getObjectSinkPropagator().getSinks()[0]; BetaNode betaNode = ( BetaNode ) liaNode.getSinkPropagator().getSinks()[1]; - assertThat(betaNode.getLeftDeclaredMask()).isEqualTo(AllSetBitMask.get()); - assertThat(betaNode.getLeftInferredMask()).isEqualTo(AllSetBitMask.get()); - assertThat(betaNode.getRightDeclaredMask()).isEqualTo(AllSetBitMask.get()); - assertThat(betaNode.getRightInferredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNode.getDeclaredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNode.getInferredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNode.getRightInput().getDeclaredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNode.getRightInput().getInferredMask()).isEqualTo(AllSetBitMask.get()); } @Test @@ -318,10 +319,10 @@ public void testSharedAlphanodeWithBetaNodeConstraintsNoPropertySpecific() { assertThat(alphaNode1_1.getDeclaredMask()).isEqualTo(AllSetBitMask.get()); assertThat(alphaNode1_1.getInferredMask()).isEqualTo(AllSetBitMask.get()); - BetaNode betaNode1 = ( BetaNode ) alphaNode1_1.getObjectSinkPropagator().getSinks()[0]; + BetaNode betaNode1 = ((RightInputAdapterNode)alphaNode1_1.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); - assertThat(betaNode1.getRightDeclaredMask()).isEqualTo(AllSetBitMask.get()); - assertThat(betaNode1.getRightInferredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNode1.getRightInput().getDeclaredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNode1.getRightInput().getInferredMask()).isEqualTo(AllSetBitMask.get()); // second share @@ -329,10 +330,10 @@ public void testSharedAlphanodeWithBetaNodeConstraintsNoPropertySpecific() { assertThat(alphaNode1_2.getDeclaredMask()).isEqualTo(AllSetBitMask.get()); assertThat(alphaNode1_2.getInferredMask()).isEqualTo(AllSetBitMask.get()); - BetaNode betaNode2 = ( BetaNode ) alphaNode1_2.getObjectSinkPropagator().getSinks()[0]; + BetaNode betaNode2 = ((RightInputAdapterNode)alphaNode1_2.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); - assertThat(betaNode2.getRightDeclaredMask()).isEqualTo(AllSetBitMask.get()); - assertThat(betaNode2.getRightInferredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNode2.getRightInput().getDeclaredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNode2.getRightInput().getInferredMask()).isEqualTo(AllSetBitMask.get()); } @@ -609,12 +610,12 @@ public void testBetaNoConstraintsNoWatches() { ObjectTypeNode otn = getObjectTypeNode(kbase, "A" ); assertThat(otn).isNotNull(); - BetaNode betaNode = ( BetaNode ) otn.getObjectSinkPropagator().getSinks()[0]; - assertThat(betaNode.getRightDeclaredMask()).isEqualTo(EmptyBitMask.get()); - assertThat(betaNode.getRightInferredMask()).isEqualTo(EmptyBitMask.get()); + BetaNode betaNode = ((RightInputAdapterNode)otn.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + assertThat(betaNode.getRightInput().getDeclaredMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNode.getRightInput().getInferredMask()).isEqualTo(EmptyBitMask.get()); - assertThat(betaNode.getLeftDeclaredMask()).isEqualTo(EmptyBitMask.get()); - assertThat(betaNode.getLeftInferredMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNode.getDeclaredMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNode.getInferredMask()).isEqualTo(EmptyBitMask.get()); } @Test @@ -627,12 +628,12 @@ public void testBetaNoConstraintsWithWatches() { assertThat(otn).isNotNull(); List sp = getSettableProperties(wm, otn); - BetaNode betaNode = ( BetaNode ) otn.getObjectSinkPropagator().getSinks()[0]; - assertThat(betaNode.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a"), sp)); - assertThat(betaNode.getRightInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a"), sp)); + BetaNode betaNode = ((RightInputAdapterNode)otn.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + assertThat(betaNode.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a"), sp)); + assertThat(betaNode.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a"), sp)); - assertThat(betaNode.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a"), sp)); - assertThat(betaNode.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a"), sp)); + assertThat(betaNode.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a"), sp)); + assertThat(betaNode.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a"), sp)); } @Test @@ -650,17 +651,17 @@ public void testBetaWithConstraintsNoWatches() { assertThat(alphaNode.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a"), sp)); assertThat(alphaNode.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b"), sp)); - BetaNode betaNode = ( BetaNode ) alphaNode.getObjectSinkPropagator().getSinks()[0]; - assertThat(betaNode.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b"), sp)); // beta declares nothing - assertThat(betaNode.getRightInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b"), sp)); // beta infers from alpha + BetaNode betaNode = ((RightInputAdapterNode)alphaNode.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + assertThat(betaNode.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b"), sp)); // beta declares nothing + assertThat(betaNode.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b"), sp)); // beta infers from alpha otn = getObjectTypeNode(kbase, "B" ); alphaNode = ( AlphaNode ) otn.getObjectSinkPropagator().getSinks()[0]; assertThat(alphaNode.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a"), sp)); assertThat(alphaNode.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b"), sp)); - assertThat(betaNode.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b"), sp)); - assertThat(betaNode.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b"), sp)); + assertThat(betaNode.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b"), sp)); + assertThat(betaNode.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b"), sp)); } @Test @@ -678,19 +679,19 @@ public void testBetaWithConstraintsWithWatches() { assertThat(alphaNode.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a"), sp)); assertThat(alphaNode.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "s"), sp)); - BetaNode betaNode = ( BetaNode ) alphaNode.getObjectSinkPropagator().getSinks()[0]; - assertThat(betaNode.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "s"), sp)); - assertThat(betaNode.getRightInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "s"), sp)); - assertThat(betaNode.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); - assertThat(betaNode.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "c"), sp)); + BetaNode betaNode =((RightInputAdapterNode)alphaNode.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + assertThat(betaNode.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "s"), sp)); + assertThat(betaNode.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "s"), sp)); + assertThat(betaNode.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); + assertThat(betaNode.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "c"), sp)); otn = getObjectTypeNode(kbase, "B" ); alphaNode = ( AlphaNode ) otn.getObjectSinkPropagator().getSinks()[0]; assertThat(alphaNode.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a"), sp)); assertThat(alphaNode.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "c"), sp)); - assertThat(betaNode.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); - assertThat(betaNode.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "c"), sp)); + assertThat(betaNode.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); + assertThat(betaNode.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "c"), sp)); } @Test @@ -708,19 +709,19 @@ public void testBetaWithConstraintsWithNegativeWatches() { assertThat(alphaNode.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a"), sp)); assertThat(alphaNode.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "s"), sp)); - BetaNode betaNode = ( BetaNode ) alphaNode.getObjectSinkPropagator().getSinks()[0]; - assertThat(betaNode.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "s"), sp)); - assertThat(betaNode.getRightInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("s"), sp)); - assertThat(betaNode.getRightNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!a", "!b"), sp)); + BetaNode betaNode = ((RightInputAdapterNode)alphaNode.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + assertThat(betaNode.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "s"), sp)); + assertThat(betaNode.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("s"), sp)); + assertThat(betaNode.getRightInput().getNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!a", "!b"), sp)); otn = getObjectTypeNode(kbase, "B" ); alphaNode = ( AlphaNode ) otn.getObjectSinkPropagator().getSinks()[0]; assertThat(alphaNode.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a"), sp)); assertThat(alphaNode.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "c"), sp)); - assertThat(betaNode.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); - assertThat(betaNode.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); - assertThat(betaNode.getLeftNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!a"), sp)); + assertThat(betaNode.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); + assertThat(betaNode.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); + assertThat(betaNode.getNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!a"), sp)); } @Test @@ -744,26 +745,26 @@ public void testBetaSharedAlphaNoWatches() { assertThat(alphaNode1_1.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("s"), sp)); assertThat(alphaNode1_1.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "s", "b"), sp)); - BetaNode betaNode1 = ( BetaNode ) alphaNode1_1.getObjectSinkPropagator().getSinks()[0]; - assertThat(betaNode1.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b"), sp)); - assertThat(betaNode1.getRightInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "s", "b"), sp)); + BetaNode betaNode1 = ((RightInputAdapterNode)alphaNode1_1.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + assertThat(betaNode1.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b"), sp)); + assertThat(betaNode1.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "s", "b"), sp)); - assertThat(betaNode1.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); - assertThat(betaNode1.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); - assertThat(betaNode1.getLeftNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!a"), sp)); + assertThat(betaNode1.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); + assertThat(betaNode1.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); + assertThat(betaNode1.getNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!a"), sp)); // second share AlphaNode alphaNode1_2 = ( AlphaNode ) alphaNode1.getObjectSinkPropagator().getSinks()[1]; assertThat(alphaNode1_2.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("i"), sp)); assertThat(alphaNode1_2.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "i", "b"), sp)); - BetaNode betaNode2 = ( BetaNode ) alphaNode1_2.getObjectSinkPropagator().getSinks()[0]; - assertThat(betaNode2.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b"), sp)); - assertThat(betaNode2.getRightInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "i", "b"), sp)); + BetaNode betaNode2 = ((RightInputAdapterNode)alphaNode1_2.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + assertThat(betaNode2.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b"), sp)); + assertThat(betaNode2.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "i", "b"), sp)); - assertThat(betaNode2.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "j"), sp)); - assertThat(betaNode2.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "j"), sp)); - assertThat(betaNode2.getLeftNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!i"), sp)); + assertThat(betaNode2.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "j"), sp)); + assertThat(betaNode2.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "j"), sp)); + assertThat(betaNode2.getNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!i"), sp)); // test rule removal kbase.removeRule( "org.drools.mvel.integrationtests", "r0" ); @@ -773,12 +774,12 @@ public void testBetaSharedAlphaNoWatches() { assertThat(alphaNode1_2.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("i"), sp)); assertThat(alphaNode1_2.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "i", "b"), sp)); - assertThat(betaNode2.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b"), sp)); - assertThat(betaNode2.getRightInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "i", "b"), sp)); + assertThat(betaNode2.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b"), sp)); + assertThat(betaNode2.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "i", "b"), sp)); - assertThat(betaNode1.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); - assertThat(betaNode1.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); - assertThat(betaNode1.getLeftNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!a"), sp)); + assertThat(betaNode1.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); + assertThat(betaNode1.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); + assertThat(betaNode1.getNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!a"), sp)); // have to rebuild to remove r1 kbase = getKnowledgeBase(rule1, rule2); @@ -794,13 +795,13 @@ public void testBetaSharedAlphaNoWatches() { assertThat(alphaNode1_1.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("s"), sp)); assertThat(alphaNode1_1.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "s", "b"), sp)); - betaNode1 = ( BetaNode ) alphaNode1_1.getObjectSinkPropagator().getSinks()[0]; - assertThat(betaNode1.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b"), sp)); - assertThat(betaNode1.getRightInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "s", "b"), sp)); + betaNode1 = ((RightInputAdapterNode)alphaNode1_1.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + assertThat(betaNode1.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b"), sp)); + assertThat(betaNode1.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "s", "b"), sp)); - assertThat(betaNode2.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "j"), sp)); - assertThat(betaNode2.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "j"), sp)); - assertThat(betaNode2.getLeftNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!i"), sp)); + assertThat(betaNode2.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "j"), sp)); + assertThat(betaNode2.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "j"), sp)); + assertThat(betaNode2.getNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!i"), sp)); } @Test @@ -824,14 +825,14 @@ public void testBetaSharedAlphaWithWatches() { assertThat(alphaNode1_1.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b"), sp)); assertThat(alphaNode1_1.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "c"), sp)); - BetaNode betaNode1 = ( BetaNode ) alphaNode1_1.getObjectSinkPropagator().getSinks()[0]; - assertThat(betaNode1.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); - assertThat(betaNode1.getRightInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "c"), sp)); - assertThat(betaNode1.getRightNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!b"), sp)); + BetaNode betaNode1 = ((RightInputAdapterNode)alphaNode1_1.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + assertThat(betaNode1.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); + assertThat(betaNode1.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "c"), sp)); + assertThat(betaNode1.getRightInput().getNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!b"), sp)); - assertThat(betaNode1.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); - assertThat(betaNode1.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); - assertThat(betaNode1.getLeftNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!a"), sp)); + assertThat(betaNode1.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); + assertThat(betaNode1.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); + assertThat(betaNode1.getNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!a"), sp)); // second share AlphaNode alphaNode1_2 = ( AlphaNode ) alphaNode1.getObjectSinkPropagator().getSinks()[1]; @@ -839,15 +840,15 @@ public void testBetaSharedAlphaWithWatches() { assertThat(alphaNode1_2.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "i", "b", "s"), sp)); - BetaNode betaNode2 = ( BetaNode ) alphaNode1_2.getObjectSinkPropagator().getSinks()[0]; - assertThat(betaNode2.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "s"), sp)); - assertThat(betaNode2.getRightInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("i", "b", "s"), sp)); - assertThat(betaNode2.getRightNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!a"), sp)); + BetaNode betaNode2 = ((RightInputAdapterNode)alphaNode1_2.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + assertThat(betaNode2.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "s"), sp)); + assertThat(betaNode2.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("i", "b", "s"), sp)); + assertThat(betaNode2.getRightInput().getNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!a"), sp)); - assertThat(betaNode1.getLeftNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!a"), sp)); - assertThat(betaNode2.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "j"), sp)); - assertThat(betaNode2.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "j"), sp)); - assertThat(betaNode2.getLeftNegativeMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNode1.getNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!a"), sp)); + assertThat(betaNode2.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "j"), sp)); + assertThat(betaNode2.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "j"), sp)); + assertThat(betaNode2.getNegativeMask()).isEqualTo(EmptyBitMask.get()); // test rule removal kbase.removeRule( "org.drools.mvel.integrationtests", "r0" ); @@ -857,13 +858,13 @@ public void testBetaSharedAlphaWithWatches() { assertThat(alphaNode1_2.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("i"), sp)); assertThat(alphaNode1_2.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "i", "b", "s"), sp)); - assertThat(betaNode2.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "s"), sp)); - assertThat(betaNode2.getRightInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("i", "b", "s"), sp)); - assertThat(betaNode2.getRightNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!a"), sp)); + assertThat(betaNode2.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "s"), sp)); + assertThat(betaNode2.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("i", "b", "s"), sp)); + assertThat(betaNode2.getRightInput().getNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!a"), sp)); - assertThat(betaNode2.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "j"), sp)); - assertThat(betaNode2.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "j"), sp)); - assertThat(betaNode2.getLeftNegativeMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNode2.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "j"), sp)); + assertThat(betaNode2.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "j"), sp)); + assertThat(betaNode2.getNegativeMask()).isEqualTo(EmptyBitMask.get()); // have to rebuild to remove r1 kbase = getKnowledgeBase(rule1, rule2); @@ -879,14 +880,14 @@ public void testBetaSharedAlphaWithWatches() { assertThat(alphaNode1_1.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b"), sp)); assertThat(alphaNode1_1.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "c"), sp)); - betaNode1 = ( BetaNode ) alphaNode1_1.getObjectSinkPropagator().getSinks()[0]; - assertThat(betaNode1.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); - assertThat(betaNode1.getRightInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "c"), sp)); - assertThat(betaNode1.getRightNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!b"), sp)); + betaNode1 = ((RightInputAdapterNode)alphaNode1_1.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + assertThat(betaNode1.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); + assertThat(betaNode1.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "c"), sp)); + assertThat(betaNode1.getRightInput().getNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!b"), sp)); - assertThat(betaNode1.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); - assertThat(betaNode1.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); - assertThat(betaNode1.getLeftNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!a"), sp)); + assertThat(betaNode1.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); + assertThat(betaNode1.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "c"), sp)); + assertThat(betaNode1.getNegativeMask()).isEqualTo(calculateNegativeMask(otn.getObjectType(), list("!a"), sp)); } @Test @@ -911,12 +912,12 @@ public void testComplexBetaSharedAlphaWithWatches() { assertThat(alphaNode1_1.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b"), sp)); assertThat(alphaNode1_1.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "c"), sp)); - BetaNode betaNode1 = ( BetaNode ) alphaNode1_1.getObjectSinkPropagator().getSinks()[0]; - assertThat(betaNode1.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("c"), sp)); - assertThat(betaNode1.getRightInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "c"), sp)); + BetaNode betaNode1 = ((RightInputAdapterNode)alphaNode1_1.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + assertThat(betaNode1.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("c"), sp)); + assertThat(betaNode1.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "c"), sp)); - assertThat(betaNode1.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("i"), sp)); - assertThat(betaNode1.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "i"), sp)); + assertThat(betaNode1.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("i"), sp)); + assertThat(betaNode1.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "i"), sp)); // second share AlphaNode alphaNode1_2 = ( AlphaNode ) alphaNode1.getObjectSinkPropagator().getSinks()[1]; @@ -924,12 +925,12 @@ public void testComplexBetaSharedAlphaWithWatches() { assertThat(alphaNode1_2.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "i", "s", "j"), sp)); - BetaNode betaNode2 = ( BetaNode ) alphaNode1_2.getObjectSinkPropagator().getSinks()[1]; - assertThat(betaNode2.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("s"), sp)); - assertThat(betaNode2.getRightInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "i", "s"), sp)); + BetaNode betaNode2 = ((RightInputAdapterNode)alphaNode1_2.getObjectSinkPropagator().getSinks()[1]).getBetaNode(); + assertThat(betaNode2.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("s"), sp)); + assertThat(betaNode2.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "i", "s"), sp)); - assertThat(betaNode2.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("j"), sp)); - assertThat(betaNode2.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "j"), sp)); + assertThat(betaNode2.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("j"), sp)); + assertThat(betaNode2.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "j"), sp)); // third share AlphaNode alphaNode1_4 = ( AlphaNode ) alphaNode1_2.getObjectSinkPropagator().getSinks()[0]; @@ -937,12 +938,12 @@ public void testComplexBetaSharedAlphaWithWatches() { assertThat(alphaNode1_4.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "i", "j"), sp)); - BetaNode betaNode3 = ( BetaNode ) alphaNode1_4.getObjectSinkPropagator().getSinks()[0]; - assertThat(betaNode3.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("j"), sp)); - assertThat(betaNode3.getRightInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "i", "b", "j"), sp)); + BetaNode betaNode3 = ((RightInputAdapterNode)alphaNode1_4.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + assertThat(betaNode3.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("j"), sp)); + assertThat(betaNode3.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "i", "b", "j"), sp)); - assertThat(betaNode3.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("k"), sp)); - assertThat(betaNode3.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("c", "k"), sp)); + assertThat(betaNode3.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("k"), sp)); + assertThat(betaNode3.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("c", "k"), sp)); } @Test @@ -969,24 +970,24 @@ public void testComplexBetaSharedAlphaWithWatchesRemoveR1() { assertThat(alphaNode1_1.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("i"), sp)); assertThat(alphaNode1_1.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "i", "b", "s", "j"), sp)); - BetaNode betaNode1 = ( BetaNode ) alphaNode1_1.getObjectSinkPropagator().getSinks()[1]; - assertThat(betaNode1.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("s"), sp)); - assertThat(betaNode1.getRightInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "i", "s"), sp)); + BetaNode betaNode1 = ((RightInputAdapterNode)alphaNode1_1.getObjectSinkPropagator().getSinks()[1]).getBetaNode(); + assertThat(betaNode1.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("s"), sp)); + assertThat(betaNode1.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "i", "s"), sp)); - assertThat(betaNode1.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("j"), sp)); - assertThat(betaNode1.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "j"), sp)); + assertThat(betaNode1.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("j"), sp)); + assertThat(betaNode1.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "j"), sp)); // second split, third alpha AlphaNode alphaNode1_2 = ( AlphaNode ) alphaNode1_1.getObjectSinkPropagator().getSinks()[0]; assertThat(alphaNode1_2.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b"), sp)); assertThat(alphaNode1_2.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "i", "j"), sp)); - BetaNode betaNode3 = ( BetaNode ) alphaNode1_2.getObjectSinkPropagator().getSinks()[0]; - assertThat(betaNode3.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("j"), sp)); - assertThat(betaNode3.getRightInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "i", "b", "j"), sp)); + BetaNode betaNode3 = ((RightInputAdapterNode)alphaNode1_2.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + assertThat(betaNode3.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("j"), sp)); + assertThat(betaNode3.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "i", "b", "j"), sp)); - assertThat(betaNode3.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("k"), sp)); - assertThat(betaNode3.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("c", "k"), sp)); + assertThat(betaNode3.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("k"), sp)); + assertThat(betaNode3.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("c", "k"), sp)); } @Test @@ -1013,12 +1014,12 @@ public void testComplexBetaSharedAlphaWithWatchesRemoveR2() { assertThat(alphaNode1_1.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b"), sp)); assertThat(alphaNode1_1.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "c"), sp)); - BetaNode betaNode1 = ( BetaNode ) alphaNode1_1.getObjectSinkPropagator().getSinks()[0]; - assertThat(betaNode1.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("c"), sp)); - assertThat(betaNode1.getRightInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "c"), sp)); + BetaNode betaNode1 = ((RightInputAdapterNode)alphaNode1_1.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + assertThat(betaNode1.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("c"), sp)); + assertThat(betaNode1.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "c"), sp)); - assertThat(betaNode1.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("i"), sp)); - assertThat(betaNode1.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "i"), sp)); + assertThat(betaNode1.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("i"), sp)); + assertThat(betaNode1.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "i"), sp)); // fist share, second alpha AlphaNode alphaNode1_2 = ( AlphaNode ) alphaNode1.getObjectSinkPropagator().getSinks()[1]; @@ -1030,12 +1031,12 @@ public void testComplexBetaSharedAlphaWithWatchesRemoveR2() { assertThat(alphaNode1_3.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "i", "b", "j"), sp)); - BetaNode betaNode2 = ( BetaNode ) alphaNode1_3.getObjectSinkPropagator().getSinks()[0]; - assertThat(betaNode2.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("j"), sp)); - assertThat(betaNode2.getRightInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "i", "b", "j"), sp)); + BetaNode betaNode2 = ((RightInputAdapterNode)alphaNode1_3.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + assertThat(betaNode2.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("j"), sp)); + assertThat(betaNode2.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "i", "b", "j"), sp)); - assertThat(betaNode2.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("k"), sp)); - assertThat(betaNode2.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("c", "k"), sp)); + assertThat(betaNode2.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("k"), sp)); + assertThat(betaNode2.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("c", "k"), sp)); } @@ -1064,12 +1065,12 @@ public void testComplexBetaSharedAlphaWithWatchesRemoveR3() { assertThat(alphaNode1_1.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "c"), sp)); // first split - BetaNode betaNode1 = ( BetaNode ) alphaNode1_1.getObjectSinkPropagator().getSinks()[0]; - assertThat(betaNode1.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("c"), sp)); - assertThat(betaNode1.getRightInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "c"), sp)); + BetaNode betaNode1 = ((RightInputAdapterNode)alphaNode1_1.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + assertThat(betaNode1.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("c"), sp)); + assertThat(betaNode1.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "c"), sp)); - assertThat(betaNode1.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("i"), sp)); - assertThat(betaNode1.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "i"), sp)); + assertThat(betaNode1.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("i"), sp)); + assertThat(betaNode1.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "i"), sp)); // second split AlphaNode alphaNode1_2 = ( AlphaNode ) alphaNode1.getObjectSinkPropagator().getSinks()[1]; @@ -1077,12 +1078,12 @@ public void testComplexBetaSharedAlphaWithWatchesRemoveR3() { assertThat(alphaNode1_2.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "i", "s"), sp)); - BetaNode betaNode2 = ( BetaNode ) alphaNode1_2.getObjectSinkPropagator().getSinks()[0]; - assertThat(betaNode2.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("s"), sp)); - assertThat(betaNode2.getRightInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "i", "s"), sp)); + BetaNode betaNode2 = ((RightInputAdapterNode)alphaNode1_2.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + assertThat(betaNode2.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("s"), sp)); + assertThat(betaNode2.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "i", "s"), sp)); - assertThat(betaNode2.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("j"), sp)); - assertThat(betaNode2.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "j"), sp)); + assertThat(betaNode2.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("j"), sp)); + assertThat(betaNode2.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b", "j"), sp)); } @Test @@ -2065,17 +2066,17 @@ public void testBetaWithWatchAfterBeta() { ObjectTypeNode otnC = getObjectTypeNode(kbase, "C" ); List sp = getSettableProperties(wm, otnA); - BetaNode betaNodeA = ( BetaNode ) otnA.getObjectSinkPropagator().getSinks()[0]; - assertThat(betaNodeA.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otnA.getObjectType(), list("i", "b", "c"), sp)); - assertThat(betaNodeA.getRightInferredMask()).isEqualTo(calculatePositiveMask(otnA.getObjectType(), list("i", "b", "c"), sp)); - assertThat(betaNodeA.getLeftDeclaredMask()).isEqualTo(AllSetBitMask.get()); - assertThat(betaNodeA.getLeftInferredMask()).isEqualTo(AllSetBitMask.get()); - - BetaNode betaNodeC = ( BetaNode ) otnC.getObjectSinkPropagator().getSinks()[0]; - assertThat(betaNodeC.getRightDeclaredMask()).isEqualTo(EmptyBitMask.get()); - assertThat(betaNodeC.getRightInferredMask()).isEqualTo(EmptyBitMask.get()); - assertThat(betaNodeC.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otnC.getObjectType(), list("j", "k"), sp)); - assertThat(betaNodeC.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otnC.getObjectType(), list("a", "j", "k"), sp)); + BetaNode betaNodeA = ((RightInputAdapterNode)otnA.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + assertThat(betaNodeA.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otnA.getObjectType(), list("i", "b", "c"), sp)); + assertThat(betaNodeA.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otnA.getObjectType(), list("i", "b", "c"), sp)); + assertThat(betaNodeA.getDeclaredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNodeA.getInferredMask()).isEqualTo(AllSetBitMask.get()); + + BetaNode betaNodeC = ((RightInputAdapterNode)otnC.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + assertThat(betaNodeC.getRightInput().getDeclaredMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNodeC.getRightInput().getInferredMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNodeC.getDeclaredMask()).isEqualTo(calculatePositiveMask(otnC.getObjectType(), list("j", "k"), sp)); + assertThat(betaNodeC.getInferredMask()).isEqualTo(calculatePositiveMask(otnC.getObjectType(), list("a", "j", "k"), sp)); } @Test @@ -2088,17 +2089,17 @@ public void testBetaAfterBetaWithWatch() { ObjectTypeNode otnC = getObjectTypeNode(kbase, "C" ); List sp = getSettableProperties(wm, otnA); - BetaNode betaNodeA = ( BetaNode ) otnA.getObjectSinkPropagator().getSinks()[0]; - assertThat(betaNodeA.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otnA.getObjectType(), list("i", "b", "c"), sp)); - assertThat(betaNodeA.getRightInferredMask()).isEqualTo(calculatePositiveMask(otnA.getObjectType(), list("i", "b", "c"), sp)); - assertThat(betaNodeA.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otnA.getObjectType(), list("j", "k"), sp)); - assertThat(betaNodeA.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otnA.getObjectType(), list("a", "j", "k"), sp)); - - BetaNode betaNodeC = ( BetaNode ) otnC.getObjectSinkPropagator().getSinks()[0]; - assertThat(betaNodeC.getRightDeclaredMask()).isEqualTo(EmptyBitMask.get()); - assertThat(betaNodeC.getRightInferredMask()).isEqualTo(EmptyBitMask.get()); - assertThat(betaNodeC.getLeftDeclaredMask()).isEqualTo(AllSetBitMask.get()); - assertThat(betaNodeC.getLeftInferredMask()).isEqualTo(AllSetBitMask.get()); + BetaNode betaNodeA = ((RightInputAdapterNode)otnA.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + assertThat(betaNodeA.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otnA.getObjectType(), list("i", "b", "c"), sp)); + assertThat(betaNodeA.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otnA.getObjectType(), list("i", "b", "c"), sp)); + assertThat(betaNodeA.getDeclaredMask()).isEqualTo(calculatePositiveMask(otnA.getObjectType(), list("j", "k"), sp)); + assertThat(betaNodeA.getInferredMask()).isEqualTo(calculatePositiveMask(otnA.getObjectType(), list("a", "j", "k"), sp)); + + BetaNode betaNodeC = ((RightInputAdapterNode)otnC.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + assertThat(betaNodeC.getRightInput().getDeclaredMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNodeC.getRightInput().getInferredMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNodeC.getDeclaredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNodeC.getInferredMask()).isEqualTo(AllSetBitMask.get()); } @Test @@ -2116,23 +2117,23 @@ public void test2DifferentAlphaWatchBeforeSameBeta() { assertThat(alphaNode.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b", "c"), sp)); ObjectTypeNode otnC = getObjectTypeNode(kbase, "C" ); - BetaNode betaNodeC1 = ( BetaNode ) otnC.getObjectSinkPropagator().getSinks()[0]; - BetaNode betaNodeC2 = ( BetaNode ) otnC.getObjectSinkPropagator().getSinks()[1]; + BetaNode betaNodeC1 = ((RightInputAdapterNode)otnC.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + BetaNode betaNodeC2 = ((RightInputAdapterNode)otnC.getObjectSinkPropagator().getSinks()[1]).getBetaNode(); LeftInputAdapterNode lia1 = (LeftInputAdapterNode)alphaNode.getObjectSinkPropagator().getSinks()[0]; assertThat(lia1.getSinkPropagator().getSinks()[0]).isSameAs(betaNodeC1); LeftInputAdapterNode lia2 = (LeftInputAdapterNode)alphaNode.getObjectSinkPropagator().getSinks()[1]; assertThat(lia2.getSinkPropagator().getSinks()[0]).isSameAs(betaNodeC2); - assertThat(betaNodeC1.getRightDeclaredMask()).isEqualTo(EmptyBitMask.get()); - assertThat(betaNodeC1.getRightInferredMask()).isEqualTo(EmptyBitMask.get()); - assertThat(betaNodeC1.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b"), sp)); - assertThat(betaNodeC1.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b"), sp)); + assertThat(betaNodeC1.getRightInput().getDeclaredMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNodeC1.getRightInput().getInferredMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNodeC1.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("b"), sp)); + assertThat(betaNodeC1.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "b"), sp)); - assertThat(betaNodeC2.getRightDeclaredMask()).isEqualTo(EmptyBitMask.get()); - assertThat(betaNodeC2.getRightInferredMask()).isEqualTo(EmptyBitMask.get()); - assertThat(betaNodeC2.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("c"), sp)); - assertThat(betaNodeC2.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "c"), sp)); + assertThat(betaNodeC2.getRightInput().getDeclaredMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNodeC2.getRightInput().getInferredMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNodeC2.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("c"), sp)); + assertThat(betaNodeC2.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "c"), sp)); kbase.removeRule( "org.drools.mvel.integrationtests", "r0" ); assertThat(alphaNode.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a"), sp)); @@ -2141,10 +2142,10 @@ public void test2DifferentAlphaWatchBeforeSameBeta() { assertThat(lia2.getSinkPropagator().getSinks().length).isEqualTo(1); BetaNode betaNodeC = ( BetaNode ) lia2.getSinkPropagator().getSinks()[0]; - assertThat(betaNodeC2.getRightDeclaredMask()).isEqualTo(EmptyBitMask.get()); - assertThat(betaNodeC2.getRightInferredMask()).isEqualTo(EmptyBitMask.get()); - assertThat(betaNodeC2.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("c"), sp)); - assertThat(betaNodeC2.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "c"), sp)); + assertThat(betaNodeC2.getRightInput().getDeclaredMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNodeC2.getRightInput().getInferredMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNodeC2.getDeclaredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("c"), sp)); + assertThat(betaNodeC2.getInferredMask()).isEqualTo(calculatePositiveMask(otn.getObjectType(), list("a", "c"), sp)); } @Test @@ -2158,28 +2159,28 @@ public void testSameBetasWith2RTNSinks() { ObjectTypeNode otnC = getObjectTypeNode(kbase, "C"); List sp = getSettableProperties(wm, otnA); - BetaNode betaNodeC = ( BetaNode ) otnC.getObjectSinkPropagator().getSinks()[0]; - BetaNode betaNodeA1 = ( BetaNode ) otnA.getObjectSinkPropagator().getSinks()[0]; - BetaNode betaNodeA2 = ( BetaNode ) otnA.getObjectSinkPropagator().getSinks()[1]; + BetaNode betaNodeC = ((RightInputAdapterNode)otnC.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + BetaNode betaNodeA1 = ((RightInputAdapterNode)otnA.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + BetaNode betaNodeA2 = ((RightInputAdapterNode)otnA.getObjectSinkPropagator().getSinks()[1]).getBetaNode(); assertThat(betaNodeA1).isSameAs(betaNodeC.getSinkPropagator().getSinks()[0]); assertThat(betaNodeA2).isSameAs(betaNodeC.getSinkPropagator().getSinks()[1]); assertThat(betaNodeC).isSameAs(betaNodeA1.getLeftTupleSource()); assertThat(betaNodeC).isSameAs(betaNodeA2.getLeftTupleSource()); - assertThat(betaNodeC.getRightDeclaredMask()).isEqualTo(EmptyBitMask.get()); - assertThat(betaNodeC.getRightInferredMask()).isEqualTo(EmptyBitMask.get()); - assertThat(betaNodeC.getLeftDeclaredMask()).isEqualTo(EmptyBitMask.get()); - assertThat(betaNodeC.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otnA.getObjectType(), list("a"), sp)); + assertThat(betaNodeC.getRightInput().getDeclaredMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNodeC.getRightInput().getInferredMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNodeC.getDeclaredMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNodeC.getInferredMask()).isEqualTo(calculatePositiveMask(otnA.getObjectType(), list("a"), sp)); - assertThat(betaNodeA1.getRightDeclaredMask()).isEqualTo(EmptyBitMask.get()); - assertThat(betaNodeA1.getRightInferredMask()).isEqualTo(EmptyBitMask.get()); - assertThat(betaNodeA1.getLeftDeclaredMask()).isEqualTo(AllSetBitMask.get()); - assertThat(betaNodeA1.getLeftInferredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNodeA1.getRightInput().getDeclaredMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNodeA1.getRightInput().getInferredMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNodeA1.getDeclaredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNodeA1.getInferredMask()).isEqualTo(AllSetBitMask.get()); - assertThat(betaNodeA2.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otnC.getObjectType(), list("b", "c"), sp)); - assertThat(betaNodeA2.getRightInferredMask()).isEqualTo(calculatePositiveMask(otnC.getObjectType(), list("b", "c"), sp)); - assertThat(betaNodeA2.getLeftDeclaredMask()).isEqualTo(AllSetBitMask.get()); - assertThat(betaNodeA2.getLeftInferredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNodeA2.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otnC.getObjectType(), list("b", "c"), sp)); + assertThat(betaNodeA2.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otnC.getObjectType(), list("b", "c"), sp)); + assertThat(betaNodeA2.getDeclaredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNodeA2.getInferredMask()).isEqualTo(AllSetBitMask.get()); kbase.removeRule( "org.drools.mvel.integrationtests", "r0" ); assertThat(betaNodeC.getSinkPropagator().getSinks().length).isEqualTo(1); @@ -2200,34 +2201,34 @@ public void testBetaWith2BetaSinks() { assertThat(alphaNode.getInferredMask()).isEqualTo(calculatePositiveMask(otnB.getObjectType(), list("a", "b", "c"), sp)); ObjectTypeNode otnA = getObjectTypeNode(kbase, "A" ); - BetaNode betaNodeA1 = ( BetaNode ) otnA.getObjectSinkPropagator().getSinks()[0]; - BetaNode betaNodeA2 = ( BetaNode ) otnA.getObjectSinkPropagator().getSinks()[1]; + BetaNode betaNodeA1 = ((RightInputAdapterNode)otnA.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); + BetaNode betaNodeA2 = ((RightInputAdapterNode)otnA.getObjectSinkPropagator().getSinks()[1]).getBetaNode(); - assertThat(betaNodeA1.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otnB.getObjectType(), list("i"), sp)); - assertThat(betaNodeA1.getRightInferredMask()).isEqualTo(calculatePositiveMask(otnB.getObjectType(), list("i"), sp)); - assertThat(betaNodeA1.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otnB.getObjectType(), list("b"), sp)); - assertThat(betaNodeA1.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otnB.getObjectType(), list("a", "b"), sp)); + assertThat(betaNodeA1.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otnB.getObjectType(), list("i"), sp)); + assertThat(betaNodeA1.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otnB.getObjectType(), list("i"), sp)); + assertThat(betaNodeA1.getDeclaredMask()).isEqualTo(calculatePositiveMask(otnB.getObjectType(), list("b"), sp)); + assertThat(betaNodeA1.getInferredMask()).isEqualTo(calculatePositiveMask(otnB.getObjectType(), list("a", "b"), sp)); - assertThat(betaNodeA2.getRightDeclaredMask()).isEqualTo(calculatePositiveMask(otnB.getObjectType(), list("j"), sp)); - assertThat(betaNodeA2.getRightInferredMask()).isEqualTo(calculatePositiveMask(otnB.getObjectType(), list("j"), sp)); - assertThat(betaNodeA2.getLeftDeclaredMask()).isEqualTo(calculatePositiveMask(otnB.getObjectType(), list("c"), sp)); - assertThat(betaNodeA2.getLeftInferredMask()).isEqualTo(calculatePositiveMask(otnB.getObjectType(), list("a", "c"), sp)); + assertThat(betaNodeA2.getRightInput().getDeclaredMask()).isEqualTo(calculatePositiveMask(otnB.getObjectType(), list("j"), sp)); + assertThat(betaNodeA2.getRightInput().getInferredMask()).isEqualTo(calculatePositiveMask(otnB.getObjectType(), list("j"), sp)); + assertThat(betaNodeA2.getDeclaredMask()).isEqualTo(calculatePositiveMask(otnB.getObjectType(), list("c"), sp)); + assertThat(betaNodeA2.getInferredMask()).isEqualTo(calculatePositiveMask(otnB.getObjectType(), list("a", "c"), sp)); ObjectTypeNode otnC = getObjectTypeNode(kbase, "C" ); - BetaNode betaNodeC = ( BetaNode ) otnC.getObjectSinkPropagator().getSinks()[0]; + BetaNode betaNodeC = ((RightInputAdapterNode)otnC.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); - assertThat(betaNodeC.getRightDeclaredMask()).isEqualTo(EmptyBitMask.get()); - assertThat(betaNodeC.getRightInferredMask()).isEqualTo(EmptyBitMask.get()); - assertThat(betaNodeC.getLeftDeclaredMask()).isEqualTo(AllSetBitMask.get()); - assertThat(betaNodeC.getLeftInferredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNodeC.getRightInput().getDeclaredMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNodeC.getRightInput().getInferredMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNodeC.getDeclaredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNodeC.getInferredMask()).isEqualTo(AllSetBitMask.get()); ObjectTypeNode otnD = getObjectTypeNode(kbase, "D" ); - BetaNode betaNodeD = ( BetaNode ) otnC.getObjectSinkPropagator().getSinks()[0]; + BetaNode betaNodeD = ((RightInputAdapterNode)otnC.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); - assertThat(betaNodeD.getRightDeclaredMask()).isEqualTo(EmptyBitMask.get()); - assertThat(betaNodeD.getRightInferredMask()).isEqualTo(EmptyBitMask.get()); - assertThat(betaNodeD.getLeftDeclaredMask()).isEqualTo(AllSetBitMask.get()); - assertThat(betaNodeD.getLeftInferredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNodeD.getRightInput().getDeclaredMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNodeD.getRightInput().getInferredMask()).isEqualTo(EmptyBitMask.get()); + assertThat(betaNodeD.getDeclaredMask()).isEqualTo(AllSetBitMask.get()); + assertThat(betaNodeD.getInferredMask()).isEqualTo(AllSetBitMask.get()); kbase.removeRule( "org.drools.mvel.integrationtests", "r1" ); assertThat(alphaNode.getDeclaredMask()).isEqualTo(calculatePositiveMask(otnB.getObjectType(), list("a"), sp)); @@ -2584,7 +2585,7 @@ public static class LongFact { private Long longDiff; public LongFact( int i) { - this.longVal = new Long(i); + this.longVal = Long.valueOf(i); } public Long getLongDiff() { diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/SegmentCreationTest.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/SegmentCreationTest.java index 0e88c104d1f..09f35e3bec0 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/SegmentCreationTest.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/SegmentCreationTest.java @@ -30,13 +30,14 @@ import org.drools.core.reteoo.ConditionalBranchNode; import org.drools.base.reteoo.InitialFactImpl; import org.drools.core.reteoo.JoinNode; +import org.drools.core.reteoo.JoinRightAdapterNode; import org.drools.core.reteoo.LeftInputAdapterNode; import org.drools.core.reteoo.LeftInputAdapterNode.LiaNodeMemory; import org.drools.core.reteoo.LeftTupleSource; import org.drools.core.reteoo.NotNode; import org.drools.core.reteoo.ObjectTypeNode; import org.drools.core.reteoo.PathMemory; -import org.drools.core.reteoo.RightInputAdapterNode; +import org.drools.core.reteoo.TupleToObjectNode; import org.drools.core.reteoo.RuleTerminalNode; import org.drools.core.reteoo.SegmentMemory; import org.drools.testcoverage.common.util.KieBaseTestConfiguration; @@ -188,7 +189,7 @@ public void testMultiSharedPattern() throws Exception { LeftInputAdapterNode lian = (LeftInputAdapterNode) dotn.getObjectSinkPropagator().getSinks()[0]; - JoinNode beta = (JoinNode) aotn.getObjectSinkPropagator().getSinks()[0]; + JoinNode beta = ((JoinRightAdapterNode) aotn.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); RuleTerminalNode rtn1 = ( RuleTerminalNode) beta.getSinkPropagator().getSinks()[0]; JoinNode bNode = ( JoinNode ) beta.getSinkPropagator().getSinks()[1]; RuleTerminalNode rtn2 = ( RuleTerminalNode) bNode.getSinkPropagator().getSinks()[0]; @@ -245,8 +246,8 @@ public void testSubnetworkNoSharing() throws Exception { LeftInputAdapterNode liaNode = (LeftInputAdapterNode) aotn.getObjectSinkPropagator().getSinks()[0]; JoinNode bNode = ( JoinNode ) liaNode.getSinkPropagator().getSinks()[0]; - JoinNode cNode = ( JoinNode ) bNode.getSinkPropagator().getSinks()[0]; - RightInputAdapterNode riaNode = ( RightInputAdapterNode ) cNode.getSinkPropagator().getSinks()[0]; + JoinNode cNode = ( JoinNode ) bNode.getSinkPropagator().getSinks()[0]; + TupleToObjectNode riaNode = (TupleToObjectNode) cNode.getSinkPropagator().getSinks()[0]; NotNode notNode = ( NotNode ) liaNode.getSinkPropagator().getSinks()[1]; RuleTerminalNode rtn1 = ( RuleTerminalNode) notNode.getSinkPropagator().getSinks()[0]; @@ -271,7 +272,7 @@ public void testSubnetworkNoSharing() throws Exception { BetaMemory bm = (BetaMemory) wm.getNodeMemory(notNode); assertThat(smem.getNext()).isEqualTo(bm.getSegmentMemory()); - assertThat(bm.getRiaRuleMemory().getSegmentMemory()).isEqualTo(bSmem); // check subnetwork ref was made + assertThat(bm.getSubnetworkPathMemory().getSegmentMemory()).isEqualTo(bSmem); // check subnetwork ref was made } @@ -287,12 +288,12 @@ public void tesSubnetworkAfterShare() throws Exception { LeftInputAdapterNode lian = (LeftInputAdapterNode) dotn.getObjectSinkPropagator().getSinks()[0]; - JoinNode joinNode = (JoinNode) aotn.getObjectSinkPropagator().getSinks()[0]; + JoinNode joinNode = ((JoinRightAdapterNode) aotn.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); RuleTerminalNode rtn1 = ( RuleTerminalNode) joinNode.getSinkPropagator().getSinks()[0]; JoinNode bNode = ( JoinNode ) joinNode.getSinkPropagator().getSinks()[1]; - JoinNode cNode = ( JoinNode ) bNode.getSinkPropagator().getSinks()[0]; - RightInputAdapterNode riaNode = ( RightInputAdapterNode ) cNode.getSinkPropagator().getSinks()[0]; + JoinNode cNode = ( JoinNode ) bNode.getSinkPropagator().getSinks()[0]; + TupleToObjectNode riaNode = (TupleToObjectNode) cNode.getSinkPropagator().getSinks()[0]; NotNode notNode = ( NotNode ) joinNode.getSinkPropagator().getSinks()[2]; RuleTerminalNode rtn2 = ( RuleTerminalNode) notNode.getSinkPropagator().getSinks()[0]; @@ -337,13 +338,13 @@ public void tesShareInSubnetwork() throws Exception { LeftInputAdapterNode lian = (LeftInputAdapterNode) dotn.getObjectSinkPropagator().getSinks()[0]; - JoinNode beta = (JoinNode) aotn.getObjectSinkPropagator().getSinks()[0]; + JoinNode beta = ((JoinRightAdapterNode) aotn.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); RuleTerminalNode rtn1 = ( RuleTerminalNode) beta.getSinkPropagator().getSinks()[0]; JoinNode bNode = ( JoinNode ) beta.getSinkPropagator().getSinks()[1]; JoinNode cNode = ( JoinNode ) bNode.getSinkPropagator().getSinks()[0]; - RuleTerminalNode rtn2 = ( RuleTerminalNode ) cNode.getSinkPropagator().getSinks()[0]; - RightInputAdapterNode riaNode = ( RightInputAdapterNode ) cNode.getSinkPropagator().getSinks()[1]; + RuleTerminalNode rtn2 = ( RuleTerminalNode ) cNode.getSinkPropagator().getSinks()[0]; + TupleToObjectNode riaNode = (TupleToObjectNode) cNode.getSinkPropagator().getSinks()[1]; NotNode notNode = ( NotNode ) beta.getSinkPropagator().getSinks()[2]; RuleTerminalNode rtn3 = ( RuleTerminalNode) notNode.getSinkPropagator().getSinks()[0]; @@ -448,7 +449,7 @@ public void testBranchCEMultipleSegments() throws Exception { ObjectTypeNode aotn = getObjectTypeNode(kbase, LinkingTest.A.class ); - LeftTupleSource liaNode = (LeftTupleSource) aotn.getObjectSinkPropagator().getSinks()[0]; + LeftTupleSource liaNode = ((JoinRightAdapterNode) aotn.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); ConditionalBranchNode cen1Node = ( ConditionalBranchNode ) liaNode.getSinkPropagator().getSinks()[1]; JoinNode bNode = ( JoinNode ) cen1Node.getSinkPropagator().getSinks()[0]; diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/phreak/AddRuleTest.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/phreak/AddRuleTest.java index e0b5bf652b8..80b3040611e 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/phreak/AddRuleTest.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/phreak/AddRuleTest.java @@ -39,9 +39,11 @@ import org.drools.core.phreak.PhreakBuilder; import org.drools.core.reteoo.BetaMemory; import org.drools.core.reteoo.BetaNode; +import org.drools.core.reteoo.RightInputAdapterNode; import org.drools.core.reteoo.EvalConditionNode; import org.drools.core.reteoo.ExistsNode; import org.drools.core.reteoo.JoinNode; +import org.drools.core.reteoo.JoinRightAdapterNode; import org.drools.core.reteoo.LeftInputAdapterNode; import org.drools.core.reteoo.LeftInputAdapterNode.LiaNodeMemory; import org.drools.core.reteoo.LeftTupleNode; @@ -99,7 +101,7 @@ public void testAddThenSplitProtoAllJoins() { ObjectTypeNode cotn = getObjectTypeNode(kbase1.getRete(), C.class); LeftInputAdapterNode lian = (LeftInputAdapterNode) aotn.getSinks()[0]; - BetaNode cbeta = (BetaNode) cotn.getSinks()[0]; + BetaNode cbeta = ((RightInputAdapterNode)cotn.getSinks()[0]).getBetaNode(); insertAndFlush(wm); @@ -152,7 +154,7 @@ public void testAddThenSplitProtoWithNot() { ObjectTypeNode cotn = getObjectTypeNode(kbase1.getRete(), C.class); LeftInputAdapterNode lian = (LeftInputAdapterNode) aotn.getSinks()[0]; - BetaNode cbeta = (BetaNode) cotn.getSinks()[0]; + BetaNode cbeta = ((RightInputAdapterNode)cotn.getSinks()[0]).getBetaNode(); insertAndFlush(wm); @@ -188,9 +190,9 @@ public void testAddWithSplitThenCreateThirdSplit() { ObjectTypeNode xotn = getObjectTypeNode(kbase1.getRete(), X.class); LeftInputAdapterNode lian = (LeftInputAdapterNode) aotn.getSinks()[0]; - BetaNode ebeta = (BetaNode) eotn.getSinks()[0].getSinks()[0]; - BetaNode ebeta3 = (BetaNode) eotn.getSinks()[2].getSinks()[0]; - BetaNode xbeta = (BetaNode) xotn.getSinks()[0]; + BetaNode ebeta = ((RightInputAdapterNode)eotn.getSinks()[0].getSinks()[0]).getBetaNode(); + BetaNode ebeta3 = ((RightInputAdapterNode)eotn.getSinks()[2].getSinks()[0]).getBetaNode(); + BetaNode xbeta = ((RightInputAdapterNode)xotn.getSinks()[0]).getBetaNode(); insertAndFlush(wm); @@ -246,10 +248,10 @@ public void testAddWithSplitThenCreateThirdSplitInSamePos() { ObjectTypeNode yotn = getObjectTypeNode(kbase1.getRete(), Y.class); LeftInputAdapterNode lian = (LeftInputAdapterNode) aotn.getSinks()[0]; - BetaNode ebeta = (BetaNode) eotn.getSinks()[0].getSinks()[0]; - BetaNode cbeta = (BetaNode) cotn.getSinks()[0]; - BetaNode ebeta3 = (BetaNode) eotn.getSinks()[2].getSinks()[0]; - BetaNode xbeta = (BetaNode) xotn.getSinks()[0]; + BetaNode ebeta = ((RightInputAdapterNode)eotn.getSinks()[0].getSinks()[0]).getBetaNode(); + BetaNode cbeta = ((RightInputAdapterNode)cotn.getSinks()[0]).getBetaNode(); + BetaNode ebeta3 = ((RightInputAdapterNode)eotn.getSinks()[2].getSinks()[0]).getBetaNode(); + BetaNode xbeta = ((RightInputAdapterNode)xotn.getSinks()[0]).getBetaNode(); insertAndFlush(wm); wm.fireAllRules(); @@ -268,7 +270,7 @@ public void testAddWithSplitThenCreateThirdSplitInSamePos() { // now add a rule at the given split, so we can check paths were all updated correctly addRuleAtGivenSplit(kbase1, wm, cbeta, yotn); - BetaNode jbeta = (BetaNode) yotn.getSinks()[1]; + BetaNode jbeta = ((RightInputAdapterNode)yotn.getSinks()[1]).getBetaNode(); assertThat(((ClassObjectType)jbeta.getObjectTypeNode().getObjectType()).getClassType()).isSameAs(Y.class); assertThat(jbeta.getLeftTupleSource()).isSameAs(cbeta); @@ -295,7 +297,7 @@ private static void addRuleAtGivenSplit(InternalKnowledgeBase kbase1, InternalWo RuleTerminalNode rtn = new RuleTerminalNode(buildContext.getNextNodeId(), joinNode, rule, new GroupElement(), 0, buildContext); rtn.setPathEndNodes(new PathEndNode[]{rtn}); rtn.doAttach(buildContext); - Arrays.stream(rtn.getPathNodes()).forEach( n -> {n.addAssociatedTerminal(rtn); ((BaseNode)n).addAssociation(rule);}); + Arrays.stream(rtn.getPathNodes()).forEach( n -> {n.addAssociatedTerminal(rtn); ((BaseNode)n).addAssociation(rule, null);}); new EagerPhreakBuilder().addRule(rtn, Collections.singletonList(wm), kbase1); } @@ -313,8 +315,8 @@ public void testAddWithSplitAndEvalThenCreateThirdSplit() { ObjectTypeNode eotn = getObjectTypeNode(kbase1.getRete(), E.class); LeftInputAdapterNode lian = (LeftInputAdapterNode) aotn.getSinks()[0]; - BetaNode cbeta = (BetaNode) cotn.getSinks()[0]; - BetaNode ebeta3 = (BetaNode) eotn.getSinks()[0].getSinks()[0]; + BetaNode cbeta = ((RightInputAdapterNode)cotn.getSinks()[0]).getBetaNode(); + BetaNode ebeta3 = ((RightInputAdapterNode)eotn.getSinks()[0].getSinks()[0]).getBetaNode(); EvalConditionNode evnode = (EvalConditionNode) cbeta.getSinks()[0]; insertAndFlush(wm); @@ -356,7 +358,7 @@ public void testChildProtosPosAndEndNodeSegmentsUpdated() { ObjectTypeNode botn = getObjectTypeNode(kbase1.getRete(), B.class); LeftInputAdapterNode lian = (LeftInputAdapterNode) aotn.getSinks()[0]; - BetaNode bbeta = (BetaNode) botn.getSinks()[0]; + BetaNode bbeta = ((RightInputAdapterNode)botn.getSinks()[0]).getBetaNode(); insertAndFlush(wm); @@ -396,7 +398,7 @@ public void testDataStructuresWithSubnetwork() { SegmentPrototype smemProto0 = kbase1.getSegmentPrototype(lian); PathEndNode endNode0 = smemProto0.getPathEndNodes()[0]; - assertThat(endNode0.getType()).isEqualTo(NodeTypeEnums.RightInputAdapterNode); + assertThat(endNode0.getType()).isEqualTo(NodeTypeEnums.TupleToObjectNode); assertThat(endNode0.getPathMemSpec().allLinkedTestMask()).isEqualTo(2); assertThat(endNode0.getPathMemSpec().smemCount()).isEqualTo(2); @@ -415,8 +417,8 @@ public void testFindNewBrancheRootsSimple() { ObjectTypeNode cotn = getObjectTypeNode(kbase1.getRete(), C.class); ObjectTypeNode xotn = getObjectTypeNode(kbase1.getRete(), X.class); - BetaNode cBeta = (BetaNode) cotn.getSinks()[0]; - BetaNode xBeta = (BetaNode) xotn.getSinks()[0]; + BetaNode cBeta = ((RightInputAdapterNode)cotn.getSinks()[0]).getBetaNode(); + BetaNode xBeta = ((RightInputAdapterNode)xotn.getSinks()[0]).getBetaNode(); TerminalNode[] tns = kbase1.getReteooBuilder().getTerminalNodes("org.kie.r0"); assertThat(tns.length).isEqualTo(1); @@ -442,9 +444,9 @@ public void testNewBrancheRootsWithSubnetwork() { ObjectTypeNode xotn = getObjectTypeNode(kbase1.getRete(), X.class); ObjectTypeNode botn = getObjectTypeNode(kbase1.getRete(), B.class); - BetaNode fBeta = (BetaNode) fotn.getSinks()[0]; - BetaNode xBeta = (BetaNode) xotn.getSinks()[0]; - ExistsNode exists = (ExistsNode) ((LeftTupleNode)botn.getSinks()[1].getSinks()[0]).getLeftTupleSource(); + BetaNode fBeta = ((RightInputAdapterNode)fotn.getSinks()[0]).getBetaNode(); + BetaNode xBeta = ((RightInputAdapterNode)xotn.getSinks()[0]).getBetaNode(); + ExistsNode exists = (ExistsNode) ((RightInputAdapterNode)botn.getSinks()[1].getSinks()[0]).getBetaNode().getLeftTupleSource(); TerminalNode[] tns = kbase1.getReteooBuilder().getTerminalNodes("org.kie.r0"); assertThat(tns.length).isEqualTo(1); @@ -830,7 +832,7 @@ public void testPopulatedSharedToRtn() throws Exception { kbase1.addPackages( buildKnowledgePackage("r2", " A() B() C() X() E()\n") ); ObjectTypeNode eotn = getObjectTypeNode(kbase1, E.class ); - JoinNode eNode = (JoinNode) eotn.getObjectSinkPropagator().getSinks()[0]; + JoinNode eNode = ((JoinRightAdapterNode)eotn.getObjectSinkPropagator().getSinks()[0]).getBetaNode(); RuleTerminalNode rtn = ( RuleTerminalNode ) eNode.getSinkPropagator().getLastLeftTupleSink(); PathMemory pm = wm.getNodeMemory(rtn); diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/phreak/BetaNodeBuilder.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/phreak/BetaNodeBuilder.java index bb5a51a6658..c090e958152 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/phreak/BetaNodeBuilder.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/phreak/BetaNodeBuilder.java @@ -18,6 +18,7 @@ */ package org.drools.mvel.integrationtests.phreak; +import org.drools.core.reteoo.JoinRightAdapterNode; import org.drools.core.reteoo.LeftTupleSource; import org.drools.mvel.accessors.ClassFieldAccessorStore; import org.drools.base.base.ClassObjectType; @@ -135,11 +136,14 @@ public BetaNode build(LeftTupleSource leftInput, ObjectSource rightInput) { switch (nodeType) { case NodeTypeEnums.JoinNode: - return new JoinNode(buildContext.getNextNodeId(), leftInput, rightInput, betaConstraints, buildContext); + return new JoinNode(buildContext.getNextNodeId(), leftInput, + new JoinRightAdapterNode(buildContext.getNextNodeId(), rightInput, buildContext), betaConstraints, buildContext); case NodeTypeEnums.NotNode: - return new NotNode(buildContext.getNextNodeId(), leftInput, rightInput, betaConstraints, buildContext); + return new NotNode(buildContext.getNextNodeId(), leftInput, + new JoinRightAdapterNode(buildContext.getNextNodeId(), rightInput, buildContext), betaConstraints, buildContext); case NodeTypeEnums.ExistsNode: - return new ExistsNode(buildContext.getNextNodeId(), leftInput, rightInput, betaConstraints, buildContext); + return new ExistsNode(buildContext.getNextNodeId(), leftInput, + new JoinRightAdapterNode(buildContext.getNextNodeId(), rightInput, buildContext), betaConstraints, buildContext); } throw new IllegalStateException("Unable to build Node"); } diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/phreak/RightBuilder.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/phreak/RightBuilder.java index 98267e1419d..24df9037179 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/phreak/RightBuilder.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/phreak/RightBuilder.java @@ -28,15 +28,15 @@ import org.drools.core.reteoo.TupleImpl; public class RightBuilder { - private InternalWorkingMemory wm; - private RightTupleSink sink; - private TupleSets rightTuples; - private Scenario scenario; + private InternalWorkingMemory wm; + private RightTupleSink sink; + private TupleSets rightTuples; + private Scenario scenario; public RightBuilder(Scenario scenario) { this.wm = scenario.getWorkingMemory(); this.scenario = scenario; - this.sink = scenario.getBetaNode(); + this.sink = scenario.getBetaNode().getRightInput(); this.rightTuples = scenario.getRightTuples(); } diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/phreak/RightMemory.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/phreak/RightMemory.java index 088c3218112..28c1fae6ed1 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/phreak/RightMemory.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/phreak/RightMemory.java @@ -53,7 +53,7 @@ public List getRightTuples(Object... objects) { List rightTuples = new ArrayList<>(); for ( Object object : objects ) { InternalFactHandle fh = (InternalFactHandle) wm.insert( object ); - TupleImpl expectedRightTuple = new RightTuple(fh, node ); //node.createLeftTuple( fh, node, true ); + TupleImpl expectedRightTuple = new RightTuple(fh, node.getRightInput() ); //node.createLeftTuple( fh, node, true ); expectedRightTuple.setPropagationContext( new PhreakPropagationContext() ); rightTuples.add( expectedRightTuple ); } diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/util/RightTupleIndexHashTableTest.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/util/RightTupleIndexHashTableTest.java index c059a168989..1885446a8ea 100644 --- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/util/RightTupleIndexHashTableTest.java +++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/util/RightTupleIndexHashTableTest.java @@ -20,11 +20,14 @@ import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import org.drools.base.rule.accessor.RightTupleValueExtractor; import org.drools.core.base.ClassFieldAccessorCache; +import org.drools.core.impl.KnowledgeBaseImpl; import org.drools.core.reteoo.MockLeftTupleSink; +import org.drools.core.reteoo.builder.BuildContext; import org.drools.core.util.index.IndexSpec; import org.drools.mvel.accessors.ClassFieldAccessorStore; import org.drools.base.base.ClassObjectType; @@ -63,6 +66,9 @@ public AbstractHashTable.Index getIndexSupplier(IndexedValueReader fieldIndex) { @Test public void testSingleEntry() throws Exception { + BuildContext bctx = new BuildContext(new KnowledgeBaseImpl("01"), Collections.emptyList()); + MockLeftTupleSink sink = new MockLeftTupleSink(0, bctx); + final ReadAccessor extractor = store.getReader( Cheese.class, "type" ); @@ -84,7 +90,7 @@ public void testSingleEntry() throws Exception { assertThat(map.size()).isEqualTo(0); assertThat(map.getFirst(new LeftTuple( cheddarHandle1, - new MockLeftTupleSink(0), + sink, true ))).isNull(); final Cheese stilton1 = new Cheese( "stilton", @@ -104,14 +110,17 @@ public void testSingleEntry() throws Exception { stilton2 ); final Tuple tuple = map.getFirst( new LeftTuple( stiltonHandle2, - new MockLeftTupleSink(0), - true ) ); + sink, + true ) ); assertThat(tuple.getFactHandle()).isSameAs(stiltonRighTuple.getFactHandle()); assertThat(tuple.getNext()).isNull(); } @Test public void testTwoDifferentEntries() throws Exception { + BuildContext bctx = new BuildContext(new KnowledgeBaseImpl("01"), Collections.emptyList()); + MockLeftTupleSink sink = new MockLeftTupleSink(0, bctx); + final ReadAccessor extractor = store.getReader( Cheese.class, "type" ); @@ -150,8 +159,8 @@ public void testTwoDifferentEntries() throws Exception { final InternalFactHandle stiltonHandle2 = new DefaultFactHandle( 2, stilton2 ); Tuple tuple = map.getFirst( new LeftTuple( stiltonHandle2, - new MockLeftTupleSink(0), - true ) ); + sink, + true ) ); assertThat(tuple.getFactHandle()).isSameAs(stiltonHandle1); assertThat(tuple.getNext()).isNull(); @@ -160,8 +169,8 @@ public void testTwoDifferentEntries() throws Exception { final InternalFactHandle cheddarHandle2 = new DefaultFactHandle( 2, cheddar2 ); tuple = map.getFirst( new LeftTuple( cheddarHandle2, - new MockLeftTupleSink(0), - true ) ); + sink, + true ) ); assertThat(tuple.getFactHandle()).isSameAs(cheddarHandle1); assertThat(tuple.getNext()).isNull(); } @@ -214,8 +223,11 @@ public void testTwoEqualEntries() throws Exception { final InternalFactHandle stiltonHandle3 = new DefaultFactHandle( 4, stilton2 ); + BuildContext bctx = new BuildContext(new KnowledgeBaseImpl("01"), Collections.emptyList()); + MockLeftTupleSink sink = new MockLeftTupleSink(0, bctx); + final TupleImpl tuple = map.getFirst( new LeftTuple( stiltonHandle3, - new MockLeftTupleSink(0), + sink, true ) ); assertThat(tuple.getFactHandle()).isSameAs(stiltonHandle1); assertThat(tuple.getNext().getFactHandle()).isSameAs(stiltonHandle2); @@ -574,7 +586,9 @@ public void testEmptyIterator() { final InternalFactHandle stiltonHandle = new DefaultFactHandle( 2, stilton ); - assertThat(map.getFirst(new LeftTuple(stiltonHandle, new MockLeftTupleSink(0), true ))).isNull(); + BuildContext bctx = new BuildContext(new KnowledgeBaseImpl("01"), Collections.emptyList()); + MockLeftTupleSink sink = new MockLeftTupleSink(0, bctx); + assertThat(map.getFirst(new LeftTuple(stiltonHandle, sink, true ))).isNull(); } }