[jboss-svn-commits] JBL Code SVN: r10987 - in labs/jbossrules/trunk/drools-core/src/main/java/org/drools: reteoo and 2 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Sun Apr 15 21:25:42 EDT 2007
Author: mark.proctor at jboss.com
Date: 2007-04-15 21:25:42 -0400 (Sun, 15 Apr 2007)
New Revision: 10987
Modified:
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaGroupImpl.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaItem.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/PropagationContextImpl.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/ScheduledAgendaItem.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/TruthMaintenanceSystem.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Rule.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/Activation.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/AgendaGroup.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/PropagationContext.java
Log:
JBRULES-797 Modified object causes logical assertion to retract even though its still true
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaGroupImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaGroupImpl.java 2007-04-16 00:00:15 UTC (rev 10986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaGroupImpl.java 2007-04-16 01:25:42 UTC (rev 10987)
@@ -84,7 +84,7 @@
return (Activation) this.queue.dequeue();
}
- public boolean isActivate() {
+ public boolean isActive() {
return this.active;
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaItem.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaItem.java 2007-04-16 00:00:15 UTC (rev 10986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AgendaItem.java 2007-04-16 01:25:42 UTC (rev 10987)
@@ -147,6 +147,10 @@
public LinkedList getLogicalDependencies() {
return this.justified;
}
+
+ public void setLogicalDependencies(LinkedList justified) {
+ this.justified = justified;
+ }
public boolean isActivated() {
return this.activated;
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/PropagationContextImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/PropagationContextImpl.java 2007-04-16 00:00:15 UTC (rev 10986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/PropagationContextImpl.java 2007-04-16 01:25:42 UTC (rev 10987)
@@ -106,28 +106,30 @@
}
public void addRetractedTuple(final Rule rule,
- final ReteTuple tuple) {
+ final Activation activation) {
if ( this.retracted == null ) {
this.retracted = new ObjectHashMap();
}
+
+ ReteTuple tuple = ( ReteTuple) activation.getTuple();
- TupleHashTable tuples = (TupleHashTable) this.retracted.get( rule );
+ ObjectHashMap tuples = (ObjectHashMap) this.retracted.get( rule );
if ( tuples == null ) {
- tuples = new TupleHashTable();
+ tuples = new ObjectHashMap();
this.retracted.put( rule,
tuples );
}
- tuples.add( tuple );
+ tuples.put( tuple, activation );
}
- public ReteTuple removeRetractedTuple(final Rule rule,
+ public Activation removeRetractedTuple(final Rule rule,
final ReteTuple tuple) {
if ( this.retracted == null ) {
return null;
}
- final TupleHashTable tuples = (TupleHashTable) this.retracted.get( rule );
- return tuples.remove( tuple );
+ final ObjectHashMap tuples = (ObjectHashMap) this.retracted.get( rule );
+ return ( Activation ) tuples.remove( tuple );
}
public void clearRetractedTuples() {
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/ScheduledAgendaItem.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/ScheduledAgendaItem.java 2007-04-16 00:00:15 UTC (rev 10986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/ScheduledAgendaItem.java 2007-04-16 01:25:42 UTC (rev 10987)
@@ -230,4 +230,8 @@
public GroupElement getSubRule() {
return this.subrule;
}
+
+ public void setLogicalDependencies(LinkedList justified) {
+ this.justified = justified;
+ }
}
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 2007-04-16 00:00:15 UTC (rev 10986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/TruthMaintenanceSystem.java 2007-04-16 01:25:42 UTC (rev 10987)
@@ -109,45 +109,110 @@
final Set set = (Set) this.justifiedMap.get( handle.getId() );
if ( set != null ) {
set.remove( node );
- if ( set.isEmpty() ) {
- // this needs to be scheduled so we don't upset the current
- // working memory operation
- WorkingMemoryAction action = new LogicalRetractCallback( this, set, handle, context );
- workingMemory.queueWorkingMemoryAction( action );
- }
+ WorkingMemoryAction action = new LogicalRetractCallback( this,
+ node,
+ set,
+ handle,
+ context );
+ workingMemory.queueWorkingMemoryAction( action );
}
+// if ( set != null ) {
+// set.remove( node );
+// if ( set.isEmpty() ) {
+// // this needs to be scheduled so we don't upset the current
+// // working memory operation
+// WorkingMemoryAction action = new LogicalRetractCallback( this,
+// node,
+// set,
+// handle,
+// context );
+// workingMemory.queueWorkingMemoryAction( action );
+//
+// // this.justifiedMap.remove( handle.getId() );
+// // WorkingMemoryAction action = new WorkingMemoryRetractAction(handle,
+// // false,
+// // true,
+// // context.getRuleOrigin(),
+// // context.getActivationOrigin() );
+// // this.workingMemory.queueWorkingMemoryAction( action );
+// }
+ }
}
+
+
+ public class WorkingMemoryRetractAction
+ implements
+ WorkingMemoryAction {
+ private InternalFactHandle factHandle;
+
+ private boolean removeLogical;
+
+ private boolean updateEqualsMap;
+
+ private Rule ruleOrigin;
+
+ private Activation activationOrigin;
+
+ public WorkingMemoryRetractAction(final InternalFactHandle factHandle,
+ final boolean removeLogical,
+ final boolean updateEqualsMap,
+ final Rule ruleOrigin,
+ final Activation activationOrigin) {
+ super();
+ this.factHandle = factHandle;
+ this.removeLogical = removeLogical;
+ this.updateEqualsMap = updateEqualsMap;
+ this.ruleOrigin = ruleOrigin;
+ this.activationOrigin = activationOrigin;
+ }
+
+ public void execute(InternalWorkingMemory workingMemory) {
+ workingMemory.retractObject( this.factHandle,
+ this.removeLogical,
+ this.updateEqualsMap,
+ this.ruleOrigin,
+ this.activationOrigin );
+ }
}
-
-
- public static class LogicalRetractCallback implements WorkingMemoryAction {
+ public static class LogicalRetractCallback
+ implements
+ WorkingMemoryAction {
private final TruthMaintenanceSystem tms;
- private final Set set;
- private final InternalFactHandle handle;
- private final PropagationContext context;
+ private final LogicalDependency node;
+ private final Set set;
+ private final InternalFactHandle handle;
+ private final PropagationContext context;
- public LogicalRetractCallback(TruthMaintenanceSystem tms, Set set, InternalFactHandle handle, PropagationContext context) {
+ public LogicalRetractCallback(TruthMaintenanceSystem tms,
+ LogicalDependency node,
+ Set set,
+ InternalFactHandle handle,
+ PropagationContext context) {
this.tms = tms;
+ this.node = node;
this.set = set;
this.handle = handle;
this.context = context;
}
public void execute(InternalWorkingMemory workingMemory) {
- if ( set.isEmpty() ) {
- this.tms.getJustifiedMap().remove( handle.getId() );
- // this needs to be scheduled so we don't upset the current
- // working memory operation
- workingMemory.retractObject( this.handle,
- false,
- true,
- context.getRuleOrigin(),
- context.getActivationOrigin() );
- }
+
+ if ( set.isEmpty() ) {
+ if ( set.isEmpty() ) {
+ this.tms.getJustifiedMap().remove( handle.getId() );
+ // this needs to be scheduled so we don't upset the current
+ // working memory operation
+ workingMemory.retractObject( this.handle,
+ false,
+ true,
+ context.getRuleOrigin(),
+ context.getActivationOrigin() );
+ }
+ }
}
- }
-
+ }
+
/**
* The FactHandle is being removed from the system so remove any logical dependencies
* between the justified FactHandle and its justifiers. Removes the FactHandle key
@@ -185,6 +250,8 @@
final Rule rule) throws FactException {
final LogicalDependency node = new LogicalDependency( activation,
handle );
+ activation.getRule().setHasLogicalDependency( true );
+
activation.addLogicalDependency( node );
Set set = (Set) this.justifiedMap.get( handle.getId() );
if ( set == null ) {
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java 2007-04-16 00:00:15 UTC (rev 10986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java 2007-04-16 01:25:42 UTC (rev 10987)
@@ -23,8 +23,10 @@
import org.drools.common.AgendaItem;
import org.drools.common.BaseNode;
import org.drools.common.InternalAgenda;
+import org.drools.common.InternalFactHandle;
import org.drools.common.InternalRuleFlowGroup;
import org.drools.common.InternalWorkingMemory;
+import org.drools.common.LogicalDependency;
import org.drools.common.NodeMemory;
import org.drools.common.PropagationContextImpl;
import org.drools.common.ScheduledAgendaItem;
@@ -37,6 +39,7 @@
import org.drools.spi.PropagationContext;
import org.drools.spi.RuleFlowGroup;
import org.drools.util.Iterator;
+import org.drools.util.LinkedList;
import org.drools.util.TupleHashTable;
/**
@@ -234,33 +237,64 @@
// do not add the activation if the rule is "lock-on-active" and the AgendaGroup is active
// we must check the context to determine if its a new tuple or an exist re-activated tuple as part of the retract
if ( context.getType() == PropagationContext.MODIFICATION ) {
- if ( this.rule.isLockOnActive() && agendaGroup.isActivate() && context.removeRetractedTuple( this.rule,
- tuple ) == null ) {
- // This rule is locked and active, do not allow new tuples to activate
- return;
+ if ( this.rule.isLockOnActive() && agendaGroup.isActive() ) {
+ Activation justifier = context.removeRetractedTuple( this.rule,
+ tuple );
+ if ( justifier == null ) {
+ // This rule is locked and active, do not allow new tuples to activate
+ return;
+ } else if ( this.rule.hasLogicalDependency() ) {
+ copyLogicalDependencies( context,
+ workingMemory,
+ item,
+ justifier );
+ }
+ } else if ( this.rule.hasLogicalDependency() ) {
+ Activation justifier = context.removeRetractedTuple( this.rule,
+ tuple );
+ copyLogicalDependencies( context,
+ workingMemory,
+ item,
+ justifier );
}
- } else if ( this.rule.isLockOnActive() && agendaGroup.isActivate() ) {
+ } else if ( this.rule.isLockOnActive() && agendaGroup.isActive() ) {
return;
}
agendaGroup.add( item );
} else {
//There is a RuleFlowNode so add it there, instead of the Agenda
-
+ RuleFlowGroup rfg = memory.getRuleFlowGroup();
// Lazy cache ruleFlowGroup
- if ( memory.getRuleFlowGroup() == null ) {
- memory.setRuleFlowGroup( workingMemory.getAgenda().getRuleFlowGroup( this.rule.getRuleFlowGroup() ) );
+ if ( rfg == null ) {
+ rfg = workingMemory.getAgenda().getRuleFlowGroup( this.rule.getRuleFlowGroup() );
+ memory.setRuleFlowGroup( rfg );
}
// do not add the activation if the rule is "lock-on-active" and the RuleFlowGroup is active
- // we must check the context to determine if its a new tuple or an exist re-activated tuple as part of the retract
+ // we must check the context to determine if its a new tuple or an exist re-activated tuple as part of the retract
if ( context.getType() == PropagationContext.MODIFICATION ) {
- if ( this.rule.isLockOnActive() && memory.getRuleFlowGroup().isActive() && context.removeRetractedTuple( this.rule,
- tuple ) == null ) {
- // This rule is locked and active, do not allow new tuples to activate
- return;
+ if ( this.rule.isLockOnActive() && rfg.isActive() ) {
+ Activation justifier = context.removeRetractedTuple( this.rule,
+ tuple );
+ if ( justifier == null ) {
+ // This rule is locked and active, do not allow new tuples to activate
+ return;
+ } else if ( this.rule.hasLogicalDependency() ) {
+ copyLogicalDependencies( context,
+ workingMemory,
+ item,
+ justifier );
+ }
+ } else if ( this.rule.hasLogicalDependency() ) {
+ Activation justifier = context.removeRetractedTuple( this.rule,
+ tuple );
+ copyLogicalDependencies( context,
+ workingMemory,
+ item,
+ justifier );
}
- } else if ( this.rule.isLockOnActive() && memory.getRuleFlowGroup().isActive() ) {
+ } else if ( this.rule.isLockOnActive() && rfg.isActive() ) {
return;
}
@@ -283,6 +317,24 @@
agenda.increaseActiveActivations();
}
+ private void copyLogicalDependencies(final PropagationContext context,
+ final InternalWorkingMemory workingMemory,
+ final AgendaItem item,
+ Activation justifier) {
+ if ( justifier != null ) {
+ final LinkedList list = justifier.getLogicalDependencies();
+ if ( list != null && !list.isEmpty() ) {
+ for ( LogicalDependency node = (LogicalDependency) list.getFirst(); node != null; node = (LogicalDependency) node.getNext() ) {
+ final InternalFactHandle handle = (InternalFactHandle) node.getFactHandle();
+ workingMemory.getTruthMaintenanceSystem().addLogicalDependency( handle,
+ item,
+ context,
+ this.rule );
+ }
+ }
+ }
+ }
+
public void retractTuple(final ReteTuple leftTuple,
final PropagationContext context,
final InternalWorkingMemory workingMemory) {
@@ -295,10 +347,19 @@
}
final Activation activation = tuple.getActivation();
+ if ( activation.getLogicalDependencies() != null && !activation.getLogicalDependencies().isEmpty() ) {
+ context.addRetractedTuple( this.rule,
+ activation );
+ }
+
if ( activation.isActivated() ) {
- if ( this.rule.isLockOnActive() && context.getType() == PropagationContext.MODIFICATION ) {
- context.addRetractedTuple( this.rule,
- tuple );
+ if ( context.getType() == PropagationContext.MODIFICATION ) {
+ // during a modify if we have either isLockOnActive or the activation has logical dependencies
+ // then we need to track retractions, so we know which are exising activations and which are truly new
+ if ( this.rule.isLockOnActive() ) {
+ context.addRetractedTuple( this.rule,
+ activation );
+ }
}
activation.remove();
@@ -309,7 +370,8 @@
if ( activation.getRuleFlowGroupNode() != null ) {
final InternalRuleFlowGroup ruleFlowGroup = activation.getRuleFlowGroupNode().getRuleFlowGroup();
- ruleFlowGroup.removeActivation( activation, workingMemory );
+ ruleFlowGroup.removeActivation( activation,
+ workingMemory );
}
workingMemory.getAgendaEventSupport().fireActivationCancelled( activation,
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Rule.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Rule.java 2007-04-16 00:00:15 UTC (rev 10986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Rule.java 2007-04-16 01:25:42 UTC (rev 10987)
@@ -88,6 +88,8 @@
private String ruleFlowGroup;
private boolean lockOnActive;
+
+ private boolean hasLogicalDependency;
/** indicates that the rule is semantically correct. */
private boolean semanticallyValid;
@@ -323,6 +325,14 @@
return (Declaration) this.declarations.get( identifier );
}
+ public boolean hasLogicalDependency() {
+ return this.hasLogicalDependency;
+ }
+
+ public void setHasLogicalDependency(boolean hasLogicalDependency) {
+ this.hasLogicalDependency = hasLogicalDependency;
+ }
+
public boolean isLockOnActive() {
return this.lockOnActive;
}
@@ -330,7 +340,7 @@
public void setLockOnActive(final boolean lockOnActive) {
this.lockOnActive = lockOnActive;
}
-
+
/**
* Retrieve the set of all <i>root fact object </i> parameter
* <code>Declarations</code>.
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/Activation.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/Activation.java 2007-04-16 00:00:15 UTC (rev 10986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/Activation.java 2007-04-16 01:25:42 UTC (rev 10987)
@@ -80,6 +80,8 @@
public void addLogicalDependency(LogicalDependency node);
public LinkedList getLogicalDependencies();
+
+ public void setLogicalDependencies(LinkedList justified);
public boolean isActivated();
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/AgendaGroup.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/AgendaGroup.java 2007-04-16 00:00:15 UTC (rev 10986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/AgendaGroup.java 2007-04-16 01:25:42 UTC (rev 10987)
@@ -57,6 +57,6 @@
*/
public int size();
- public boolean isActivate();
+ public boolean isActive();
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/PropagationContext.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/PropagationContext.java 2007-04-16 00:00:15 UTC (rev 10986)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/spi/PropagationContext.java 2007-04-16 01:25:42 UTC (rev 10987)
@@ -43,10 +43,10 @@
public int getDormantActivations();
public void addRetractedTuple(Rule rule,
- ReteTuple tuple);
+ Activation activation);
- public ReteTuple removeRetractedTuple(Rule rule,
- ReteTuple tuple);
+ public Activation removeRetractedTuple(Rule rule,
+ ReteTuple tuple);
public void clearRetractedTuples();
More information about the jboss-svn-commits
mailing list