[jboss-svn-commits] JBL Code SVN: r5823 - in labs/jbossrules/branches/3.0.x: drools-compiler/src/test/java/org/drools drools-compiler/src/test/java/org/drools/integrationtests drools-compiler/src/test/resources/org/drools/integrationtests drools-core/src/main/java/org/drools/reteoo

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Sat Aug 12 10:13:41 EDT 2006


Author: tirelli
Date: 2006-08-12 10:13:27 -0400 (Sat, 12 Aug 2006)
New Revision: 5823

Added:
   labs/jbossrules/branches/3.0.x/drools-compiler/src/test/resources/org/drools/integrationtests/test_LogicalAssertionWithExists.drl
Modified:
   labs/jbossrules/branches/3.0.x/drools-compiler/src/test/java/org/drools/Cheese.java
   labs/jbossrules/branches/3.0.x/drools-compiler/src/test/java/org/drools/integrationtests/IntegrationCases.java
   labs/jbossrules/branches/3.0.x/drools-core/src/main/java/org/drools/reteoo/JoinNode.java
   labs/jbossrules/branches/3.0.x/drools-core/src/main/java/org/drools/reteoo/NotNode.java
   labs/jbossrules/branches/3.0.x/drools-core/src/main/java/org/drools/reteoo/TerminalNode.java
Log:
JBRULES-387:

  * Fixing NOT and JOIN node problems on modify tuple
  * Adding test case
 


Modified: labs/jbossrules/branches/3.0.x/drools-compiler/src/test/java/org/drools/Cheese.java
===================================================================
--- labs/jbossrules/branches/3.0.x/drools-compiler/src/test/java/org/drools/Cheese.java	2006-08-12 13:44:25 UTC (rev 5822)
+++ labs/jbossrules/branches/3.0.x/drools-compiler/src/test/java/org/drools/Cheese.java	2006-08-12 14:13:27 UTC (rev 5823)
@@ -43,6 +43,10 @@
         return this.type;
     }
 
+    public void setType( String type ) {
+        this.type = type;
+    }
+
     public void setPrice(final int price) {
         this.price = price;
     }

Modified: labs/jbossrules/branches/3.0.x/drools-compiler/src/test/java/org/drools/integrationtests/IntegrationCases.java
===================================================================
--- labs/jbossrules/branches/3.0.x/drools-compiler/src/test/java/org/drools/integrationtests/IntegrationCases.java	2006-08-12 13:44:25 UTC (rev 5822)
+++ labs/jbossrules/branches/3.0.x/drools-compiler/src/test/java/org/drools/integrationtests/IntegrationCases.java	2006-08-12 14:13:27 UTC (rev 5823)
@@ -2612,4 +2612,92 @@
         assertEquals(1, list.size() );        
     }
 
+    public void testLogicalAssertionsWithExists() throws Exception {
+        final PackageBuilder builder = new PackageBuilder();
+        builder.addPackageFromDrl( new InputStreamReader( getClass().getResourceAsStream( "test_LogicalAssertionWithExists.drl" )) );
+        final Package pkg = builder.getPackage();
+    
+        final RuleBase ruleBase = getRuleBase();
+        ruleBase.addPackage( pkg );
+        final WorkingMemory workingMemory = ruleBase.newWorkingMemory();
+    
+        Person p1 = new Person( "p1",
+                                "stilton",
+                                20 );
+        p1.setStatus( "europe" );
+        FactHandle c1FactHandle = workingMemory.assertObject( p1 );
+        Person p2 = new Person( "p2",
+                                "stilton",
+                                30 );
+        p2.setStatus( "europe" );
+        FactHandle c2FactHandle = workingMemory.assertObject( p2 );
+        Person p3 = new Person( "p3",
+                                "stilton",
+                                40 );
+        p3.setStatus( "europe" );
+        FactHandle c3FactHandle = workingMemory.assertObject( p3 );
+        workingMemory.fireAllRules();
+        
+        // all 3 in europe, so, 2 cheese
+        List cheeseList = workingMemory.getObjects( String.class );
+        assertEquals( 2,
+                      cheeseList.size() );
+        
+        // europe=[ 1, 2 ], america=[ 3 ]
+        p3.setStatus( "america" );
+        workingMemory.modifyObject( c3FactHandle,
+                                    p3 );
+        workingMemory.fireAllRules();
+        cheeseList = workingMemory.getObjects( String.class );
+        assertEquals( 1,
+                      cheeseList.size() );
+        
+        // europe=[ 1 ], america=[ 2, 3 ]
+        p2.setStatus( "america" );
+        workingMemory.modifyObject( c2FactHandle,
+                                    p2 );
+        workingMemory.fireAllRules();
+        cheeseList = workingMemory.getObjects( String.class );
+        assertEquals( 1,
+                      cheeseList.size() );
+        
+        // europe=[ ], america=[ 1, 2, 3 ]
+        p1.setStatus( "america" );
+        workingMemory.modifyObject( c1FactHandle,
+                                    p1 );
+        workingMemory.fireAllRules();
+        cheeseList = workingMemory.getObjects( String.class );
+        assertEquals( 2,
+                      cheeseList.size() );
+        
+        // europe=[ 2 ], america=[ 1, 3 ]
+        p2.setStatus( "europe" );
+        workingMemory.modifyObject( c2FactHandle,
+                                    p2 );
+        workingMemory.fireAllRules();
+        cheeseList = workingMemory.getObjects( String.class );
+        assertEquals( 1,
+                      cheeseList.size() );
+        
+        // europe=[ 1, 2 ], america=[ 3 ]
+        p1.setStatus( "europe" );
+        workingMemory.modifyObject( c1FactHandle,
+                                    p1 );
+        workingMemory.fireAllRules();
+        cheeseList = workingMemory.getObjects( String.class );
+        assertEquals( 1,
+                      cheeseList.size() );
+        
+        // europe=[ 1, 2, 3 ], america=[ ]
+        p3.setStatus( "europe" );
+        workingMemory.modifyObject( c3FactHandle,
+                                    p3 );
+        workingMemory.fireAllRules();
+        cheeseList = workingMemory.getObjects( String.class );
+        assertEquals( 2,
+                      cheeseList.size() );
+        
+        
+    }
+
 }

Added: labs/jbossrules/branches/3.0.x/drools-compiler/src/test/resources/org/drools/integrationtests/test_LogicalAssertionWithExists.drl
===================================================================
--- labs/jbossrules/branches/3.0.x/drools-compiler/src/test/resources/org/drools/integrationtests/test_LogicalAssertionWithExists.drl	2006-08-12 13:44:25 UTC (rev 5822)
+++ labs/jbossrules/branches/3.0.x/drools-compiler/src/test/resources/org/drools/integrationtests/test_LogicalAssertionWithExists.drl	2006-08-12 14:13:27 UTC (rev 5823)
@@ -0,0 +1,9 @@
+package org.drools
+
+rule "Supply cheese for every 2 persons with the same status"
+	when
+		p : Person($status : status, $age : age)
+		exists Person(status == $status, age > $age);
+	then
+        assertLogical(new String("Cheese for person with age " + $age));
+end
\ No newline at end of file


Property changes on: labs/jbossrules/branches/3.0.x/drools-compiler/src/test/resources/org/drools/integrationtests/test_LogicalAssertionWithExists.drl
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:eol-style
   + native

Modified: labs/jbossrules/branches/3.0.x/drools-core/src/main/java/org/drools/reteoo/JoinNode.java
===================================================================
--- labs/jbossrules/branches/3.0.x/drools-core/src/main/java/org/drools/reteoo/JoinNode.java	2006-08-12 13:44:25 UTC (rev 5822)
+++ labs/jbossrules/branches/3.0.x/drools-core/src/main/java/org/drools/reteoo/JoinNode.java	2006-08-12 14:13:27 UTC (rev 5823)
@@ -17,6 +17,7 @@
  */
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -258,6 +259,11 @@
                          context,
                          workingMemory );
         } else {
+            // TIRELLI's NOTE: the following is necessary because in case memory  
+            // indexing is enabled, the loop over right objects may skip some of the
+            // previously matched objects
+            final Map oldMatches = new HashMap(matches);
+            
             // ensure the tuple is at the top of the memory
             memory.add( workingMemory,
                         leftTuple );
@@ -271,7 +277,7 @@
                 if ( binder.isAllowed( handle,
                                        leftTuple,
                                        workingMemory ) ) {
-                    TupleMatch tupleMatch = (TupleMatch) leftTuple.getTupleMatches().get( handle );
+                    TupleMatch tupleMatch = (TupleMatch) oldMatches.remove( handle );
                     if ( tupleMatch != null ) {
                         // ensures tupleMatch will be in the appropriate order
                         objectMatches.remove( tupleMatch );
@@ -294,6 +300,7 @@
                 } else {
                     final TupleMatch tupleMatch = leftTuple.removeMatch( handle );
                     if ( tupleMatch != null ) {
+                        oldMatches.remove( handle );
                         objectMatches.remove( tupleMatch );
                         propagateRetractTuple( tupleMatch,
                                                context,
@@ -301,6 +308,16 @@
                     }
                 }
             }
+            
+            // TIRELLI's NOTE: the following is necessary because in case memory  
+            // indexing is enabled, the loop over right objects may skip some of the
+            // previously matched objects
+            if(!oldMatches.isEmpty()) {
+                for(Iterator it = oldMatches.values().iterator(); it.hasNext(); ) {
+                    final TupleMatch tupleMatch = (TupleMatch) it.next();
+                    tupleMatch.getObjectMatches().remove( tupleMatch );
+                }
+            }
         }
     }
 

Modified: labs/jbossrules/branches/3.0.x/drools-core/src/main/java/org/drools/reteoo/NotNode.java
===================================================================
--- labs/jbossrules/branches/3.0.x/drools-core/src/main/java/org/drools/reteoo/NotNode.java	2006-08-12 13:44:25 UTC (rev 5822)
+++ labs/jbossrules/branches/3.0.x/drools-core/src/main/java/org/drools/reteoo/NotNode.java	2006-08-12 14:13:27 UTC (rev 5823)
@@ -17,6 +17,7 @@
  */
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -249,9 +250,13 @@
         memory.add( workingMemory,
                     leftTuple );
 
-        final Map matches = leftTuple.getTupleMatches();
+        // TIRELLI's NOTE: the following is necessary because in case memory  
+        // indexing is enabled, the loop over right objects may skip some of the
+        // previously matched objects
+        final Map oldMatches = new HashMap(leftTuple.getTupleMatches());
+        leftTuple.getTupleMatches().clear();
 
-        final int previous = matches.size();
+        final int previous = oldMatches.size();
         final BetaNodeBinder binder = getJoinNodeBinder();
 
         for ( final Iterator rightIterator = memory.rightObjectIterator( workingMemory,
@@ -263,21 +268,30 @@
                                    leftTuple,
                                    workingMemory ) ) {
                 // test passes
-                TupleMatch tupleMatch = (TupleMatch) leftTuple.getTupleMatches().get( handle );
+                TupleMatch tupleMatch = (TupleMatch) oldMatches.remove( handle );
                 if ( tupleMatch == null ) {
                     // no previous matches so add a match now
                     tupleMatch = objectMatches.add( leftTuple );
-                    leftTuple.addTupleMatch( handle,
-                                             tupleMatch );
                 }
+                leftTuple.addTupleMatch( handle,
+                                         tupleMatch );
             } else {
-                final TupleMatch tupleMatch = leftTuple.removeMatch( handle );
+                final TupleMatch tupleMatch = (TupleMatch) oldMatches.remove( handle );
                 if ( tupleMatch != null ) {
                     // use to match and doesn't any more, so remove match
                     objectMatches.remove( tupleMatch );
                 }
             }
         }
+
+        // TIRELLI's NOTE: the following is necessary because in case memory  
+        // indexing is enabled, the loop over right objects may skip some of the
+        // previously matched objects
+        for ( final Iterator oldMatchesIt = oldMatches.values().iterator(); oldMatchesIt.hasNext(); ) {
+            final TupleMatch tupleMatch = (TupleMatch) oldMatchesIt.next();
+            tupleMatch.getObjectMatches().remove( tupleMatch );
+        }
+        
         if ( previous == 0 && leftTuple.matchesSize() == 0 ) {
             propagateModifyTuple( leftTuple,
                                   context,
@@ -306,20 +320,22 @@
 
         TupleMatch tupleMatch = objectMatches.getFirstTupleMatch();
         final BetaNodeBinder binder = getJoinNodeBinder();
-
+        
         for ( final Iterator it = memory.leftTupleIterator( workingMemory,
                                                             handle ); it.hasNext(); ) {
             final ReteTuple leftTuple = (ReteTuple) it.next();
+            
             if ( tupleMatch != null && tupleMatch.getTuple() == leftTuple ) {
                 // has previous match so need to decide whether to continue
                 // modify or retract
                 final int previous = leftTuple.getTupleMatches().size();
+                TupleMatch nextTupleMatch = (TupleMatch) tupleMatch.getNext();
                 if ( !binder.isAllowed( handle,
                                         leftTuple,
                                         workingMemory ) ) {
                     leftTuple.removeMatch( handle );
                     objectMatches.remove( tupleMatch );
-                }
+                } 
                 if ( previous == 0 && leftTuple.matchesSize() == 0 ) {
                     propagateModifyTuple( leftTuple,
                                           context,
@@ -334,7 +350,7 @@
                                            workingMemory );
                 }
 
-                tupleMatch = (TupleMatch) tupleMatch.getNext();
+                tupleMatch = (TupleMatch) nextTupleMatch;
             } else {
                 // no previous join, so attempt join now
                 final int previousSize = leftTuple.matchesSize();

Modified: labs/jbossrules/branches/3.0.x/drools-core/src/main/java/org/drools/reteoo/TerminalNode.java
===================================================================
--- labs/jbossrules/branches/3.0.x/drools-core/src/main/java/org/drools/reteoo/TerminalNode.java	2006-08-12 13:44:25 UTC (rev 5822)
+++ labs/jbossrules/branches/3.0.x/drools-core/src/main/java/org/drools/reteoo/TerminalNode.java	2006-08-12 14:13:27 UTC (rev 5823)
@@ -227,14 +227,18 @@
                             final PropagationContext context,
                             final ReteooWorkingMemory workingMemory) {
         // We have to remove and assert the new tuple as it has modified facts and thus its tuple is newer
-        if ( tuple.getActivation().isActivated() ) {
-            tuple.getActivation().remove();
+        boolean fireActivation = true;
+        Activation activation = tuple.getActivation();
+        
+        if ( activation.isActivated() ) {
+            activation.remove();
+            fireActivation = false;
         }
+
         assertTuple( tuple,
                      context,
                      workingMemory,
-                     false );
-
+                     fireActivation );
     }
 
     public String toString() {




More information about the jboss-svn-commits mailing list