diff --git a/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java b/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java index 1740620596c..9559adc71c7 100644 --- a/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java +++ b/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java @@ -37,12 +37,15 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Properties; +import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; @@ -11639,7 +11642,7 @@ public void testDeterministicOTNOrdering() throws Exception { ksession.fireAllRules(); } - @Test + @Test(timeout = 10000) public void testRemoveBigRule() throws Exception { // JBRULES-3496 String str = @@ -11796,4 +11799,77 @@ public void testAlphaHashingWithConstants() { ksession.insert(new Person("Mario", 38)); assertEquals(3, ksession.fireAllRules()); } + + @Test + public void testMemoriesCCEWhenAddRemoveAddRule() { + // JBRULES-3656 + String rule1 = + "import org.drools.integrationtests.MiscTest.*\n" + + "import java.util.Date\n" + + "rule \"RTR - 28717 retract\"\n" + + "when\n" + + " $listMembership0 : SimpleMembership( $listMembershipPatientSpaceIdRoot : patientSpaceId,\n" + + " ( listId != null && listId == \"28717\" ) ) and not ($patient0 : SimplePatient( $patientSpaceIdRoot : spaceId, spaceId != null &&\n" + + " spaceId == $listMembershipPatientSpaceIdRoot ) and\n" + + " (($ruleTime0 : RuleTime( $ruleTimeStartOfDay4_1 : startOfDay, $ruleTimeTime4_1 : time ) and $patient1 :\n" + + " SimplePatient( spaceId != null && spaceId == $patientSpaceIdRoot, birthDate != null && (birthDate after[0s,1d] $ruleTimeStartOfDay4_1) ) ) ) )\n" + + "then\n" + + "end"; + + String rule2 = + "import org.drools.integrationtests.MiscTest.*\n" + + "import java.util.Date\n" + + "rule \"RTR - 28717 retract\"\n" + + "when $listMembership0 : SimpleMembership( $listMembershipPatientSpaceIdRoot : patientSpaceId, ( listId != null && listId == \"28717\" ) )\n" + + " and not ($patient0 : SimplePatient( $patientSpaceIdRoot : spaceId, spaceId != null && spaceId == $listMembershipPatientSpaceIdRoot )\n" + + " and ( ($ruleTime0 : RuleTime( $ruleTimeStartOfDay4_1 : startOfDay, $ruleTimeTime4_1 : time )\n" + + " and $patient1 : SimplePatient( spaceId != null && spaceId == $patientSpaceIdRoot, birthDate != null && (birthDate not after[0s,1d] $ruleTimeStartOfDay4_1) ) ) ) )\n" + + "then\n" + + "end"; + + KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); + kbuilder.add( ResourceFactory.newByteArrayResource(rule1.getBytes()), ResourceType.DRL ); + + KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); + StatefulKnowledgeSession knowledgeSession = kbase.newStatefulKnowledgeSession(); + + Collection knowledgePackages = kbuilder.getKnowledgePackages(); + kbase.addKnowledgePackages( knowledgePackages ); + + for (KnowledgePackage kPackage : knowledgePackages) { + kbase.removeKnowledgePackage(kPackage.getName()); + } + + kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); + kbuilder.add( ResourceFactory.newByteArrayResource(rule2.getBytes()), ResourceType.DRL ); + kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() ); + } + + public static class RuleTime { + public Date getTime() { + return new Date(); + } + public Date getStartOfDay(){ + return new Date(); + } + } + public static class SimpleMembership { + public String getListId() { + return ""; + } + public String getPatientSpaceId() { + return ""; + } + } + public class SimplePatient { + public String getSpaceId() { + return ""; + } + public String getFactHandleString() { + return ""; + } + public Date getBirthDate() { + return new Date(); + } + } } \ No newline at end of file diff --git a/drools-core/src/main/java/org/drools/common/BaseNode.java b/drools-core/src/main/java/org/drools/common/BaseNode.java index 17df5d4ff52..031f0c257a7 100644 --- a/drools-core/src/main/java/org/drools/common/BaseNode.java +++ b/drools-core/src/main/java/org/drools/common/BaseNode.java @@ -106,7 +106,8 @@ public void remove(RuleRemovalContext context, BaseNode node, InternalWorkingMemory[] workingMemories) { - if (!context.addRemovedNode(this) && !(this instanceof LeftTupleSource)) { + if (!context.addRemovedNode(this) && !(this instanceof LeftTupleSource) ) { + node.internalCleanUp(builder, workingMemories); return; } @@ -120,6 +121,19 @@ public void remove(RuleRemovalContext context, } } + private void internalCleanUp(ReteooBuilder builder, InternalWorkingMemory[] workingMemories) { + if ( !this.isInUse() && this instanceof NodeMemory ) { + if (this instanceof NodeMemory) { + for( InternalWorkingMemory workingMemory : workingMemories ) { + workingMemory.clearNodeMemory( (NodeMemory) this ); + } + } + if ( !(this instanceof EntryPointNode) ) { + builder.getIdGenerator().releaseId( this.getId() ); + } + } + } + /** * Removes the node from teh network. Usually from the parent ObjectSource or TupleSource * @param builder diff --git a/drools-core/src/main/java/org/drools/reteoo/NodeSet.java b/drools-core/src/main/java/org/drools/reteoo/NodeSet.java index 57844bb6436..bdff192e994 100644 --- a/drools-core/src/main/java/org/drools/reteoo/NodeSet.java +++ b/drools-core/src/main/java/org/drools/reteoo/NodeSet.java @@ -18,7 +18,7 @@ public List getNodes() { public boolean add(BaseNode node) { if (nodeIds.add(node.getId())) { - getNodes().add(node); + nodes.add(node); return true; } return false;