mirror of https://github.com/apache/openjpa.git
OPENJPA-141. A few improvements to the performance-related changes done with the previous Issue. Reference OPENJPA-141 for details. Biggest change was moving some of the common caching code to ImplHelper.
git-svn-id: https://svn.apache.org/repos/asf/incubator/openjpa/trunk@508395 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
7a2330ce3b
commit
dfc102beba
|
@ -29,7 +29,7 @@ public class JNDIManagedRuntime
|
|||
implements ManagedRuntime {
|
||||
|
||||
private String _tmLoc = "java:/TransactionManager";
|
||||
private static TransactionManager _tm;
|
||||
private TransactionManager _tm = null;
|
||||
|
||||
/**
|
||||
* Return the location of the {@link TransactionManager} in JNDI.
|
||||
|
@ -43,12 +43,14 @@ public class JNDIManagedRuntime
|
|||
*/
|
||||
public void setTransactionManagerName(String name) {
|
||||
_tmLoc = name;
|
||||
_tm = null; // reset the cached TM
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the cached TransactionManager instance.
|
||||
*/
|
||||
public TransactionManager getTransactionManager() throws Exception {
|
||||
|
||||
if (_tm == null) {
|
||||
Context ctx = new InitialContext();
|
||||
try {
|
||||
|
|
|
@ -63,7 +63,6 @@ import org.apache.openjpa.lib.util.Localizer;
|
|||
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;
|
||||
|
@ -75,6 +74,7 @@ import org.apache.openjpa.util.ApplicationIds;
|
|||
import org.apache.openjpa.util.CallbackException;
|
||||
import org.apache.openjpa.util.Exceptions;
|
||||
import org.apache.openjpa.util.GeneralException;
|
||||
import org.apache.openjpa.util.ImplHelper;
|
||||
import org.apache.openjpa.util.InternalException;
|
||||
import org.apache.openjpa.util.InvalidStateException;
|
||||
import org.apache.openjpa.util.NoTransactionException;
|
||||
|
@ -139,9 +139,6 @@ public class BrokerImpl
|
|||
|
||||
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
|
||||
|
@ -1101,7 +1098,8 @@ public class BrokerImpl
|
|||
cls));
|
||||
return PCRegistry.newObjectId(cls, (String) val);
|
||||
}
|
||||
if (isAssignable(meta.getObjectIdType(), val.getClass())) {
|
||||
if (ImplHelper.isAssignable(meta.getObjectIdType(), val.getClass()))
|
||||
{
|
||||
if (!meta.isOpenJPAIdentity() && meta.isObjectIdTypeShared())
|
||||
return new ObjectId(cls, val);
|
||||
return val;
|
||||
|
@ -1122,37 +1120,6 @@ public class BrokerImpl
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
|
|
@ -36,11 +36,10 @@ import org.apache.openjpa.lib.rop.ResultObjectProvider;
|
|||
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;
|
||||
import org.apache.openjpa.util.ImplHelper;
|
||||
import org.apache.openjpa.util.InternalException;
|
||||
import org.apache.openjpa.util.NoTransactionException;
|
||||
import org.apache.openjpa.util.UserException;
|
||||
|
@ -60,10 +59,6 @@ public class FetchConfigurationImpl
|
|||
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.
|
||||
*/
|
||||
|
@ -563,7 +558,7 @@ public class FetchConfigurationImpl
|
|||
// see if there's a previous limit
|
||||
int avail = Integer.MIN_VALUE;
|
||||
for (FetchConfigurationImpl f = this; f != null; f = f._parent) {
|
||||
if (isAssignable(type, f._fromType)) {
|
||||
if (ImplHelper.isAssignable(type, f._fromType)) {
|
||||
avail = f._availableRecursion;
|
||||
if (traverse)
|
||||
avail = reduce(avail);
|
||||
|
@ -588,15 +583,15 @@ public class FetchConfigurationImpl
|
|||
max = cur;
|
||||
}
|
||||
// reduce max if we're traversing a self-type relation
|
||||
if (traverse && max != Integer.MIN_VALUE
|
||||
&& isAssignable(meta.getDescribedType(), type))
|
||||
if (traverse && max != Integer.MIN_VALUE
|
||||
&& ImplHelper.isAssignable(meta.getDescribedType(), type))
|
||||
max = reduce(max);
|
||||
|
||||
// take min/defined of previous avail and fetch group max
|
||||
if (avail == Integer.MIN_VALUE && max == Integer.MIN_VALUE) {
|
||||
int def = FetchGroup.RECURSION_DEPTH_DEFAULT;
|
||||
return (traverse && isAssignable(meta.getDescribedType(), type))
|
||||
? def - 1 : def;
|
||||
return (traverse && ImplHelper.isAssignable(
|
||||
meta.getDescribedType(), type)) ? def - 1 : def;
|
||||
}
|
||||
if (avail == Integer.MIN_VALUE || avail == FetchGroup.DEPTH_INFINITE)
|
||||
return max;
|
||||
|
@ -618,40 +613,6 @@ public class FetchConfigurationImpl
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduce the given logical depth by 1.
|
||||
*/
|
||||
|
|
|
@ -20,8 +20,8 @@ import java.util.BitSet;
|
|||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.openjpa.enhance.PersistenceCapable;
|
||||
import org.apache.openjpa.kernel.FetchConfiguration;
|
||||
import org.apache.openjpa.kernel.LockManager;
|
||||
|
@ -30,7 +30,10 @@ import org.apache.openjpa.kernel.PCState;
|
|||
import org.apache.openjpa.kernel.StoreContext;
|
||||
import org.apache.openjpa.kernel.StoreManager;
|
||||
import org.apache.openjpa.lib.util.Closeable;
|
||||
import org.apache.openjpa.lib.util.ReferenceMap;
|
||||
import org.apache.openjpa.lib.util.UUIDGenerator;
|
||||
import org.apache.openjpa.lib.util.concurrent.ConcurrentHashMap;
|
||||
import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap;
|
||||
import org.apache.openjpa.meta.ClassMetaData;
|
||||
import org.apache.openjpa.meta.FieldMetaData;
|
||||
import org.apache.openjpa.meta.JavaTypes;
|
||||
|
@ -46,6 +49,10 @@ import org.apache.openjpa.meta.ValueStrategies;
|
|||
*/
|
||||
public class ImplHelper {
|
||||
|
||||
// Cache for from/to type assignments
|
||||
private static ConcurrentReferenceHashMap _assignableTypes =
|
||||
new ConcurrentReferenceHashMap(ReferenceMap.WEAK, ReferenceMap.HARD);
|
||||
|
||||
/**
|
||||
* Helper for store manager implementations. This method simply delegates
|
||||
* to the proper singular method for each state manager.
|
||||
|
@ -187,4 +194,34 @@ public class ImplHelper {
|
|||
public static boolean isManageable(Object instance) {
|
||||
return instance instanceof PersistenceCapable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the referenced "to" class is assignable to the "from"
|
||||
* class. This helper method utilizes a cache to help avoid the overhead
|
||||
* of the Class.isAssignableFrom() method.
|
||||
*
|
||||
* @param from target class instance to be checked for assignability
|
||||
* @param to second class instance to be checked for assignability
|
||||
* @return true if the "to" class is assignable to the "from" class
|
||||
*/
|
||||
public static boolean isAssignable(Class from, Class to) {
|
||||
Boolean isAssignable = null;
|
||||
if (from == null || to == null)
|
||||
return false;
|
||||
Map assignableTo = (Map) _assignableTypes.get(from);
|
||||
|
||||
if (assignableTo == null) { // "to" cache doesn't exist, so create it...
|
||||
assignableTo = new ConcurrentHashMap();
|
||||
_assignableTypes.put(from, assignableTo);
|
||||
} else { // "to" cache exists...
|
||||
isAssignable = (Boolean) assignableTo.get(to);
|
||||
}
|
||||
|
||||
if (isAssignable == null) {// we don't have a record of this pair...
|
||||
isAssignable = new Boolean(from.isAssignableFrom(to));
|
||||
assignableTo.put(to, isAssignable);
|
||||
}
|
||||
|
||||
return isAssignable.booleanValue();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ package org.apache.openjpa.util;
|
|||
|
||||
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;
|
||||
|
||||
|
@ -37,7 +36,7 @@ public abstract class OpenJPAId
|
|||
private transient int _typeHash = 0;
|
||||
// cache the types' generated hashcodes
|
||||
private static ConcurrentReferenceHashMap _typeCache =
|
||||
new ConcurrentReferenceHashMap(ReferenceMap.HARD, ReferenceMap.WEAK);
|
||||
new ConcurrentReferenceHashMap(ReferenceMap.WEAK, ReferenceMap.HARD);
|
||||
|
||||
protected OpenJPAId() {
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue