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 {
|
implements ManagedRuntime {
|
||||||
|
|
||||||
private String _tmLoc = "java:/TransactionManager";
|
private String _tmLoc = "java:/TransactionManager";
|
||||||
private static TransactionManager _tm;
|
private TransactionManager _tm = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the location of the {@link TransactionManager} in JNDI.
|
* Return the location of the {@link TransactionManager} in JNDI.
|
||||||
|
@ -43,12 +43,14 @@ public class JNDIManagedRuntime
|
||||||
*/
|
*/
|
||||||
public void setTransactionManagerName(String name) {
|
public void setTransactionManagerName(String name) {
|
||||||
_tmLoc = name;
|
_tmLoc = name;
|
||||||
|
_tm = null; // reset the cached TM
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the cached TransactionManager instance.
|
* Return the cached TransactionManager instance.
|
||||||
*/
|
*/
|
||||||
public TransactionManager getTransactionManager() throws Exception {
|
public TransactionManager getTransactionManager() throws Exception {
|
||||||
|
|
||||||
if (_tm == null) {
|
if (_tm == null) {
|
||||||
Context ctx = new InitialContext();
|
Context ctx = new InitialContext();
|
||||||
try {
|
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.ReferenceHashMap;
|
||||||
import org.apache.openjpa.lib.util.ReferenceHashSet;
|
import org.apache.openjpa.lib.util.ReferenceHashSet;
|
||||||
import org.apache.openjpa.lib.util.ReferenceMap;
|
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.lib.util.concurrent.ReentrantLock;
|
||||||
import org.apache.openjpa.meta.ClassMetaData;
|
import org.apache.openjpa.meta.ClassMetaData;
|
||||||
import org.apache.openjpa.meta.FieldMetaData;
|
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.CallbackException;
|
||||||
import org.apache.openjpa.util.Exceptions;
|
import org.apache.openjpa.util.Exceptions;
|
||||||
import org.apache.openjpa.util.GeneralException;
|
import org.apache.openjpa.util.GeneralException;
|
||||||
|
import org.apache.openjpa.util.ImplHelper;
|
||||||
import org.apache.openjpa.util.InternalException;
|
import org.apache.openjpa.util.InternalException;
|
||||||
import org.apache.openjpa.util.InvalidStateException;
|
import org.apache.openjpa.util.InvalidStateException;
|
||||||
import org.apache.openjpa.util.NoTransactionException;
|
import org.apache.openjpa.util.NoTransactionException;
|
||||||
|
@ -139,9 +139,6 @@ public class BrokerImpl
|
||||||
|
|
||||||
private static final Localizer _loc =
|
private static final Localizer _loc =
|
||||||
Localizer.forPackage(BrokerImpl.class);
|
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
|
// the store manager in use; this may be a decorator such as a
|
||||||
// data cache store manager around the native store manager
|
// data cache store manager around the native store manager
|
||||||
|
@ -1101,7 +1098,8 @@ public class BrokerImpl
|
||||||
cls));
|
cls));
|
||||||
return PCRegistry.newObjectId(cls, (String) val);
|
return PCRegistry.newObjectId(cls, (String) val);
|
||||||
}
|
}
|
||||||
if (isAssignable(meta.getObjectIdType(), val.getClass())) {
|
if (ImplHelper.isAssignable(meta.getObjectIdType(), val.getClass()))
|
||||||
|
{
|
||||||
if (!meta.isOpenJPAIdentity() && meta.isObjectIdTypeShared())
|
if (!meta.isOpenJPAIdentity() && meta.isObjectIdTypeShared())
|
||||||
return new ObjectId(cls, val);
|
return new ObjectId(cls, val);
|
||||||
return 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.
|
* 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.SimpleResultList;
|
||||||
import org.apache.openjpa.lib.rop.WindowResultList;
|
import org.apache.openjpa.lib.rop.WindowResultList;
|
||||||
import org.apache.openjpa.lib.util.Localizer;
|
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.ClassMetaData;
|
||||||
import org.apache.openjpa.meta.FetchGroup;
|
import org.apache.openjpa.meta.FetchGroup;
|
||||||
import org.apache.openjpa.meta.FieldMetaData;
|
import org.apache.openjpa.meta.FieldMetaData;
|
||||||
|
import org.apache.openjpa.util.ImplHelper;
|
||||||
import org.apache.openjpa.util.InternalException;
|
import org.apache.openjpa.util.InternalException;
|
||||||
import org.apache.openjpa.util.NoTransactionException;
|
import org.apache.openjpa.util.NoTransactionException;
|
||||||
import org.apache.openjpa.util.UserException;
|
import org.apache.openjpa.util.UserException;
|
||||||
|
@ -60,10 +59,6 @@ public class FetchConfigurationImpl
|
||||||
private static final Localizer _loc = Localizer.forPackage
|
private static final Localizer _loc = Localizer.forPackage
|
||||||
(FetchConfigurationImpl.class);
|
(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.
|
* Configurable state shared throughout a traversal chain.
|
||||||
*/
|
*/
|
||||||
|
@ -563,7 +558,7 @@ public class FetchConfigurationImpl
|
||||||
// see if there's a previous limit
|
// see if there's a previous limit
|
||||||
int avail = Integer.MIN_VALUE;
|
int avail = Integer.MIN_VALUE;
|
||||||
for (FetchConfigurationImpl f = this; f != null; f = f._parent) {
|
for (FetchConfigurationImpl f = this; f != null; f = f._parent) {
|
||||||
if (isAssignable(type, f._fromType)) {
|
if (ImplHelper.isAssignable(type, f._fromType)) {
|
||||||
avail = f._availableRecursion;
|
avail = f._availableRecursion;
|
||||||
if (traverse)
|
if (traverse)
|
||||||
avail = reduce(avail);
|
avail = reduce(avail);
|
||||||
|
@ -589,14 +584,14 @@ public class FetchConfigurationImpl
|
||||||
}
|
}
|
||||||
// reduce max if we're traversing a self-type relation
|
// reduce max if we're traversing a self-type relation
|
||||||
if (traverse && max != Integer.MIN_VALUE
|
if (traverse && max != Integer.MIN_VALUE
|
||||||
&& isAssignable(meta.getDescribedType(), type))
|
&& ImplHelper.isAssignable(meta.getDescribedType(), type))
|
||||||
max = reduce(max);
|
max = reduce(max);
|
||||||
|
|
||||||
// take min/defined of previous avail and fetch group max
|
// take min/defined of previous avail and fetch group max
|
||||||
if (avail == Integer.MIN_VALUE && max == Integer.MIN_VALUE) {
|
if (avail == Integer.MIN_VALUE && max == Integer.MIN_VALUE) {
|
||||||
int def = FetchGroup.RECURSION_DEPTH_DEFAULT;
|
int def = FetchGroup.RECURSION_DEPTH_DEFAULT;
|
||||||
return (traverse && isAssignable(meta.getDescribedType(), type))
|
return (traverse && ImplHelper.isAssignable(
|
||||||
? def - 1 : def;
|
meta.getDescribedType(), type)) ? def - 1 : def;
|
||||||
}
|
}
|
||||||
if (avail == Integer.MIN_VALUE || avail == FetchGroup.DEPTH_INFINITE)
|
if (avail == Integer.MIN_VALUE || avail == FetchGroup.DEPTH_INFINITE)
|
||||||
return max;
|
return max;
|
||||||
|
@ -618,40 +613,6 @@ public class FetchConfigurationImpl
|
||||||
return null;
|
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.
|
* Reduce the given logical depth by 1.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -20,8 +20,8 @@ import java.util.BitSet;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.apache.openjpa.enhance.PersistenceCapable;
|
import org.apache.openjpa.enhance.PersistenceCapable;
|
||||||
import org.apache.openjpa.kernel.FetchConfiguration;
|
import org.apache.openjpa.kernel.FetchConfiguration;
|
||||||
import org.apache.openjpa.kernel.LockManager;
|
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.StoreContext;
|
||||||
import org.apache.openjpa.kernel.StoreManager;
|
import org.apache.openjpa.kernel.StoreManager;
|
||||||
import org.apache.openjpa.lib.util.Closeable;
|
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.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.ClassMetaData;
|
||||||
import org.apache.openjpa.meta.FieldMetaData;
|
import org.apache.openjpa.meta.FieldMetaData;
|
||||||
import org.apache.openjpa.meta.JavaTypes;
|
import org.apache.openjpa.meta.JavaTypes;
|
||||||
|
@ -46,6 +49,10 @@ import org.apache.openjpa.meta.ValueStrategies;
|
||||||
*/
|
*/
|
||||||
public class ImplHelper {
|
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
|
* Helper for store manager implementations. This method simply delegates
|
||||||
* to the proper singular method for each state manager.
|
* to the proper singular method for each state manager.
|
||||||
|
@ -187,4 +194,34 @@ public class ImplHelper {
|
||||||
public static boolean isManageable(Object instance) {
|
public static boolean isManageable(Object instance) {
|
||||||
return instance instanceof PersistenceCapable;
|
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 java.io.Serializable;
|
||||||
|
|
||||||
import org.apache.openjpa.lib.util.ReferenceHashSet;
|
|
||||||
import org.apache.openjpa.lib.util.ReferenceMap;
|
import org.apache.openjpa.lib.util.ReferenceMap;
|
||||||
import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap;
|
import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap;
|
||||||
|
|
||||||
|
@ -37,7 +36,7 @@ public abstract class OpenJPAId
|
||||||
private transient int _typeHash = 0;
|
private transient int _typeHash = 0;
|
||||||
// cache the types' generated hashcodes
|
// cache the types' generated hashcodes
|
||||||
private static ConcurrentReferenceHashMap _typeCache =
|
private static ConcurrentReferenceHashMap _typeCache =
|
||||||
new ConcurrentReferenceHashMap(ReferenceMap.HARD, ReferenceMap.WEAK);
|
new ConcurrentReferenceHashMap(ReferenceMap.WEAK, ReferenceMap.HARD);
|
||||||
|
|
||||||
protected OpenJPAId() {
|
protected OpenJPAId() {
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue