[jboss-svn-commits] JBL Code SVN: r31678 - labs/jbossrules/branches/true_modify_20100104/drools-core/src/main/java/org/drools/reteoo.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Mon Feb 15 15:47:34 EST 2010
Author: tirelli
Date: 2010-02-15 15:47:33 -0500 (Mon, 15 Feb 2010)
New Revision: 31678
Modified:
labs/jbossrules/branches/true_modify_20100104/drools-core/src/main/java/org/drools/reteoo/BetaNode.java
labs/jbossrules/branches/true_modify_20100104/drools-core/src/main/java/org/drools/reteoo/FromNode.java
labs/jbossrules/branches/true_modify_20100104/drools-core/src/main/java/org/drools/reteoo/LeftTuple.java
Log:
JBRULES-2339: JBRULES-2340: trying again: fixing from node
Modified: labs/jbossrules/branches/true_modify_20100104/drools-core/src/main/java/org/drools/reteoo/BetaNode.java
===================================================================
--- labs/jbossrules/branches/true_modify_20100104/drools-core/src/main/java/org/drools/reteoo/BetaNode.java 2010-02-15 16:39:21 UTC (rev 31677)
+++ labs/jbossrules/branches/true_modify_20100104/drools-core/src/main/java/org/drools/reteoo/BetaNode.java 2010-02-15 20:47:33 UTC (rev 31678)
@@ -36,7 +36,6 @@
import org.drools.rule.BehaviorManager;
import org.drools.spi.BetaNodeFieldConstraint;
import org.drools.spi.PropagationContext;
-import org.drools.util.ConcurrentRightTupleList;
import org.drools.util.Iterator;
import org.drools.util.LinkedList;
import org.drools.util.LinkedListEntry;
@@ -180,8 +179,8 @@
this.leftInput.networkUpdated();
}
- public List getRules() {
- final List list = new ArrayList();
+ public List<String> getRules() {
+ final List<String> list = new ArrayList<String>();
final LeftTupleSink[] sinks = this.sink.getSinks();
for ( int i = 0, length = sinks.length; i < length; i++ ) {
Modified: labs/jbossrules/branches/true_modify_20100104/drools-core/src/main/java/org/drools/reteoo/FromNode.java
===================================================================
--- labs/jbossrules/branches/true_modify_20100104/drools-core/src/main/java/org/drools/reteoo/FromNode.java 2010-02-15 16:39:21 UTC (rev 31677)
+++ labs/jbossrules/branches/true_modify_20100104/drools-core/src/main/java/org/drools/reteoo/FromNode.java 2010-02-15 20:47:33 UTC (rev 31678)
@@ -4,6 +4,8 @@
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
import org.drools.RuleBaseConfiguration;
import org.drools.common.BaseNode;
@@ -29,7 +31,6 @@
*
*/
private static final long serialVersionUID = 400L;
-
private DataProvider dataProvider;
private LeftTupleSource tupleSource;
@@ -50,7 +51,7 @@
final AlphaNodeFieldConstraint[] constraints,
final BetaConstraints binder,
final boolean tupleMemoryEnabled,
- final BuildContext context ) {
+ final BuildContext context) {
super( id,
context.getPartitionId(),
context.getRuleBase().getConfiguration().isMultithreadEvaluation() );
@@ -92,8 +93,12 @@
final InternalWorkingMemory workingMemory) {
final FromMemory memory = (FromMemory) workingMemory.getNodeMemory( this );
- if ( this.tupleMemoryEnabled ) {
+ Map<Object, RightTuple> matches = null;
+ if( this.tupleMemoryEnabled ) {
memory.betaMemory.getLeftTupleMemory().add( leftTuple );
+ matches = new HashMap<Object, RightTuple>();
+ memory.betaMemory.getCreatedHandles().put( leftTuple,
+ matches );
}
if ( this.sink.size() == 0 ) {
@@ -101,30 +106,14 @@
return;
}
- evaluateAndPropagate( leftTuple,
- context,
- workingMemory,
- memory );
- }
-
- /**
- * @param leftTuple
- * @param context
- * @param workingMemory
- * @param memory
- */
- private void evaluateAndPropagate(final LeftTuple leftTuple,
- final PropagationContext context,
- final InternalWorkingMemory workingMemory,
- final FromMemory memory) {
this.betaConstraints.updateFromTuple( memory.betaMemory.getContext(),
workingMemory,
leftTuple );
- for ( final java.util.Iterator it = this.dataProvider.getResults( leftTuple,
- workingMemory,
- context,
- memory.providerContext ); it.hasNext(); ) {
+ for ( final java.util.Iterator< ? > it = this.dataProvider.getResults( leftTuple,
+ workingMemory,
+ context,
+ memory.providerContext ); it.hasNext(); ) {
final Object object = it.next();
final InternalFactHandle handle = workingMemory.getFactHandleFactory().newFactHandle( object,
@@ -134,35 +123,180 @@
RightTuple rightTuple = new RightTuple( handle,
null );
- boolean isAllowed = true;
- if ( this.alphaConstraints != null ) {
- // First alpha node filters
- for ( int i = 0, length = this.alphaConstraints.length; i < length; i++ ) {
- if ( !this.alphaConstraints[i].isAllowed( handle,
- workingMemory,
- memory.alphaContexts[i] ) ) {
- // next iteration
- isAllowed = false;
- break;
- }
+ checkConstraintsAndPropagate( leftTuple,
+ rightTuple,
+ context,
+ workingMemory,
+ memory );
+ if( this.tupleMemoryEnabled ) {
+ addToCreatedHandlesMap( matches,
+ rightTuple );
+ }
+ }
+
+ this.betaConstraints.resetTuple( memory.betaMemory.getContext() );
+ }
+
+ private void addToCreatedHandlesMap(final Map<Object, RightTuple> matches,
+ final RightTuple rightTuple) {
+ if ( rightTuple.getFactHandle().isValid() ) {
+ Object object = rightTuple.getFactHandle().getObject();
+ // keeping a list of matches
+ RightTuple existingMatch = matches.get( object );
+ if ( existingMatch != null ) {
+ // this is for the obscene case where two or more objects returned by "from"
+ // have the same hash code and evaluate equals() to true, so we need to preserve
+ // all of them to avoid leaks
+ rightTuple.setNext( existingMatch );
+ }
+ matches.put( object,
+ rightTuple );
+ }
+ }
+
+ public void modifyLeftTuple(InternalFactHandle factHandle,
+ ModifyPreviousTuples modifyPreviousTuples,
+ PropagationContext context,
+ InternalWorkingMemory workingMemory) {
+ LeftTuple leftTuple = modifyPreviousTuples.removeLeftTuple( this );
+ if ( leftTuple != null ) {
+ leftTuple.reAdd(); //
+ // LeftTuple previously existed, so continue as modify
+ modifyLeftTuple( leftTuple,
+ context,
+ workingMemory );
+ } else {
+ // LeftTuple does not exist, so create and continue as assert
+ assertLeftTuple( new LeftTuple( factHandle,
+ this,
+ true ),
+ context,
+ workingMemory );
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void modifyLeftTuple(LeftTuple leftTuple,
+ PropagationContext context,
+ InternalWorkingMemory workingMemory) {
+
+ final FromMemory memory = (FromMemory) workingMemory.getNodeMemory( this );
+
+ memory.betaMemory.getLeftTupleMemory().remove( leftTuple );
+ memory.betaMemory.getLeftTupleMemory().add( leftTuple );
+
+ final Map<Object, RightTuple> previousMatches = (Map<Object, RightTuple>) memory.betaMemory.getCreatedHandles().remove( leftTuple );
+ final Map<Object, RightTuple> newMatches = new HashMap<Object, RightTuple>();
+ memory.betaMemory.getCreatedHandles().put( leftTuple,
+ newMatches );
+
+ this.betaConstraints.updateFromTuple( memory.betaMemory.getContext(),
+ workingMemory,
+ leftTuple );
+
+ for ( final java.util.Iterator< ? > it = this.dataProvider.getResults( leftTuple,
+ workingMemory,
+ context,
+ memory.providerContext ); it.hasNext(); ) {
+ final Object object = it.next();
+ RightTuple rightTuple = previousMatches.remove( object );
+
+ if ( rightTuple == null ) {
+ // new match, propagate assert
+ final InternalFactHandle handle = workingMemory.getFactHandleFactory().newFactHandle( object,
+ null, // set this to null, otherwise it uses the driver fact's entrypoint
+ workingMemory );
+ rightTuple = new RightTuple( handle,
+ null );
+ } else {
+ // previous match, so reevaluate and propagate modify
+ if ( rightTuple.getNext() != null ) {
+ // handle the odd case where more than one object has the same hashcode/equals value
+ previousMatches.put( object,
+ (RightTuple) rightTuple.getNext() );
+ rightTuple.setNext( null );
}
}
- if ( isAllowed && this.betaConstraints.isAllowedCachedLeft( memory.betaMemory.getContext(),
- handle ) ) {
- //list.add( new LinkedListEntry( handle ) );
+ checkConstraintsAndPropagate( leftTuple,
+ rightTuple,
+ context,
+ workingMemory,
+ memory );
+ addToCreatedHandlesMap( newMatches,
+ rightTuple );
+ }
+ this.betaConstraints.resetTuple( memory.betaMemory.getContext() );
+
+ for ( RightTuple rightTuple : previousMatches.values() ) {
+ for ( RightTuple current = rightTuple; current != null; current = (RightTuple) current.getNext() ) {
+ retractMatchAndDestroyHandle( leftTuple,
+ current,
+ context,
+ workingMemory );
+ }
+ }
+ }
+
+ private void checkConstraintsAndPropagate(final LeftTuple leftTuple,
+ final RightTuple rightTuple,
+ final PropagationContext context,
+ final InternalWorkingMemory workingMemory,
+ final FromMemory memory) {
+ boolean isAllowed = true;
+ if ( this.alphaConstraints != null ) {
+ // First alpha node filters
+ for ( int i = 0, length = this.alphaConstraints.length; i < length; i++ ) {
+ if ( !this.alphaConstraints[i].isAllowed( rightTuple.getFactHandle(),
+ workingMemory,
+ memory.alphaContexts[i] ) ) {
+ // next iteration
+ isAllowed = false;
+ break;
+ }
+ }
+ }
+
+ if ( isAllowed && this.betaConstraints.isAllowedCachedLeft( memory.betaMemory.getContext(),
+ rightTuple.getFactHandle() ) ) {
+
+ if ( rightTuple.firstChild == null ) {
+ // this is a new match, so propagate as assert
this.sink.propagateAssertLeftTuple( leftTuple,
rightTuple,
context,
workingMemory,
this.tupleMemoryEnabled );
} else {
- workingMemory.getFactHandleFactory().destroyFactHandle( handle );
+ // this is an existing match, so propagate as a modify
+ this.sink.propagateModifyChildLeftTuple( rightTuple.firstChild,
+ leftTuple,
+ context,
+ workingMemory,
+ this.tupleMemoryEnabled );
}
+ } else {
+ retractMatchAndDestroyHandle( leftTuple,
+ rightTuple,
+ context,
+ workingMemory );
}
+ }
- this.betaConstraints.resetTuple( memory.betaMemory.getContext() );
+ private void retractMatchAndDestroyHandle(final LeftTuple leftTuple,
+ final RightTuple rightTuple,
+ final PropagationContext context,
+ final InternalWorkingMemory workingMemory) {
+ if ( rightTuple.firstChild != null ) {
+ // there was a previous match, so need to retract
+ this.sink.propagateRetractChildLeftTuple( rightTuple.firstChild,
+ leftTuple,
+ context,
+ workingMemory );
+
+ }
+ workingMemory.getFactHandleFactory().destroyFactHandle( rightTuple.getFactHandle() );
}
public void retractLeftTuple(final LeftTuple leftTuple,
@@ -171,6 +305,7 @@
final FromMemory memory = (FromMemory) workingMemory.getNodeMemory( this );
memory.betaMemory.getLeftTupleMemory().remove( leftTuple );
+ memory.betaMemory.getCreatedHandles().remove( leftTuple );
this.sink.propagateRetractLeftTupleDestroyRightTuple( leftTuple,
context,
@@ -211,23 +346,23 @@
if ( !node.isInUse() ) {
removeTupleSink( (LeftTupleSink) node );
}
-
+
if ( !this.isInUse() ) {
for ( int i = 0, length = workingMemories.length; i < length; i++ ) {
- FromMemory memory = ( FromMemory ) workingMemories[i].getNodeMemory( this );
+ FromMemory memory = (FromMemory) workingMemories[i].getNodeMemory( this );
Iterator it = memory.betaMemory.getLeftTupleMemory().iterator();
for ( LeftTuple leftTuple = (LeftTuple) it.next(); leftTuple != null; leftTuple = (LeftTuple) it.next() ) {
leftTuple.unlinkFromLeftParent();
leftTuple.unlinkFromRightParent();
- }
-
+ }
+
// RightTuple is already disconnected via the child LeftTuple in the sink nodes
// special case exists in the BetaNode to handle destroying of the FactHandle
-
+
workingMemories[i].clearNodeMemory( this );
}
}
-
+
if ( !context.alreadyVisited( this.tupleSource ) ) {
this.tupleSource.remove( context,
builder,
@@ -236,6 +371,7 @@
}
}
+ @SuppressWarnings("unchecked")
public void updateSink(final LeftTupleSink sink,
final PropagationContext context,
final InternalWorkingMemory workingMemory) {
@@ -244,10 +380,16 @@
final Iterator tupleIter = memory.betaMemory.getLeftTupleMemory().iterator();
for ( LeftTuple leftTuple = (LeftTuple) tupleIter.next(); leftTuple != null; leftTuple = (LeftTuple) tupleIter.next() ) {
- evaluateAndPropagate( leftTuple,
- context,
- workingMemory,
- memory );
+ Map<Object, RightTuple> matches = (Map<Object, RightTuple>) memory.betaMemory.getCreatedHandles().get( leftTuple );
+ for ( RightTuple rightTuples : matches.values() ) {
+ for( RightTuple rightTuple = rightTuples; rightTuple != null; rightTuple = (RightTuple)rightTuples.getNext() ) {
+ this.sink.propagateAssertLeftTuple( leftTuple,
+ rightTuple,
+ context,
+ workingMemory,
+ this.tupleMemoryEnabled );
+ }
+ }
}
}
@@ -303,10 +445,10 @@
public void setPreviousLeftTupleSinkNode(final LeftTupleSinkNode previous) {
this.previousTupleSinkNode = previous;
}
-
+
public short getType() {
return NodeTypeEnums.FromNode;
- }
+ }
public static class FromMemory
implements
@@ -329,18 +471,4 @@
}
}
- public void modifyLeftTuple(InternalFactHandle factHandle,
- ModifyPreviousTuples modifyPreviousTuples,
- PropagationContext context,
- InternalWorkingMemory workingMemory) {
- // TODO Auto-generated method stub
-
- }
-
- public void modifyLeftTuple(LeftTuple leftTuple,
- PropagationContext context,
- InternalWorkingMemory workingMemory) {
- // TODO Auto-generated method stub
-
- }
}
Modified: labs/jbossrules/branches/true_modify_20100104/drools-core/src/main/java/org/drools/reteoo/LeftTuple.java
===================================================================
--- labs/jbossrules/branches/true_modify_20100104/drools-core/src/main/java/org/drools/reteoo/LeftTuple.java 2010-02-15 16:39:21 UTC (rev 31677)
+++ labs/jbossrules/branches/true_modify_20100104/drools-core/src/main/java/org/drools/reteoo/LeftTuple.java 2010-02-15 20:47:33 UTC (rev 31678)
@@ -154,7 +154,6 @@
this.leftParent.firstChild = this.leftParentNext;
this.leftParentNext.leftParentPrevious = null;
}
-
// re-add to end
this.leftParentPrevious = this.leftParent.lastChild;
this.leftParentPrevious.leftParentNext = this;
@@ -174,7 +173,6 @@
this.rightParent.firstChild = this.rightParentNext;
this.rightParentNext.rightParentPrevious = null;
}
-
// re-add to end
this.rightParentPrevious = this.rightParent.lastChild;
this.rightParentPrevious.rightParentNext = this;
More information about the jboss-svn-commits
mailing list