[jboss-svn-commits] JBL Code SVN: r33708 - in labs/jbossrules/trunk/drools-core/src/main/java/org/drools: common and 1 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed Jun 30 11:59:07 EDT 2010


Author: tirelli
Date: 2010-06-30 11:59:07 -0400 (Wed, 30 Jun 2010)
New Revision: 33708

Modified:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ClassFieldAccessorCache.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/ObjectTypeConfigurationRegistry.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EntryPointNode.java
Log:
JBRULES-2346: fixing concurrency problems

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ClassFieldAccessorCache.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ClassFieldAccessorCache.java	2010-06-30 15:27:47 UTC (rev 33707)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/ClassFieldAccessorCache.java	2010-06-30 15:59:07 UTC (rev 33708)
@@ -4,17 +4,18 @@
 import java.util.HashMap;
 import java.util.Map;
 import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 
 import org.drools.RuntimeDroolsException;
 import org.drools.core.util.asm.ClassFieldInspector;
 
 public class ClassFieldAccessorCache {
 
-    private Map<ClassLoader, CacheEntry>   cacheByClassLoader;
+    private Map<ClassLoader, CacheEntry> cacheByClassLoader;
 
-    private ClassLoader                    classLoader;
+    private ClassLoader                  classLoader;
 
-
     public ClassFieldAccessorCache(ClassLoader classLoader) {
         //        lookup = new HashMap<AccessorKey, LookupEntry>();
         cacheByClassLoader = new WeakHashMap<ClassLoader, CacheEntry>();
@@ -28,25 +29,29 @@
     public ClassLoader getClassLoader() {
         return this.classLoader;
     }
-    
+
     public ClassObjectType getClassObjectType(ClassObjectType objectType) {
         // always lookup the class, as the ClassObjectType might refer to the class from another ClassLoader
         Class cls = getClass( objectType.getClassName() );
         CacheEntry cache = getCacheEntry( cls );
-        return cache.getClassObjectType( cls, objectType );                
+        return cache.getClassObjectType( cls,
+                                         objectType );
     }
-    
+
     public static class ClassObjectTypeKey {
-        private Class cls;
+        private Class   cls;
         private boolean event;
+
         public ClassObjectTypeKey(Class cls,
                                   boolean event) {
             this.cls = cls;
             this.event = event;
         }
+
         public Class getCls() {
             return cls;
         }
+
         public boolean isEvent() {
             return event;
         }
@@ -71,8 +76,6 @@
             return true;
         }
 
-        
-        
     }
 
     public BaseClassFieldReader getReadAcessor(ClassFieldReader reader) {
@@ -92,29 +95,28 @@
     public BaseClassFieldWriter getWriteAcessor(ClassFieldWriter writer) {
         String className = writer.getClassName();
         String fieldName = writer.getFieldName();
-        
+
         Class cls = getClass( className );
         CacheEntry cache = getCacheEntry( cls );
-        
+
         // get the ReaderAccessor for this key
         return cache.getWriteAccessor( new AccessorKey( className,
                                                         fieldName,
                                                         AccessorKey.AccessorType.FieldAccessor ),
                                        cls );
     }
-    
-    public Class getClass(String className) { 
+
+    public Class getClass(String className) {
         try {
             return this.classLoader.loadClass( className );
         } catch ( ClassNotFoundException e ) {
             throw new RuntimeDroolsException( "Unable to resolve class '" + className + "'" );
         }
-    }    
-        
+    }
+
     public CacheEntry getCacheEntry(Class cls) {
         // System classloader classes return null on some JVMs
-        ClassLoader cl = cls.getClassLoader() != null ? 
-        		         cls.getClassLoader() : this.classLoader;
+        ClassLoader cl = cls.getClassLoader() != null ? cls.getClassLoader() : this.classLoader;
 
         CacheEntry cache = this.cacheByClassLoader.get( cl );
         if ( cache == null ) {
@@ -123,18 +125,18 @@
             this.cacheByClassLoader.put( cl,
                                          cache );
         }
-        
+
         return cache;
     }
 
     public static class CacheEntry {
-        private ByteArrayClassLoader                         byteArrayClassLoader;
-        private final Map<AccessorKey, BaseClassFieldReader> readCache   = new HashMap<AccessorKey, BaseClassFieldReader>();
-        private final Map<AccessorKey, BaseClassFieldWriter> writeCache  = new HashMap<AccessorKey, BaseClassFieldWriter>();
+        private ByteArrayClassLoader                                     byteArrayClassLoader;
+        private final ConcurrentMap<AccessorKey, BaseClassFieldReader>   readCache   = new ConcurrentHashMap<AccessorKey, BaseClassFieldReader>();
+        private final ConcurrentMap<AccessorKey, BaseClassFieldWriter>   writeCache  = new ConcurrentHashMap<AccessorKey, BaseClassFieldWriter>();
 
-        private final Map<Class< ? >, ClassFieldInspector>   inspectors  = new HashMap<Class< ? >, ClassFieldInspector>();
+        private final ConcurrentMap<Class< ? >, ClassFieldInspector>     inspectors  = new ConcurrentHashMap<Class< ? >, ClassFieldInspector>();
 
-        private final Map<ClassObjectTypeKey, ClassObjectType>       objectTypes = new HashMap<ClassObjectTypeKey, ClassObjectType>();
+        private final ConcurrentMap<ClassObjectTypeKey, ClassObjectType> objectTypes = new ConcurrentHashMap<ClassObjectTypeKey, ClassObjectType>();
 
         public CacheEntry(ClassLoader parentClassLoader) {
             if ( parentClassLoader == null ) {
@@ -142,7 +144,7 @@
             }
             this.byteArrayClassLoader = new ByteArrayClassLoader( parentClassLoader );
         }
-        
+
         public ByteArrayClassLoader getByteArrayClassLoader() {
             return byteArrayClassLoader;
         }
@@ -154,8 +156,12 @@
                 reader = ClassFieldAccessorFactory.getInstance().getClassFieldReader( cls,
                                                                                       key.getFieldName(),
                                                                                       this );
-                this.readCache.put( key,
-                                    reader );
+                BaseClassFieldReader existingReader = this.readCache.putIfAbsent( key,
+                                                                                  reader );
+                if ( existingReader != null ) {
+                    // Raced, use the (now) existing entry
+                    reader = existingReader;
+                }
             }
 
             return reader;
@@ -163,34 +169,42 @@
 
         public BaseClassFieldWriter getWriteAccessor(AccessorKey key,
                                                      Class cls) {
-            BaseClassFieldWriter reader = this.writeCache.get( key );
-            if ( reader == null ) {
-                reader = ClassFieldAccessorFactory.getInstance().getClassFieldWriter( cls,
+            BaseClassFieldWriter writer = this.writeCache.get( key );
+            if ( writer == null ) {
+                writer = ClassFieldAccessorFactory.getInstance().getClassFieldWriter( cls,
                                                                                       key.getFieldName(),
                                                                                       this );
-                this.writeCache.put( key,
-                                     reader );
+                BaseClassFieldWriter existingWriter = this.writeCache.putIfAbsent( key,
+                                                                                   writer );
+                if ( existingWriter != null ) {
+                    // Raced, use the (now) existing entry
+                    writer = existingWriter;
+                }
             }
 
-            return reader;
+            return writer;
         }
 
         public Map<Class< ? >, ClassFieldInspector> getInspectors() {
             return inspectors;
         }
-        
-        public ClassObjectType getClassObjectType(Class cls, ClassObjectType objectType) {
-            ClassObjectTypeKey key = new ClassObjectTypeKey(cls, objectType.isEvent() );            
+
+        public ClassObjectType getClassObjectType(Class<?> cls,
+                                                  ClassObjectType objectType) {
+            ClassObjectTypeKey key = new ClassObjectTypeKey( cls,
+                                                             objectType.isEvent() );
             ClassObjectType existing = objectTypes.get( key );
-            
-            if ( existing != null ) {
-                objectType = existing;
-            } else {
+
+            if ( existing == null ) {
                 objectType.setClassType( cls ); // most likely set, but set anyway.
-                objectTypes.put(  key, objectType );
+                existing = objectTypes.putIfAbsent( key, objectType );
+                if ( existing == null ) {
+                    // Not raced, use the one we created.
+                    existing = objectType;
+                }
             }
-            
-            return objectType;            
+
+            return existing;
         }
 
     }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/ObjectTypeConfigurationRegistry.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/ObjectTypeConfigurationRegistry.java	2010-06-30 15:27:47 UTC (rev 33707)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/ObjectTypeConfigurationRegistry.java	2010-06-30 15:59:07 UTC (rev 33708)
@@ -39,14 +39,8 @@
         
         // first see if it's a ClassObjectTypeConf        
         ObjectTypeConf objectTypeConf = null;
-        Class<?> cls = null;
-        if ( object instanceof Fact ) {
-            String key = ((Fact) object).getFactTemplate().getName();
-            objectTypeConf = (ObjectTypeConf) this.typeConfMap.get( key );            
-        } else {
-            cls = object.getClass();
-            objectTypeConf = this.typeConfMap.get( cls );            
-        }                       
+        Object key = ( object instanceof Fact ) ? ((Fact) object).getFactTemplate().getName() : object.getClass();
+        objectTypeConf = this.typeConfMap.get( key );            
         
         // it doesn't exist, so create it.
         if ( objectTypeConf == null ) {
@@ -54,16 +48,17 @@
                 objectTypeConf = new FactTemplateTypeConf( entrypoint,
                                                            ((Fact) object).getFactTemplate(),
                                                            this.ruleBase );           
-                this.typeConfMap.put( ((Fact) object).getFactTemplate().getName(), 
-                                      objectTypeConf );
             } else {
                 objectTypeConf = new ClassObjectTypeConf( entrypoint,
-                                                          cls,
+                                                          (Class<?>) key,
                                                           this.ruleBase );
-                this.typeConfMap.put( cls, objectTypeConf );
             }            
         }
-
+        ObjectTypeConf existing = this.typeConfMap.putIfAbsent( key, objectTypeConf );
+        if ( existing != null ) {
+            // Raced, take the (now) existing.
+            objectTypeConf = existing;
+        }
         return objectTypeConf;
     }
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EntryPointNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EntryPointNode.java	2010-06-30 15:27:47 UTC (rev 33707)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/EntryPointNode.java	2010-06-30 15:59:07 UTC (rev 33708)
@@ -24,6 +24,7 @@
 import java.io.ObjectOutput;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.drools.base.ShadowProxy;
 import org.drools.common.BaseNode;
@@ -101,7 +102,7 @@
                objectSource,
                999 ); // irrelevant for this node, since it overrides sink management
         this.entryPoint = entryPoint;
-        this.objectTypeNodes = new HashMap<ObjectType, ObjectTypeNode>();
+        this.objectTypeNodes = new ConcurrentHashMap<ObjectType, ObjectTypeNode>();
     }
 
     // ------------------------------------------------------------



More information about the jboss-svn-commits mailing list