[jboss-svn-commits] JBL Code SVN: r32382 - in labs/jbossrules/trunk: drools-core/src/main/java/org/drools/base and 2 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Sat Apr 3 22:33:40 EDT 2010
Author: mark.proctor at jboss.com
Date: 2010-04-03 22:33:39 -0400 (Sat, 03 Apr 2010)
New Revision: 32382
Modified:
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/TruthMaintenanceTest.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/DefaultKnowledgeHelper.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/SequentialKnowledgeHelper.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultAgenda.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/TruthMaintenanceSystem.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/KnowledgeHelper.java
Log:
JBRULES-1804 Logical dependencies accumulate on recursion
-Before the first logical insertion we make a copy of the current LogicalDependencies.
-For each logical insertion we check the copied list and if it exists we remove it and just add it back onto the current activation.
-After the rule has fired we cancel any remaining LogicalDependencies.
Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/TruthMaintenanceTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/TruthMaintenanceTest.java 2010-04-03 20:21:47 UTC (rev 32381)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/TruthMaintenanceTest.java 2010-04-04 02:33:39 UTC (rev 32382)
@@ -787,7 +787,7 @@
assertEquals( 0, IteratorToList.convert( workingMemory.iterateObjects() ).size() );
}
- public void FIXME_testLogicalInsertionsModifySameRuleGivesDifferentLogicalInsertion() throws Exception {
+ public void testLogicalInsertionsModifySameRuleGivesDifferentLogicalInsertion() throws Exception {
// TODO JBRULES-1804
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/DefaultKnowledgeHelper.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/DefaultKnowledgeHelper.java 2010-04-03 20:21:47 UTC (rev 32381)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/DefaultKnowledgeHelper.java 2010-04-04 02:33:39 UTC (rev 32382)
@@ -40,6 +40,8 @@
import org.drools.WorkingMemory;
import org.drools.common.InternalFactHandle;
import org.drools.common.InternalWorkingMemoryEntryPoint;
+import org.drools.common.LogicalDependency;
+import org.drools.core.util.LinkedList;
import org.drools.spi.Activation;
import org.drools.spi.KnowledgeHelper;
import org.drools.spi.Tuple;
@@ -49,16 +51,18 @@
KnowledgeHelper,
Externalizable {
- private static final long serialVersionUID = 400L;
+ private static final long serialVersionUID = 400L;
- private Rule rule;
- private GroupElement subrule;
- private Activation activation;
- private Tuple tuple;
- private InternalWorkingMemoryActions workingMemory;
+ private Rule rule;
+ private GroupElement subrule;
+ private Activation activation;
+ private Tuple tuple;
+ private InternalWorkingMemoryActions workingMemory;
- private IdentityHashMap<Object,FactHandle> identityMap;
+ private IdentityHashMap<Object, FactHandle> identityMap;
+ private LinkedList previousJustified;
+
public DefaultKnowledgeHelper() {
}
@@ -66,7 +70,7 @@
public DefaultKnowledgeHelper(final WorkingMemory workingMemory) {
this.workingMemory = (InternalWorkingMemoryActions) workingMemory;
- this.identityMap = new IdentityHashMap<Object,FactHandle>();
+ this.identityMap = new IdentityHashMap<Object, FactHandle>();
}
@@ -77,7 +81,7 @@
activation = (Activation) in.readObject();
tuple = (Tuple) in.readObject();
workingMemory = (InternalWorkingMemoryActions) in.readObject();
- identityMap = (IdentityHashMap<Object,FactHandle> ) in.readObject();
+ identityMap = (IdentityHashMap<Object, FactHandle>) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
@@ -86,7 +90,7 @@
out.writeObject( activation );
out.writeObject( tuple );
out.writeObject( workingMemory );
- out.writeObject( identityMap );
+ out.writeObject( identityMap );
}
public void setActivation(final Activation agendaItem) {
@@ -111,12 +115,13 @@
public void insert(final Object object,
final boolean dynamic) throws FactException {
- FactHandle handle = this.workingMemory.insert( object,
- dynamic,
- false,
- this.rule,
- this.activation );
- this.getIdentityMap().put(object, handle);
+ FactHandle handle = this.workingMemory.insert( object,
+ dynamic,
+ false,
+ this.rule,
+ this.activation );
+ this.getIdentityMap().put( object,
+ handle );
}
public void insertLogical(final Object object) throws FactException {
@@ -126,42 +131,76 @@
public void insertLogical(final Object object,
final boolean dynamic) throws FactException {
- FactHandle handle = this.workingMemory.insert( object,
- dynamic,
- true,
- this.rule,
- this.activation );
- this.getIdentityMap().put(object, handle);
+ if ( this.previousJustified == null ) {
+ this.previousJustified = this.activation.getLogicalDependencies();
+ this.activation.setLogicalDependencies( null );
+ }
+
+ // iterate to find previous equal logical insertion
+ LogicalDependency dep = null;
+ if ( this.previousJustified != null ) {
+ for ( dep = (LogicalDependency) this.previousJustified.getFirst(); dep != null; dep = (LogicalDependency) dep.getNext() ) {
+ if ( object.equals( ((InternalFactHandle) dep.getFactHandle()).getObject() ) ) {
+ this.previousJustified.remove( dep );
+ break;
+ }
+ }
+
+
+ }
+
+ if ( dep != null ) {
+ // Add the previous matching logical dependency back into the list
+ this.activation.addLogicalDependency( dep );
+ } else {
+ // no previous matching logical dependency, so create a new one
+ FactHandle handle = this.workingMemory.insert( object,
+ dynamic,
+ true,
+ this.rule,
+ this.activation );
+
+ this.getIdentityMap().put( object,
+ handle );
+ }
}
+
+ public void cancelRemainingPreviousLogicalDependencies() {
+ if ( this.previousJustified != null ) {
+ for ( LogicalDependency dep = (LogicalDependency) this.previousJustified.getFirst(); dep != null; dep = (LogicalDependency) dep.getNext() ) {
+ this.workingMemory.getTruthMaintenanceSystem().removeLogicalDependency( activation, dep, activation.getPropagationContext() );
+ }
+ }
+ }
public void update(final FactHandle handle,
final Object newObject) throws FactException {
// only update if this fact exists in the wm
- ((InternalWorkingMemoryEntryPoint)((InternalFactHandle)handle).getEntryPoint())
- .update( handle,
- newObject,
- this.rule,
- this.activation );
- this.getIdentityMap().put(newObject, handle);
+ ((InternalWorkingMemoryEntryPoint) ((InternalFactHandle) handle).getEntryPoint()).update( handle,
+ newObject,
+ this.rule,
+ this.activation );
+ this.getIdentityMap().put( newObject,
+ handle );
}
public void update(final Object object) throws FactException {
FactHandle handle = getFactHandle( object );
- if( handle == null ) {
+ if ( handle == null ) {
throw new FactException( "Update error: handle not found for object: " + object + ". Is it in the working memory?" );
}
- update( handle, object );
+ update( handle,
+ object );
}
public void retract(final FactHandle handle) throws FactException {
- ((InternalWorkingMemoryEntryPoint)((InternalFactHandle)handle).getEntryPoint())
- .retract( handle,
- true,
- true,
- this.rule,
- this.activation );
- this.getIdentityMap().remove(((InternalFactHandle)handle).getObject());
+ ((InternalWorkingMemoryEntryPoint) ((InternalFactHandle) handle).getEntryPoint()).retract( handle,
+ true,
+ true,
+ this.rule,
+ this.activation );
+ this.getIdentityMap().remove( ((InternalFactHandle) handle).getObject() );
}
public void retract(final Object object) throws FactException {
@@ -197,20 +236,21 @@
}
public Object get(final Declaration declaration) {
- InternalWorkingMemoryEntryPoint wmTmp = ((InternalWorkingMemoryEntryPoint)(this.tuple.get(declaration)).getEntryPoint());
-
- if(wmTmp != null){
- Object object = declaration.getValue( wmTmp.getInternalWorkingMemory() ,
- this.tuple.get( declaration ).getObject() );
+ InternalWorkingMemoryEntryPoint wmTmp = ((InternalWorkingMemoryEntryPoint) (this.tuple.get( declaration )).getEntryPoint());
- getIdentityMap().put(object, wmTmp.getFactHandleByIdentity(object));
- return object;
+ if ( wmTmp != null ) {
+ Object object = declaration.getValue( wmTmp.getInternalWorkingMemory(),
+ this.tuple.get( declaration ).getObject() );
+
+ getIdentityMap().put( object,
+ wmTmp.getFactHandleByIdentity( object ) );
+ return object;
}
return null;
}
public Declaration getDeclaration(final String identifier) {
- return (Declaration) this.subrule.getOuterDeclarations().get( identifier );
+ return (Declaration) this.subrule.getOuterDeclarations().get( identifier );
}
public void halt() {
@@ -238,7 +278,7 @@
*/
public IdentityHashMap<Object, FactHandle> getIdentityMap() {
return identityMap;
-}
+ }
/**
* @param identityMap the identityMap to set
@@ -248,14 +288,15 @@
}
private FactHandle getFactHandle(final Object object) {
- FactHandle handle = identityMap.get(object);
+ FactHandle handle = identityMap.get( object );
// entry point null means it is a generated fact, not a regular inserted fact
// NOTE: it would probably be a good idea to create a specific attribute for that
- if ( handle == null || ((InternalFactHandle)handle).getEntryPoint() == null ) {
- for( WorkingMemoryEntryPoint ep : workingMemory.getEntryPoints().values() ) {
+ if ( handle == null || ((InternalFactHandle) handle).getEntryPoint() == null ) {
+ for ( WorkingMemoryEntryPoint ep : workingMemory.getEntryPoints().values() ) {
handle = (FactHandle) ep.getFactHandle( object );
- if( handle != null ) {
- identityMap.put( object, handle );
+ if ( handle != null ) {
+ identityMap.put( object,
+ handle );
break;
}
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/SequentialKnowledgeHelper.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/SequentialKnowledgeHelper.java 2010-04-03 20:21:47 UTC (rev 32381)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/SequentialKnowledgeHelper.java 2010-04-04 02:33:39 UTC (rev 32382)
@@ -215,4 +215,9 @@
public void setIdentityMap(IdentityHashMap<Object, FactHandle> identityMap) {
this.identityMap = identityMap;
}
+
+ public void cancelRemainingPreviousLogicalDependencies() {
+ // TODO Auto-generated method stub
+
+ }
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultAgenda.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultAgenda.java 2010-04-03 20:21:47 UTC (rev 32381)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultAgenda.java 2010-04-04 02:33:39 UTC (rev 32382)
@@ -902,6 +902,7 @@
this.knowledgeHelper.setActivation( activation );
activation.getRule().getConsequence().evaluate( this.knowledgeHelper,
this.workingMemory );
+ this.knowledgeHelper.cancelRemainingPreviousLogicalDependencies();
this.knowledgeHelper.reset();
} catch ( final Exception e ) {
if ( this.legacyConsequenceExceptionHandler != null ) {
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/TruthMaintenanceSystem.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/TruthMaintenanceSystem.java 2010-04-03 20:21:47 UTC (rev 32381)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/TruthMaintenanceSystem.java 2010-04-04 02:33:39 UTC (rev 32382)
@@ -175,21 +175,28 @@
if ( list == null || list.isEmpty() ) {
return;
}
+
for ( LogicalDependency node = (LogicalDependency) list.getFirst(); node != null; node = (LogicalDependency) node.getNext() ) {
- final InternalFactHandle handle = (InternalFactHandle) node.getFactHandle();
- final Set set = (Set) this.justifiedMap.get( handle.getId() );
- if ( set != null ) {
- set.remove( node );
- WorkingMemoryAction action = new LogicalRetractCallback( this,
- node,
- set,
- handle,
- context,
- activation );
- workingMemory.queueWorkingMemoryAction( action );
- }
+ removeLogicalDependency( activation, node, context );
}
}
+
+ public void removeLogicalDependency(final Activation activation,
+ final LogicalDependency node,
+ final PropagationContext context) {
+ final InternalFactHandle handle = (InternalFactHandle) node.getFactHandle();
+ final Set set = (Set) this.justifiedMap.get( handle.getId() );
+ if ( set != null ) {
+ set.remove( node );
+ WorkingMemoryAction action = new LogicalRetractCallback( this,
+ node,
+ set,
+ handle,
+ context,
+ activation );
+ workingMemory.queueWorkingMemoryAction( action );
+ }
+ }
public static class LogicalRetractCallback
implements
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/KnowledgeHelper.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/KnowledgeHelper.java 2010-04-03 20:21:47 UTC (rev 32381)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/KnowledgeHelper.java 2010-04-04 02:33:39 UTC (rev 32382)
@@ -83,6 +83,8 @@
public void insertLogical(Object object,
boolean dynamic) throws FactException;
+ public void cancelRemainingPreviousLogicalDependencies();
+
void update(FactHandle handle,
Object newObject) throws FactException;
More information about the jboss-svn-commits
mailing list