How about just assigning cl = ClassLoader.getSystemClassLoader()
(which will hopefully never be null) when cl is null?
On Feb 27, 2007, at 7:29 AM, Patrick Linskey wrote:
> Hi,
>
> I was just looking at ObjectValue, and noticed something odd in the
> code
> snippet below. It looks like if cl is null, we will end up with
> constant
> cache misses. So, outside a container, we'll always be doing the extra
> cache overhead, and will never get any benefit from doing so.
>
> Should we put some sort of placeholder in place for 'cl' when it's
> null
> to disambiguate?
>
> -Patrick
>
>> - public Object newInstance(String clsName, Class type,
>> - Configuration conf, boolean fatal) {
>> - return Configurations.newInstance(clsName, this, conf,
>> - type.getClassLoader(), fatal);
>> + public Object newInstance(String clsName, Class type,
>> Configuration conf,
>> + boolean fatal) {
>> + ClassLoader cl = (ClassLoader) _classloaderCache.get(type);
>> + if (cl == null) {
>> + cl = type.getClassLoader();
>> + if (cl != null) { // System classloader is
>> returned as null
>> + _classloaderCache.put(type, cl);
>> + }
>> + }
>> + return Configurations.newInstance(clsName, this,
>> conf, cl, fatal);
>> }
>
> --
> Patrick Linskey
> BEA Systems, Inc.
>
> ______________________________________________________________________
> _
> Notice: This email message, together with any attachments, may
> contain
> information of BEA Systems, Inc., its subsidiaries and
> affiliated
> entities, that may be confidential, proprietary, copyrighted
> and/or
> legally privileged, and is intended solely for the use of the
> individual
> or entity named in this message. If you are not the intended
> recipient,
> and have received this message in error, please immediately return
> this
> by email and then delete it.
>
>> -----Original Message-----
>> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
>> Sent: Sunday, February 11, 2007 6:33 PM
>> To: open-jpa-commits@incubator.apache.org
>> Subject: svn commit: r506230 - in /incubator/openjpa/trunk:
>> openjpa-kernel/src/main/java/org/apache/openjpa/ee/
>> openjpa-kernel/src/main/java/org/apache/openjpa/kernel/
>> openjpa-kernel/src/main/java/org/apache/openjpa/util/
>> openjpa-kernel/src/main/resources/org/a...
>>
>> Author: kwsutter
>> Date: Sun Feb 11 18:33:05 2007
>> New Revision: 506230
>>
>> URL: http://svn.apache.org/viewvc?view=rev&rev=506230
>> Log:
>> OPENJPA-138. Some updates to help with performance of
>> OpenJPA in an application server environment. Details can be
>> found in the OPENJPA-138 Issue.
>>
>> Modified:
>>
>> incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apach
> e/openjpa/ee/JNDIManagedRuntime.java
>>
>> incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apach
> e/openjpa/kernel/AbstractBrokerFactory.java
>>
>> incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apach
> e/openjpa/kernel/BrokerImpl.java
>>
>> incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apach
> e/openjpa/kernel/FetchConfigurationImpl.java
>>
>> incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apach
> e/openjpa/util/OpenJPAId.java
>>
>> incubator/openjpa/trunk/openjpa-kernel/src/main/resources/org/
> apache/openjpa/kernel/localizer.properties
>>
>> incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/o
> penjpa/lib/conf/ObjectValue.java
>>
>> Modified:
>> incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apach
> e/openjpa/ee/JNDIManagedRuntime.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-k
> ernel/src/main/java/org/apache/openjpa/ee/JNDIManagedRuntime.java?>
> view=diff&rev=506230&r1=506229&r2=506230
>> ==============================================================
>> ================
>> ---
>> incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apach
> e/openjpa/ee/JNDIManagedRuntime.java (original)
>> +++
>> incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apach
> e/openjpa/ee/JNDIManagedRuntime.java Sun Feb 11 18:33:05 2007
>> @@ -29,6 +29,7 @@
>> implements ManagedRuntime {
>>
>> private String _tmLoc = "java:/TransactionManager";
>> + private static TransactionManager _tm;
>>
>> /**
>> * Return the location of the [EMAIL PROTECTED] TransactionManager} in
>> JNDI.
>> @@ -44,13 +45,18 @@
>> _tmLoc = name;
>> }
>>
>> - public TransactionManager getTransactionManager()
>> - throws Exception {
>> - Context ctx = new InitialContext();
>> - try {
>> - return (TransactionManager) ctx.lookup(_tmLoc);
>> - } finally {
>> - ctx.close();
>> + /**
>> + * Return the cached TransactionManager instance.
>> + */
>> + public TransactionManager getTransactionManager() throws
>> Exception {
>> + if (_tm == null) {
>> + Context ctx = new InitialContext();
>> + try {
>> + _tm = (TransactionManager) ctx.lookup(_tmLoc);
>> + } finally {
>> + ctx.close();
>> + }
>> }
>> - }
>> + return _tm;
>> + }
>> }
>>
>> Modified:
>> incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apach
> e/openjpa/kernel/AbstractBrokerFactory.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-k
> ernel/src/main/java/org/apache/openjpa/kernel/
> AbstractBrokerFactory.java
> ?> view=diff&rev=506230&r1=506229&r2=506230
>> ==============================================================
>> ================
>> ---
>> incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apach
> e/openjpa/kernel/AbstractBrokerFactory.java (original)
>> +++
>> incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apach
> e/openjpa/kernel/AbstractBrokerFactory.java Sun Feb 11 18:33:05 2007
>> @@ -64,7 +64,8 @@
>> // configuration
>> private final OpenJPAConfiguration _conf;
>> private transient boolean _readOnly = false;
>> - private transient RuntimeException _closed = null;
>> + private transient boolean _closed = false;
>> + private transient RuntimeException _closedException = null;
>> private Map _userObjects = null;
>>
>> // internal lock: spec forbids synchronization on this object
>> @@ -267,7 +268,7 @@
>> * Returns true if this broker factory is closed.
>> */
>> public boolean isClosed() {
>> - return _closed != null;
>> + return _closed;
>> }
>>
>> public void close() {
>> @@ -297,7 +298,10 @@
>> (_conf.getMetaDataRepositoryInstance());
>>
>> _conf.close();
>> - _closed = new IllegalStateException();
>> + _closed = true;
>> + Log log = _conf.getLog
>> (OpenJPAConfiguration.LOG_RUNTIME);
>> + if (log.isTraceEnabled())
>> + _closedException = new IllegalStateException();
>> } finally {
>> unlock();
>> }
>> @@ -546,12 +550,18 @@
>> }
>>
>> /**
>> - * Throw an exception if the factory is closed.
>> + * Throw an exception if the factory is closed. The
>> exact message and
>> + * content of the exception varies whether TRACE is
>> enabled or not.
>> */
>> private void assertOpen() {
>> - if (_closed != null)
>> - throw new
>> InvalidStateException(_loc.get("closed-factory")).
>> - setCause(_closed);
>> + if (_closed) {
>> + if (_closedException == null) // TRACE not enabled
>> + throw new InvalidStateException(_loc
>> + .get("closed-factory-notrace"));
>> + else
>> + throw new
>> InvalidStateException(_loc.get("closed-factory"))
>> + .setCause(_closedException);
>> + }
>> }
>>
>> ////////////////////
>>
>> Modified:
>> incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apach
> e/openjpa/kernel/BrokerImpl.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-k
> ernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java?>
> view=diff&rev=506230&r1=506229&r2=506230
>> ==============================================================
>> ================
>> ---
>> incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apach
> e/openjpa/kernel/BrokerImpl.java (original)
>> +++
>> incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apach
> e/openjpa/kernel/BrokerImpl.java Sun Feb 11 18:33:05 2007
>> @@ -63,6 +63,7 @@
>> import org.apache.openjpa.lib.util.ReferenceHashMap;
>> import org.apache.openjpa.lib.util.ReferenceHashSet;
>> import org.apache.openjpa.lib.util.ReferenceMap;
>> +import
>> org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap;
>> import org.apache.openjpa.lib.util.concurrent.ReentrantLock;
>> import org.apache.openjpa.meta.ClassMetaData;
>> import org.apache.openjpa.meta.FieldMetaData;
>> @@ -138,6 +139,9 @@
>>
>> private static final Localizer _loc =
>> Localizer.forPackage(BrokerImpl.class);
>> + // Cache for from/to type assignments
>> + private static ConcurrentReferenceHashMap _assignableTypes =
>> + new ConcurrentReferenceHashMap(ReferenceMap.HARD,
>> ReferenceMap.WEAK);
>>
>> // the store manager in use; this may be a
>> decorator such as a
>> // data cache store manager around the native store manager
>> @@ -215,7 +219,8 @@
>>
>> // status
>> private int _flags = 0;
>> - private RuntimeException _closed = null;
>> + private boolean _closed = false;
>> + private RuntimeException _closedException = null;
>>
>> // event managers
>> private TransactionEventManager _transEventManager = null;
>> @@ -1096,8 +1101,7 @@
>> cls));
>> return PCRegistry.newObjectId(cls, (String) val);
>> }
>> -
>> - if
>> (meta.getObjectIdType().isAssignableFrom(val.getClass())) {
>> + if (isAssignable(meta.getObjectIdType(),
>> val.getClass())) {
>> if (!meta.isOpenJPAIdentity() &&
>> meta.isObjectIdTypeShared())
>> return new ObjectId(cls, val);
>> return val;
>> @@ -1119,6 +1123,37 @@
>> }
>>
>> /**
>> + * Cache from/to assignments to avoid
>> Class.isAssignableFrom overhead
>> + * @param from the target Class
>> + * @param to the Class to test
>> + * @return true if the "to" class could be assigned to
>> "from" class
>> + */
>> + private boolean isAssignable(Class from, Class to) {
>> + boolean isAssignable;
>> + ConcurrentReferenceHashMap assignableTo =
>> + (ConcurrentReferenceHashMap) _assignableTypes.get(from);
>> +
>> + if (assignableTo != null) { // "to" cache exists...
>> + isAssignable = (assignableTo.get(to) != null);
>> + if (!isAssignable) { // not in the map yet...
>> + isAssignable = from.isAssignableFrom(to);
>> + if (isAssignable) {
>> + assignableTo.put(to, new Object());
>> + }
>> + }
>> + } else { // no "to" cache yet...
>> + isAssignable = from.isAssignableFrom(to);
>> + if (isAssignable) {
>> + assignableTo = new ConcurrentReferenceHashMap(
>> + ReferenceMap.HARD, ReferenceMap.WEAK);
>> + _assignableTypes.put(from, assignableTo);
>> + assignableTo.put(to, new Object());
>> + }
>> + }
>> + return isAssignable;
>> + }
>> +
>> + /**
>> * Create a new state manager for the given oid.
>> */
>> private StateManagerImpl newStateManagerImpl(Object oid,
>> boolean copy) {
>> @@ -3969,11 +4004,11 @@
>> ///////////
>>
>> public boolean isClosed() {
>> - return _closed != null;
>> + return _closed;
>> }
>>
>> public boolean isCloseInvoked() {
>> - return _closed != null || (_flags & FLAG_CLOSE_INVOKED) !
>> = 0;
>> + return _closed || (_flags & FLAG_CLOSE_INVOKED) != 0;
>> }
>>
>> public void close() {
>> @@ -4055,8 +4090,10 @@
>>
>> _lm.close();
>> _store.close();
>> - _closed = new IllegalStateException();
>> _flags = 0;
>> + _closed = true;
>> + if (_log.isTraceEnabled())
>> + _closedException = new IllegalStateException();
>>
>> if (err != null)
>> throw err;
>> @@ -4246,11 +4283,19 @@
>> /////////
>> // Utils
>> /////////
>> -
>> + /**
>> + * Throw an exception if the context is closed. The
>> exact message and
>> + * content of the exception varies whether TRACE is
>> enabled or not.
>> + */
>> public void assertOpen() {
>> - if (_closed != null)
>> - throw new
>> InvalidStateException(_loc.get("closed"), _closed).
>> - setFatal(true);
>> + if (_closed) {
>> + if (_closedException == null) // TRACE not enabled
>> + throw new
>> InvalidStateException(_loc.get("closed-notrace"))
>> + .setFatal(true);
>> + else
>> + throw new InvalidStateException(_loc.get("closed"),
>> + _closedException).setFatal(true);
>> + }
>> }
>>
>> public void assertActiveTransaction() {
>>
>> Modified:
>> incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apach
> e/openjpa/kernel/FetchConfigurationImpl.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-k
> ernel/src/main/java/org/apache/openjpa/kernel/
> FetchConfigurationImpl.jav
> a?> view=diff&rev=506230&r1=506229&r2=506230
>> ==============================================================
>> ================
>> ---
>> incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apach
> e/openjpa/kernel/FetchConfigurationImpl.java (original)
>> +++
>> incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apach
> e/openjpa/kernel/FetchConfigurationImpl.java Sun Feb 11 18:33:05 2007
>> @@ -36,6 +36,8 @@
>> import org.apache.openjpa.lib.rop.SimpleResultList;
>> import org.apache.openjpa.lib.rop.WindowResultList;
>> import org.apache.openjpa.lib.util.Localizer;
>> +import org.apache.openjpa.lib.util.ReferenceMap;
>> +import
>> org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap;
>> import org.apache.openjpa.meta.ClassMetaData;
>> import org.apache.openjpa.meta.FetchGroup;
>> import org.apache.openjpa.meta.FieldMetaData;
>> @@ -58,6 +60,10 @@
>> private static final Localizer _loc = Localizer.forPackage
>> (FetchConfigurationImpl.class);
>>
>> + // Cache the from/to isAssignable invocations
>> + private static ConcurrentReferenceHashMap _assignableTypes =
>> + new ConcurrentReferenceHashMap(ReferenceMap.HARD,
>> ReferenceMap.WEAK);
>> +
>> /**
>> * Configurable state shared throughout a traversal chain.
>> */
>> @@ -613,11 +619,37 @@
>> }
>>
>> /**
>> - * Whether either of the two types is assignable from the other.
>> + * Whether either of the two types is assignable from
>> the other. Optimize
>> + * for the repeat calls with similar parameters by
>> caching the from/to
>> + * type parameters.
>> */
>> - private static boolean isAssignable(Class c1, Class c2) {
>> - return c1 != null && c2 != null
>> - && (c1.isAssignableFrom(c2) || c2.isAssignableFrom(c1));
>> + private static boolean isAssignable(Class from, Class to) {
>> + boolean isAssignable;
>> +
>> + if (from == null || to == null)
>> + return false;
>> + ConcurrentReferenceHashMap assignableTo =
>> + (ConcurrentReferenceHashMap) _assignableTypes.get(from);
>> +
>> + if (assignableTo != null) { // "to" cache exists...
>> + isAssignable = (assignableTo.get(to) != null);
>> + if (!isAssignable) { // not in the map yet...
>> + isAssignable = from.isAssignableFrom(to);
>> + if (isAssignable) {
>> + assignableTo.put(to, new Object());
>> + }
>> + }
>> + } else { // no "to" cache yet...
>> + isAssignable = from.isAssignableFrom(to);
>> + if (isAssignable) {
>> + assignableTo = new ConcurrentReferenceHashMap(
>> + ReferenceMap.HARD, ReferenceMap.WEAK);
>> + _assignableTypes.put(from, assignableTo);
>> + assignableTo.put(to, new Object());
>> + }
>> + }
>> +
>> + return isAssignable;
>> }
>>
>> /**
>>
>> Modified:
>> incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apach
> e/openjpa/util/OpenJPAId.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-k
> ernel/src/main/java/org/apache/openjpa/util/OpenJPAId.java?
> view=diff&rev
> => 506230&r1=506229&r2=506230
>> ==============================================================
>> ================
>> ---
>> incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apach
> e/openjpa/util/OpenJPAId.java (original)
>> +++
>> incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apach
> e/openjpa/util/OpenJPAId.java Sun Feb 11 18:33:05 2007
>> @@ -17,6 +17,10 @@
>>
>> import java.io.Serializable;
>>
>> +import org.apache.openjpa.lib.util.ReferenceHashSet;
>> +import org.apache.openjpa.lib.util.ReferenceMap;
>> +import
>> org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap;
>> +
>> /**
>> * Identity class extended by builtin OpenJPA identity objects.
>> *
>> @@ -31,6 +35,9 @@
>> // type has his based on the least-derived non-object
>> class so that
>> // user-given ids with non-exact types match ids with exact
>> types
>> private transient int _typeHash = 0;
>> + // cache the types' generated hashcodes
>> + private static ConcurrentReferenceHashMap _typeCache =
>> + new ConcurrentReferenceHashMap(ReferenceMap.HARD,
>> ReferenceMap.WEAK);
>>
>> protected OpenJPAId() {
>> }
>> @@ -82,13 +89,25 @@
>> */
>> protected abstract boolean idEquals(OpenJPAId other);
>>
>> + /**
>> + * Generate the hashcode for this Id. Cache the type's
>> generated hashcode
>> + * so that it doesn't have to be generated each time.
>> + */
>> public int hashCode() {
>> if (_typeHash == 0) {
>> - Class base = type;
>> - while (base.getSuperclass() != null
>> - && base.getSuperclass() != Object.class)
>> - base = base.getSuperclass();
>> - _typeHash = base.hashCode();
>> + Integer typeHashInt = (Integer) _typeCache.get(type);
>> + if (typeHashInt == null) {
>> + Class base = type;
>> + Class superclass = base.getSuperclass();
>> + while (superclass != null && superclass !=
>> Object.class) {
>> + base = base.getSuperclass();
>> + superclass = base.getSuperclass();
>> + }
>> + _typeHash = base.hashCode();
>> + _typeCache.put(type, new Integer(_typeHash));
>> + } else {
>> + _typeHash = typeHashInt.intValue();
>> + }
>> }
>> return _typeHash ^ idHash();
>> }
>>
>> Modified:
>> incubator/openjpa/trunk/openjpa-kernel/src/main/resources/org/
> apache/openjpa/kernel/localizer.properties
>> URL:
>> http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-k
> ernel/src/main/resources/org/apache/openjpa/kernel/
> localizer.properties?
>> view=diff&rev=506230&r1=506229&r2=506230
>> ==============================================================
>> ================
>> ---
>> incubator/openjpa/trunk/openjpa-kernel/src/main/resources/org/
> apache/openjpa/kernel/localizer.properties (original)
>> +++
>> incubator/openjpa/trunk/openjpa-kernel/src/main/resources/org/
> apache/openjpa/kernel/localizer.properties Sun Feb 11 18:33:05 2007
>> @@ -94,8 +94,13 @@
>> active: This operation cannot be performed while a
>> Transaction is active.
>> closed: The context has been closed. The stack trace at which the \
>> context was closed is held in the embedded exception.
>> +closed-notrace: The context has been closed. The stack
>> trace at which the \
>> + context was closed is available if Runtime=TRACE
>> logging is enabled.
>> closed-factory: The factory has been closed. The stack trace at \
>> which the factory was closed is held in the embedded exception.
>> +closed-factory-notrace: The factory has been closed. The
>> stack trace at \
>> + which the factory was closed is available if
>> Runtime=TRACE logging is \
>> + enabled.
>> non-trans-read: To perform reads on persistent data outside
>> of a transaction, \
>> the "NontransactionalRead" property must be set on the
>> Transaction.
>> non-trans-write: To perform writes on persistent data outside of a \
>>
>> Modified:
>> incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/o
> penjpa/lib/conf/ObjectValue.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-l
> ib/src/main/java/org/apache/openjpa/lib/conf/ObjectValue.java?>
> view=diff&rev=506230&r1=506229&r2=506230
>> ==============================================================
>> ================
>> ---
>> incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/o
> penjpa/lib/conf/ObjectValue.java (original)
>> +++
>> incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/o
> penjpa/lib/conf/ObjectValue.java Sun Feb 11 18:33:05 2007
>> @@ -17,6 +17,8 @@
>>
>> import org.apache.commons.lang.ObjectUtils;
>> import org.apache.openjpa.lib.util.Localizer;
>> +import org.apache.openjpa.lib.util.ReferenceMap;
>> +import
>> org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap;
>>
>> /**
>> * An object [EMAIL PROTECTED] Value}.
>> @@ -28,6 +30,10 @@
>> private static final Localizer _loc = Localizer.forPackage
>> (ObjectValue.class);
>>
>> + // cache the types' classloader
>> + private static ConcurrentReferenceHashMap _classloaderCache =
>> + new ConcurrentReferenceHashMap(ReferenceMap.HARD,
>> ReferenceMap.WEAK);
>> +
>> private Object _value = null;
>>
>> public ObjectValue(String prop) {
>> @@ -81,10 +87,16 @@
>> * Allow subclasses to instantiate additional plugins.
>> This method does
>> * not perform configuration.
>> */
>> - public Object newInstance(String clsName, Class type,
>> - Configuration conf, boolean fatal) {
>> - return Configurations.newInstance(clsName, this, conf,
>> - type.getClassLoader(), fatal);
>> + public Object newInstance(String clsName, Class type,
>> Configuration conf,
>> + boolean fatal) {
>> + ClassLoader cl = (ClassLoader) _classloaderCache.get(type);
>> + if (cl == null) {
>> + cl = type.getClassLoader();
>> + if (cl != null) { // System classloader is
>> returned as null
>> + _classloaderCache.put(type, cl);
>> + }
>> + }
>> + return Configurations.newInstance(clsName, this,
>> conf, cl, fatal);
>> }
>>
>> public Class getValueType() {
>>
>>
>>