[jboss-svn-commits] JBL Code SVN: r36534 - labs/jbossrules/soa_branches/BRMS-5.0.2-GA_BRMS-532_BRMS-533/drools-core/src/main/java/org/drools/base.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Fri Jan 14 15:57:24 EST 2011
Author: tsurdilovic
Date: 2011-01-14 15:57:24 -0500 (Fri, 14 Jan 2011)
New Revision: 36534
Modified:
labs/jbossrules/soa_branches/BRMS-5.0.2-GA_BRMS-532_BRMS-533/drools-core/src/main/java/org/drools/base/ClassFieldAccessorCache.java
Log:
BRMS-535: Fix for BRMS-532 and BRMS-533
Modified: labs/jbossrules/soa_branches/BRMS-5.0.2-GA_BRMS-532_BRMS-533/drools-core/src/main/java/org/drools/base/ClassFieldAccessorCache.java
===================================================================
--- labs/jbossrules/soa_branches/BRMS-5.0.2-GA_BRMS-532_BRMS-533/drools-core/src/main/java/org/drools/base/ClassFieldAccessorCache.java 2011-01-14 20:55:53 UTC (rev 36533)
+++ labs/jbossrules/soa_branches/BRMS-5.0.2-GA_BRMS-532_BRMS-533/drools-core/src/main/java/org/drools/base/ClassFieldAccessorCache.java 2011-01-14 20:57:24 UTC (rev 36534)
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package org.drools.base;
import java.security.ProtectionDomain;
@@ -4,208 +20,50 @@
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.util.asm.ClassFieldInspector;
+import org.drools.core.util.asm.ClassFieldInspector;
public class ClassFieldAccessorCache {
- private static ClassFieldAccessorCache instance;
- private Map<ClassLoader, CacheEntry> cacheByClassLoader;
+ private Map<ClassLoader, CacheEntry> cacheByClassLoader;
- private ClassLoader classLoader;
+ private ClassLoader classLoader;
- // private boolean eagerWire;
-
- // public static ClassFieldAccessorCache getInstance() {
- // if ( instance == null ) {
- // ClassLoader cl = Thread.currentThread().getContextClassLoader();
- // if ( cl == null ) {
- // cl = ClassFieldAccessorCache.class.getClassLoader();
- // }
- // instance = new ClassFieldAccessorCache( cl );
- // }
- //
- // return instance;
- // }
- //
- // public ClassFieldAccessorCache() {
- // // we don't set the classloader here, its just for Externalisable
- // // any using class will need to set the classloader before using
- // this( null );
- // }
-
public ClassFieldAccessorCache(ClassLoader classLoader) {
// lookup = new HashMap<AccessorKey, LookupEntry>();
cacheByClassLoader = new WeakHashMap<ClassLoader, CacheEntry>();
this.classLoader = classLoader;
}
- // public void writeExternal(ObjectOutput out) throws IOException {
- // out.writeObject( lookup );
- //
- // }
- //
- // public void readExternal(ObjectInput in) throws IOException,
- // ClassNotFoundException {
- // lookup = ( Map<AccessorKey, LookupEntry> ) in.readObject();
- // }
-
- public void setClassLoader(ClassLoader classLoader) {
- this.classLoader = classLoader;
- }
-
public ClassLoader getClassLoader() {
return this.classLoader;
}
- // public void setEagerWire(boolean eagerWire) {
- // this.eagerWire = eagerWire;
- // }
- //
- // public ClassFieldWriter getWriter(Class cls,
- // String fieldName,
- // ClassLoader classLoader) {
- // // return getReader( cls.getName(),
- // // fieldName,
- // // null );
- // return null;
- // }
- //
- // public ClassFieldReader getReader(Class cls,
- // String fieldName,
- // ClassLoader classLoader) {
- // return getReader( cls.getName(),
- // fieldName,
- // null );
- // }
- //
- // public synchronized ClassFieldReader getReader(final String className,
- // final String fieldName,
- // final AcceptsReadAccessor target) {
- // AccessorKey key = new AccessorKey( className,
- // fieldName );
- // LookupEntry entry = this.lookup.get( key );
- // if ( entry == null ) {
- // entry = new LookupEntry( new ClassFieldReader( className,
- // fieldName ) );
- // }
- //
- // if ( target != null ) {
- // entry.addReadAccessorTargets( target );
- // }
- //
- // if ( this.eagerWire ) {
- // wire( entry.getClassFieldReader() );
- // }
- //
- // return entry.getClassFieldReader();
- // }
- //
- // public synchronized ClassFieldWriter getWriter(final String className,
- // final String fieldName,
- // final AcceptsWriteAccessor target) {
- // AccessorKey key = new AccessorKey( className,
- // fieldName );
- // LookupEntry entry = this.lookup.get( key );
- // if ( entry == null ) {
- // entry = new LookupEntry( new ClassFieldWriter( className,
- // fieldName ) );
- // if ( target != null ) {
- // //entry.addReadAccessorTargets( target );
- // }
- // }
- //
- // if ( this.eagerWire ) {
- // wire( entry.getClassFieldReader() );
- // }
- //
- // return entry.getClassFieldWriter();
- // }
- //
- // public void merge(ClassFieldAccessorCache other) {
- // for ( Entry<AccessorKey, LookupEntry> entry : other.lookup.entrySet() ) {
- // LookupEntry lookupEntry = this.lookup.get( entry.getKey() );
- // if ( lookupEntry == null ) {
- // // ClassFieldReader does not exist here, so copy in everything.
- // this.lookup.put( entry.getKey(),
- // entry.getValue() );
- // } else {
- // // iterate through new constraints adding them and wiring them up
- // // to the existing ClassFieldReader
- // for ( AcceptsReadAccessor target : entry.getValue().getReadAccessorTargets() ) {
- // target.setReadAccessor( lookupEntry.getClassFieldReader() );
- // lookupEntry.addReadAccessorTargets( target );
- // }
- // }
- // }
- // }
- //
- // public void wire() {
- // for ( Entry<AccessorKey, LookupEntry> entry : lookup.entrySet() ) {
- // wire( entry.getValue().getClassFieldReader() );
- // }
- // }
- //
- // public void wire(ClassFieldReader reader) {
- // reader.setReadAccessor( getReadAcessor( reader ) );
- // }
- //
- // public void wire(ClassFieldWriter writer) {
- // writer.setWriteAccessor( getWriteAcessor( writer ) );
- // }
- //
- // public ClassFieldAccessor getAccessor(Class cls,
- // String fieldName,
- // ClassLoader classLoader) {
- // return getAccessor( cls.getName(),
- // fieldName,
- // null );
- // }
- //
- // public ClassFieldAccessor getAccessor(final String className,
- // final String fieldName,
- // final AcceptsReadAccessor target) {
- // AccessorKey key = new AccessorKey( className,
- // fieldName );
- // LookupEntry entry = this.lookup.get( key );
- // if ( entry == null ) {
- // entry = new LookupEntry( new ClassFieldReader( className,
- // fieldName ),
- // new ClassFieldWriter( className,
- // fieldName ) );
- // if ( target != null ) {
- // entry.addReadAccessorTargets( target );
- // }
- // }
- //
- // if ( this.eagerWire ) {
- // wire( entry.getClassFieldReader() );
- // wire( entry.getClassFieldWriter() );
- // }
- //
- // return new ClassFieldAccessor( entry.getClassFieldReader(),
- // entry.getClassFieldWriter() );
- // }
-
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;
}
@@ -230,8 +88,6 @@
return true;
}
-
-
}
public BaseClassFieldReader getReadAcessor(ClassFieldReader reader) {
@@ -251,51 +107,48 @@
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 != null ) ?
- this.classLoader :
- ClassLoader.getSystemClassLoader();
+ ClassLoader cl = cls.getClassLoader() != null ? cls.getClassLoader() : this.classLoader;
CacheEntry cache = this.cacheByClassLoader.get( cl );
if ( cache == null ) {
// setup a cache for this ClassLoader
- cache = new CacheEntry( cl );
+ cache = new CacheEntry( this.classLoader );
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 ) {
@@ -303,7 +156,7 @@
}
this.byteArrayClassLoader = new ByteArrayClassLoader( parentClassLoader );
}
-
+
public ByteArrayClassLoader getByteArrayClassLoader() {
return byteArrayClassLoader;
}
@@ -315,8 +168,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;
@@ -324,34 +181,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;
}
}
More information about the jboss-svn-commits
mailing list