[jboss-svn-commits] JBL Code SVN: r12721 - in labs/jbossrules/trunk/drools-core/src: test/java/org/drools/reteoo and 1 other directory.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed Jun 20 16:33:42 EDT 2007


Author: tirelli
Date: 2007-06-20 16:33:42 -0400 (Wed, 20 Jun 2007)
New Revision: 12721

Modified:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AccumulateNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CollectNode.java
   labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/CollectNodeTest.java
Log:
JBRULES-936: implementing incremental collect operations

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AccumulateNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AccumulateNode.java	2007-06-20 19:01:06 UTC (rev 12720)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AccumulateNode.java	2007-06-20 20:33:42 UTC (rev 12721)
@@ -374,8 +374,8 @@
     }
 
     private static class AccumulateResult {
+        // keeping attributes public just for performance
         public InternalFactHandle handle;
         public Object             context;
-
     }
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CollectNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CollectNode.java	2007-06-20 19:01:06 UTC (rev 12720)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CollectNode.java	2007-06-20 20:33:42 UTC (rev 12721)
@@ -128,6 +128,14 @@
         memory.getTupleMemory().add( leftTuple );
 
         final Collection result = this.collect.instantiateResultObject();
+        final InternalFactHandle resultHandle = workingMemory.getFactHandleFactory().newFactHandle( result );
+        CollectResult colresult = new CollectResult();
+        colresult.handle = resultHandle;
+        colresult.propagated = false;
+        memory.getCreatedHandles().put( leftTuple,
+                                        colresult,
+                                        false );
+
         final Iterator it = memory.getFactHandleMemory().iterator( leftTuple );
         this.constraints.updateFromTuple( workingMemory,
                                           leftTuple );
@@ -152,15 +160,11 @@
             this.resultsBinder.updateFromTuple( workingMemory,
                                                 leftTuple );
             if ( this.resultsBinder.isAllowedCachedLeft( result ) ) {
-                final InternalFactHandle handle = workingMemory.getFactHandleFactory().newFactHandle( result );
-                memory.getCreatedHandles().put( leftTuple,
-                                                handle,
-                                                false );
-
+                colresult.propagated = true;
                 this.sink.propagateAssertTuple( leftTuple,
-                                           handle,
-                                           context,
-                                           workingMemory );
+                                                resultHandle,
+                                                context,
+                                                workingMemory );
             }
         }
     }
@@ -174,10 +178,11 @@
 
         final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
         memory.getTupleMemory().remove( leftTuple );
-        final InternalFactHandle handle = (InternalFactHandle) memory.getCreatedHandles().remove( leftTuple );
+        CollectResult result = (CollectResult) memory.getCreatedHandles().remove( leftTuple );
+        final InternalFactHandle handle = result.handle;
 
         // if tuple was propagated
-        if ( handle != null ) {
+        if ( result.propagated ) {
 
             this.sink.propagateRetractTuple( leftTuple,
                                              handle,
@@ -213,10 +218,8 @@
         for ( int i = 0; i < tuples.length; i++ ) {
             ReteTuple tuple = (ReteTuple) tuples[i];
             if ( this.constraints.isAllowedCachedRight( tuple ) ) {
-                this.retractTuple( tuple,
-                                   context,
-                                   workingMemory );
-                this.assertTuple( tuple,
+                this.modifyTuple( tuple,
+                                  handle,
                                   context,
                                   workingMemory );
             }
@@ -240,22 +243,78 @@
 
         this.constraints.updateFromFactHandle( workingMemory,
                                                handle );
-        
+
         // need to clone the tuples to avoid concurrent modification exceptions
         Entry[] tuples = memory.getTupleMemory().toArray();
         for ( int i = 0; i < tuples.length; i++ ) {
             ReteTuple tuple = (ReteTuple) tuples[i];
             if ( this.constraints.isAllowedCachedRight( tuple ) ) {
-                this.retractTuple( tuple,
-                                   context,
-                                   workingMemory );
-                this.assertTuple( tuple,
+                
+                this.modifyTuple( tuple,
+                                  handle,
                                   context,
                                   workingMemory );
             }
         }
     }
 
+    /**
+     * Modifies the results match for a tuple, retracting it and repropagating
+     * if constraints allow it
+     * 
+     * @param leftTuple
+     * @param handle
+     * @param context
+     * @param workingMemory
+     */
+    public void modifyTuple(final ReteTuple leftTuple,
+                            final InternalFactHandle handle,
+                            final PropagationContext context,
+                            final InternalWorkingMemory workingMemory) {
+
+        final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
+
+        CollectResult result = (CollectResult) memory.getCreatedHandles().get( leftTuple );
+
+        // if tuple was propagated
+        if ( result.propagated ) {
+            this.sink.propagateRetractTuple( leftTuple,
+                                             result.handle,
+                                             context,
+                                             workingMemory );
+            result.propagated = false;
+        }
+
+        if ( context.getType() == PropagationContext.ASSERTION ) {
+            ((Collection) result.handle.getObject()).add( handle.getObject() );
+        } else if ( context.getType() == PropagationContext.RETRACTION ) {
+            ((Collection) result.handle.getObject()).remove( handle.getObject() );
+        } else if ( context.getType() == PropagationContext.MODIFICATION ) {
+            // nothing to do
+        }
+
+        // First alpha node filters
+        boolean isAllowed = true;
+        for ( int i = 0, length = this.resultConstraints.length; i < length; i++ ) {
+            if ( !this.resultConstraints[i].isAllowed( result.handle.getObject(),
+                                                       workingMemory ) ) {
+                isAllowed = false;
+                break;
+            }
+        }
+        if ( isAllowed ) {
+            this.resultsBinder.updateFromTuple( workingMemory,
+                                                leftTuple );
+            if ( this.resultsBinder.isAllowedCachedLeft( result.handle.getObject() ) ) {
+                result.propagated = true;
+                this.sink.propagateAssertTuple( leftTuple,
+                                                result.handle,
+                                                context,
+                                                workingMemory );
+            }
+        }
+    }
+
     public void updateSink(final TupleSink sink,
                            final PropagationContext context,
                            final InternalWorkingMemory workingMemory) {
@@ -264,8 +323,9 @@
         final Iterator it = memory.getCreatedHandles().iterator();
 
         for ( ObjectEntry entry = (ObjectEntry) it.next(); entry != null; entry = (ObjectEntry) it.next() ) {
+            CollectResult result = (CollectResult) entry.getValue();
             sink.assertTuple( new ReteTuple( (ReteTuple) entry.getKey(),
-                                             (InternalFactHandle) entry.getValue() ),
+                                             result.handle ),
                               context,
                               workingMemory );
         }
@@ -275,8 +335,7 @@
      * @see org.drools.reteoo.BaseNode#hashCode()
      */
     public int hashCode() {
-        return this.leftInput.hashCode() ^ this.rightInput.hashCode() ^ this.collect.hashCode() ^ this.resultsBinder.hashCode() ^
-            ArrayUtils.hashCode( this.resultConstraints );
+        return this.leftInput.hashCode() ^ this.rightInput.hashCode() ^ this.collect.hashCode() ^ this.resultsBinder.hashCode() ^ ArrayUtils.hashCode( this.resultConstraints );
     }
 
     /* (non-Javadoc)
@@ -292,17 +351,22 @@
         }
 
         final CollectNode other = (CollectNode) object;
-        
-        if( this.getClass() != other.getClass() || ( ! this.leftInput.equals( other.leftInput ) ) || 
-            ( ! this.rightInput.equals( other.rightInput ) ) || (! this.constraints.equals( other.constraints )) ) {
+
+        if ( this.getClass() != other.getClass() || (!this.leftInput.equals( other.leftInput )) || (!this.rightInput.equals( other.rightInput )) || (!this.constraints.equals( other.constraints )) ) {
             return false;
         }
-        
-        return this.collect.equals( other.collect ) && resultsBinder.equals( other.resultsBinder ) && Arrays.equals( this.resultConstraints, other.resultConstraints );
+
+        return this.collect.equals( other.collect ) && resultsBinder.equals( other.resultsBinder ) && Arrays.equals( this.resultConstraints,
+                                                                                                                     other.resultConstraints );
     }
 
     public String toString() {
         return "[ " + this.getClass().getName() + "(" + this.id + ") ]";
     }
 
+    private static class CollectResult {
+        // keeping attributes public just for performance
+        public InternalFactHandle handle;
+        public boolean            propagated;
+    }
 }

Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/CollectNodeTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/CollectNodeTest.java	2007-06-20 19:01:06 UTC (rev 12720)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/CollectNodeTest.java	2007-06-20 20:33:42 UTC (rev 12721)
@@ -40,7 +40,8 @@
  */
 public class CollectNodeTest extends DroolsTestCase {
     Rule                rule;
-    PropagationContext  context;
+    PropagationContext  contextAssert;
+    PropagationContext  contextRetract;
     ReteooWorkingMemory workingMemory;
     MockObjectSource    objectSource;
     MockTupleSource     tupleSource;
@@ -56,10 +57,14 @@
     protected void setUp() throws Exception {
         super.setUp();
         this.rule = new Rule( "test-rule" );
-        this.context = new PropagationContextImpl( 0,
-                                                   PropagationContext.ASSERTION,
-                                                   null,
-                                                   null );
+        this.contextAssert = new PropagationContextImpl( 0,
+                                                         PropagationContext.ASSERTION,
+                                                         null,
+                                                         null );
+        this.contextRetract = new PropagationContextImpl( 0,
+                                                         PropagationContext.RETRACTION,
+                                                         null,
+                                                         null );
         this.workingMemory = new ReteooWorkingMemory( 1,
                                                       (ReteooRuleBase) RuleBaseFactory.newRuleBase() );
 
@@ -101,17 +106,17 @@
 
     public void testUpdateNewNode() {
         this.node.updateSink( this.sink,
-                              this.context,
+                              this.contextAssert,
                               this.workingMemory );
         Assert.assertEquals( "No tuple should be propagated",
                              0,
                              this.sink.getAsserted().size() );
 
         this.node.assertTuple( new ReteTuple( this.workingMemory.getFactHandleFactory().newFactHandle( "cheese" ) ),
-                               this.context,
+                               this.contextAssert,
                                this.workingMemory );
         this.node.assertTuple( new ReteTuple( this.workingMemory.getFactHandleFactory().newFactHandle( "other cheese" ) ),
-                               this.context,
+                               this.contextAssert,
                                this.workingMemory );
 
         Assert.assertEquals( "Two tuples should have been propagated",
@@ -122,7 +127,7 @@
 
         this.node.addTupleSink( otherSink );
         this.node.updateSink( otherSink,
-                              this.context,
+                              this.contextAssert,
                               this.workingMemory );
 
         Assert.assertEquals( "Two tuples should have been propagated",
@@ -136,7 +141,7 @@
 
         // assert tuple, should add one to left memory
         this.node.assertTuple( tuple0,
-                               this.context,
+                               this.contextAssert,
                                this.workingMemory );
         // check memories 
         assertEquals( 1,
@@ -151,7 +156,7 @@
 
         final ReteTuple tuple1 = new ReteTuple( f1 );
         this.node.assertTuple( tuple1,
-                               this.context,
+                               this.contextAssert,
                                this.workingMemory );
         assertEquals( 2,
                       this.memory.getTupleMemory().size() );
@@ -173,15 +178,15 @@
         final ReteTuple tuple0 = new ReteTuple( f0 );
 
         this.node.assertObject( f0,
-                                this.context,
+                                this.contextAssert,
                                 this.workingMemory );
         this.node.assertObject( f1,
-                                this.context,
+                                this.contextAssert,
                                 this.workingMemory );
 
         // assert tuple, should add one to left memory
         this.node.assertTuple( tuple0,
-                               this.context,
+                               this.contextAssert,
                                this.workingMemory );
         // check memories 
         assertEquals( 1,
@@ -195,7 +200,7 @@
         // assert tuple, should add left memory 
         final ReteTuple tuple1 = new ReteTuple( f1 );
         this.node.assertTuple( tuple1,
-                               this.context,
+                               this.contextAssert,
                                this.workingMemory );
         assertEquals( 2,
                       this.memory.getTupleMemory().size() );
@@ -218,7 +223,7 @@
 
         // assert tuple, should add one to left memory
         this.node.assertTuple( tuple0,
-                               this.context,
+                               this.contextAssert,
                                this.workingMemory );
         // check memories 
         assertEquals( 1,
@@ -229,7 +234,7 @@
                            ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this.sink.getAsserted().get( 0 ))[0]).get( 1 )).getObject()).isEmpty() );
 
         this.node.retractTuple( tuple0,
-                                this.context,
+                                this.contextRetract,
                                 this.workingMemory );
         assertEquals( 0,
                       this.memory.getTupleMemory().size() );
@@ -247,7 +252,7 @@
 
         // assert tuple, should add one to left memory
         this.node.assertTuple( tuple0,
-                               this.context,
+                               this.contextAssert,
                                this.workingMemory );
 
         // check memory 
@@ -259,7 +264,7 @@
                            ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this.sink.getAsserted().get( 0 ))[0]).get( 1 )).getObject()).isEmpty() );
 
         this.node.assertObject( f0,
-                                this.context,
+                                this.contextAssert,
                                 this.workingMemory );
         assertEquals( 1,
                       this.memory.getFactHandleMemory().size() );
@@ -270,7 +275,7 @@
                              ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this.sink.getAsserted().get( 1 ))[0]).get( 1 )).getObject()).size() );
 
         this.node.assertObject( f1,
-                                this.context,
+                                this.contextAssert,
                                 this.workingMemory );
 
         assertEquals( 2,
@@ -290,17 +295,17 @@
         final ReteTuple tuple0 = new ReteTuple( f0 );
 
         this.node.assertObject( f0,
-                                this.context,
+                                this.contextAssert,
                                 this.workingMemory );
         this.node.assertObject( f1,
-                                this.context,
+                                this.contextAssert,
                                 this.workingMemory );
         assertEquals( 2,
                       this.memory.getFactHandleMemory().size() );
 
         // assert tuple, should add one to left memory
         this.node.assertTuple( tuple0,
-                               this.context,
+                               this.contextAssert,
                                this.workingMemory );
 
         // check memory 
@@ -315,7 +320,7 @@
                              ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this.sink.getAsserted().get( 0 ))[0]).get( 1 )).getObject()).size() );
 
         this.node.retractObject( f1,
-                                 this.context,
+                                 this.contextRetract,
                                  this.workingMemory );
         assertEquals( 1,
                       this.memory.getFactHandleMemory().size() );
@@ -328,7 +333,7 @@
                              ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this.sink.getAsserted().get( 1 ))[0]).get( 1 )).getObject()).size() );
 
         this.node.retractObject( f0,
-                                 this.context,
+                                 this.contextRetract,
                                  this.workingMemory );
         assertEquals( 0,
                       this.memory.getFactHandleMemory().size() );




More information about the jboss-svn-commits mailing list