[jboss-svn-commits] JBL Code SVN: r30949 - in labs/jbossrules/trunk: drools-compiler/src/test/java/org/drools/rule/builder/dialect/java and 5 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Tue Jan 5 14:10:57 EST 2010


Author: mark.proctor at jboss.com
Date: 2010-01-05 14:10:56 -0500 (Tue, 05 Jan 2010)
New Revision: 30949

Modified:
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/rule/builder/dialect/java/JavaDialectBinaryEqualityTest.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/QueryResult.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/QueryResults.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/mvel/MVELReturnValueExpression.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DisconnectedFactHandle.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/QueryTerminalNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooWorkingMemory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/MVELDialectRuntimeData.java
Log:
JBRULES-1432 Thread safe queries
-the query results are now effectively cloned before returning, wm is locked during this process.

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java	2010-01-05 19:05:51 UTC (rev 30948)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java	2010-01-05 19:10:56 UTC (rev 30949)
@@ -353,7 +353,11 @@
 
         // read in the source
         KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
-        kbuilder.add( ResourceFactory.newClassPathResource( "MVEL_soundex.drl", getClass() ), ResourceType.DRL );        
+        kbuilder.add( ResourceFactory.newClassPathResource( "MVEL_soundex.drl", getClass() ), ResourceType.DRL ); 
+        
+        if ( kbuilder.hasErrors() ) {
+            fail( kbuilder.getErrors().toString() );
+        }
 
         KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
         kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/rule/builder/dialect/java/JavaDialectBinaryEqualityTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/rule/builder/dialect/java/JavaDialectBinaryEqualityTest.java	2010-01-05 19:05:51 UTC (rev 30948)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/rule/builder/dialect/java/JavaDialectBinaryEqualityTest.java	2010-01-05 19:10:56 UTC (rev 30949)
@@ -72,7 +72,7 @@
         assertNotSame( pe1, pe3 );
         assertThat(pe1, not( equalTo( pe3 ) ) );
         
-       // test inline eval
+       // test eval
         EvalCondition ec1 = ( EvalCondition ) rule1.getLhs().getChildren().get( 1 );
         EvalExpression ee1 =( EvalExpression) ec1.getEvalExpression();
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/QueryResult.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/QueryResult.java	2010-01-05 19:05:51 UTC (rev 30948)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/QueryResult.java	2010-01-05 19:10:56 UTC (rev 30949)
@@ -19,6 +19,7 @@
 
 import org.drools.common.InternalFactHandle;
 import org.drools.common.InternalWorkingMemory;
+import org.drools.reteoo.LeftTuple;
 import org.drools.rule.Declaration;
 import org.drools.FactHandle;
 import org.drools.WorkingMemory;
@@ -26,14 +27,14 @@
 
 public class QueryResult {
 
-    protected Tuple       tuple;
+    protected FactHandle[] factHandles;
     private WorkingMemory workingMemory;
     private QueryResults  queryResults;
 
-    public QueryResult(final Tuple tuple,
+    public QueryResult(final FactHandle[] factHandles,
                        final WorkingMemory workingMemory,
                        final QueryResults queryResults) {
-        this.tuple = tuple;
+        this.factHandles = factHandles;
         this.workingMemory = workingMemory;
         this.queryResults = queryResults;
     }
@@ -57,8 +58,7 @@
      *     The Object
      */
     public Object get(final int i) {
-        //adjust for the DroolsQuery object
-        return getObject( this.tuple.get( i + 1 ));
+        return getObject( this.factHandles[ i ]);
     }
 
     /** 
@@ -78,31 +78,24 @@
      *      The Object
      */    
     public Object get(final Declaration declaration) {
-        return declaration.getValue( (InternalWorkingMemory) workingMemory, getObject( this.tuple.get( declaration ) ) );
+        return declaration.getValue( (InternalWorkingMemory) workingMemory, getObject( getFactHandle( declaration ) ) );
     }
     
     public FactHandle getFactHandle(String identifier) {
-        return this.tuple.get( ( Declaration ) this.queryResults.getDeclarations().get( identifier ) );
+        return getFactHandle( ( Declaration ) this.queryResults.getDeclarations().get( identifier ) );
     }
     
     public FactHandle getFactHandle(Declaration declr) {
-        return this.tuple.get( declr );
-    }    
+        return this.factHandles[  declr.getPattern().getOffset() -1 ]; // -1 because we shifted the array left
+                                                                       // when removing the query object
+    }     
 
     /**
      * Return the FactHandles for the Tuple.
      * @return
      */
     public FactHandle[] getFactHandles() {
-        // Strip the DroolsQuery fact
-        final FactHandle[] src = this.tuple.getFactHandles();
-        final FactHandle[] dst = new FactHandle[src.length - 1];
-        System.arraycopy( src,
-                          1,
-                          dst,
-                          0,
-                          dst.length );
-        return dst;
+        return this.factHandles;
     }
 
     /**
@@ -110,8 +103,7 @@
      * @return
      */
     public int size() {
-        // Adjust for the DroolsQuery object
-        return this.tuple.getFactHandles().length - 1;
+        return this.factHandles.length;
     }
     
     /**

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/QueryResults.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/QueryResults.java	2010-01-05 19:05:51 UTC (rev 30948)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/QueryResults.java	2010-01-05 19:10:56 UTC (rev 30949)
@@ -51,7 +51,7 @@
         if ( i > this.results.size() ) {
             throw new NoSuchElementException();
         }
-        return new QueryResult( (Tuple) this.results.get( i ),
+        return new QueryResult( (FactHandle[]) this.results.get( i ),
                                 this.workingMemory,
                                 this );
     }
@@ -107,7 +107,7 @@
         }
 
         public Object next() {
-            return new QueryResult( (Tuple) this.iterator.next(),
+            return new QueryResult( (FactHandle[]) this.iterator.next(),
                                     QueryResults.this.workingMemory,
                                     QueryResults.this );
         }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/mvel/MVELReturnValueExpression.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/mvel/MVELReturnValueExpression.java	2010-01-05 19:05:51 UTC (rev 30948)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/mvel/MVELReturnValueExpression.java	2010-01-05 19:10:56 UTC (rev 30949)
@@ -41,15 +41,11 @@
     public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
         id = in.readUTF();
         unit = ( MVELCompilationUnit ) in.readObject();
-//        expr    = (Serializable)in.readObject();
-//        prototype   = (DroolsMVELFactory)in.readObject();
     }
 
     public void writeExternal(ObjectOutput out) throws IOException {
         out.writeUTF( id );
         out.writeObject( unit );
-//        out.writeObject(expr);
-//        out.writeObject(prototype);
     }
     
     public void compile(ClassLoader classLoader) {
@@ -89,6 +85,35 @@
     
     public String toString() {
         return this.unit.getExpression();
-    }    
+    }
 
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        if ( expr == null ) {
+            throw new RuntimeException("this MVELReturnValueExpression must be compiled for hashCode");
+        }        
+        result = prime * result + unit.getExpression().hashCode();
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if ( this == obj ) return true;
+        if ( obj == null ) return false;
+        if ( getClass() != obj.getClass() ) return false;
+        
+        if ( expr == null ) {
+            throw new RuntimeException("this MVELReturnValueExpression must be compiled for equality");
+        }
+        
+        MVELReturnValueExpression other = (MVELReturnValueExpression) obj;
+        if ( other.expr == null ) {
+            throw new RuntimeException("other MVELReturnValueExpression must be compiled for equality");
+        }
+        
+        return this.expr.equals( other.expr );
+    } 
+
 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DisconnectedFactHandle.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DisconnectedFactHandle.java	2010-01-05 19:05:51 UTC (rev 30948)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DisconnectedFactHandle.java	2010-01-05 19:10:56 UTC (rev 30949)
@@ -12,10 +12,20 @@
     private int  identityHashCode;
     private int  objectHashCode;
     private long recency;
+    private Object object;
 
     public DisconnectedFactHandle(int id,
                                   int identityHashCode,
                                   int objectHashCode,
+                                  long recency,
+                                  Object object) {
+        this( id, identityHashCode, objectHashCode, recency );
+        this.object = object;
+    }    
+
+    public DisconnectedFactHandle(int id,
+                                  int identityHashCode,
+                                  int objectHashCode,
                                   long recency) {
         this.id = id;
         this.identityHashCode = identityHashCode;
@@ -56,6 +66,9 @@
     }
 
     public Object getObject() {
+        if ( this.object != null ) {
+            return this.object;
+        }
         throw new UnsupportedOperationException( "DisonnectedFactHandle does not support this method" );
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/QueryTerminalNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/QueryTerminalNode.java	2010-01-05 19:05:51 UTC (rev 30948)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/QueryTerminalNode.java	2010-01-05 19:10:56 UTC (rev 30949)
@@ -21,8 +21,11 @@
 import java.io.ObjectOutput;
 import java.util.LinkedList;
 
+import org.drools.FactHandle;
 import org.drools.RuleBaseConfiguration;
 import org.drools.common.BaseNode;
+import org.drools.common.DisconnectedFactHandle;
+import org.drools.common.InternalFactHandle;
 import org.drools.common.InternalWorkingMemory;
 import org.drools.common.NodeMemory;
 import org.drools.common.PropagationContextImpl;
@@ -148,7 +151,18 @@
             ((ReteooWorkingMemory) workingMemory).setQueryResults( this.rule.getName(),
                                                                    this );
         }
-        list.add( tuple );
+        
+        InternalFactHandle[] handles = new InternalFactHandle[tuple.getIndex()]; // don't add one, as we adjust for root Query object
+        LeftTuple entry = tuple;
+  
+        // miss out 0, which is the DroolsQuery object
+        while ( entry.getIndex() != 0 ) { 
+            InternalFactHandle handle  = entry.getLastHandle();
+            handles[entry.getIndex() - 1] = new DisconnectedFactHandle(handle.getId(), handle.getIdentityHashCode(), handle.getObjectHashCode(), handle.getRecency(), handle.getObject() );
+            entry = entry.getParent();
+        }
+        
+        list.add( handles );   
     }
 
     public void retractLeftTuple(final LeftTuple tuple,

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooWorkingMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooWorkingMemory.java	2010-01-05 19:05:51 UTC (rev 30948)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooWorkingMemory.java	2010-01-05 19:10:56 UTC (rev 30949)
@@ -135,6 +135,8 @@
 
         try {
             startOperation();
+            this.ruleBase.readLock();
+            this.lock.lock();            
             Object object = new DroolsQuery( query,
                                              arguments );
             InternalFactHandle handle = this.handleFactory.newFactHandle( object,
@@ -187,6 +189,8 @@
                                      queryObj,
                                      this );
         } finally {
+            this.lock.unlock();
+            this.ruleBase.readUnlock();            
             endOperation();
         }
     }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/MVELDialectRuntimeData.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/MVELDialectRuntimeData.java	2010-01-05 19:05:51 UTC (rev 30948)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/MVELDialectRuntimeData.java	2010-01-05 19:10:56 UTC (rev 30949)
@@ -7,6 +7,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.IdentityHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -30,7 +31,7 @@
 
     public MVELDialectRuntimeData() {
         this.functionFactory = new MapFunctionResolverFactory();
-        invokerLookups = new HashMap<Wireable, MVELCompileable>();
+        invokerLookups = new IdentityHashMap<Wireable, MVELCompileable>();
     }
 
     public void writeExternal(ObjectOutput out) throws IOException {



More information about the jboss-svn-commits mailing list