You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openjpa.apache.org by Patrick Linskey <pl...@bea.com> on 2007/02/27 07:29:08 UTC

RE: 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/

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: kwsutter@apache.org [mailto:kwsutter@apache.org] 
> 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 {@link 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 {@link 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() {
> 
> 
> 

RE: 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/

Posted by Patrick Linskey <pl...@bea.com>.
Yeah, that's pretty much what we do most of the time also. For the code
in question, I don't think that it's relevant though.

-Patrick

-- 
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: Dain Sundstrom [mailto:dain@iq80.com] 
> Sent: Tuesday, February 27, 2007 1:29 PM
> To: open-jpa-dev@incubator.apache.org
> Subject: Re: 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/
> 
> Not sure if this is relevant, but normally, I use explicit, thread  
> and then system.
> 
> -dain
> 
> On Feb 26, 2007, at 10:52 PM, Marc Prud'hommeaux wrote:
> 
> >
> > 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: kwsutter@apache.org [mailto:kwsutter@apache.org]
> >>> 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 {@link 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 {@link 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() {
> >>>
> >>>
> >>>
> >
> 
> 

Re: 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/

Posted by Dain Sundstrom <da...@iq80.com>.
Not sure if this is relevant, but normally, I use explicit, thread  
and then system.

-dain

On Feb 26, 2007, at 10:52 PM, Marc Prud'hommeaux wrote:

>
> 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: kwsutter@apache.org [mailto:kwsutter@apache.org]
>>> 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 {@link 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 {@link 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() {
>>>
>>>
>>>
>


Re: 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/

Posted by Marc Prud'hommeaux <mp...@apache.org>.
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: kwsutter@apache.org [mailto:kwsutter@apache.org]
>> 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 {@link 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 {@link 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() {
>>
>>
>>