[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