You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2013/06/22 21:46:16 UTC
svn commit: r1495775 - in
/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne:
map/EntityResolver.java reflect/ClassDescriptorMap.java
Author: aadamchik
Date: Sat Jun 22 19:46:16 2013
New Revision: 1495775
URL: http://svn.apache.org/r1495775
Log:
CAY-1789 Lock-free EntityResolver
making class descriptor access non-synchronized
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/EntityResolver.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/ClassDescriptorMap.java
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/EntityResolver.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/EntityResolver.java?rev=1495775&r1=1495774&r2=1495775&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/EntityResolver.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/EntityResolver.java Sat Jun 22 19:46:16 2013
@@ -64,7 +64,7 @@ public class EntityResolver implements M
// must be transient, as resolver may get deserialized in another VM, and
// descriptor recompilation will be desired.
- protected transient ClassDescriptorMap classDescriptorMap;
+ protected transient volatile ClassDescriptorMap classDescriptorMap;
// callbacks are not serializable
protected transient LifecycleCallbackRegistry callbackRegistry;
@@ -444,7 +444,7 @@ public class EntityResolver implements M
*
* @since 1.2
*/
- public synchronized ClassDescriptor getClassDescriptor(String entityName) {
+ public ClassDescriptor getClassDescriptor(String entityName) {
if (entityName == null) {
throw new IllegalArgumentException("Null entityName");
}
@@ -659,22 +659,30 @@ public class EntityResolver implements M
*/
public ClassDescriptorMap getClassDescriptorMap() {
if (classDescriptorMap == null) {
- ClassDescriptorMap classDescriptorMap = new ClassDescriptorMap(this);
- FaultFactory faultFactory = new SingletonFaultFactory();
- // add factories in reverse of the desired chain order
- classDescriptorMap.addFactory(new ValueHolderDescriptorFactory(classDescriptorMap));
- classDescriptorMap.addFactory(new DataObjectDescriptorFactory(classDescriptorMap, faultFactory));
+ synchronized (this) {
- // since ClassDescriptorMap is not synchronized, we need to prefill
- // it with entity proxies here.
- for (DataMap map : maps) {
- for (String entityName : map.getObjEntityMap().keySet()) {
- classDescriptorMap.getDescriptor(entityName);
+ if (classDescriptorMap == null) {
+
+ ClassDescriptorMap classDescriptorMap = new ClassDescriptorMap(this);
+ FaultFactory faultFactory = new SingletonFaultFactory();
+
+ // add factories in reverse of the desired chain order
+ classDescriptorMap.addFactory(new ValueHolderDescriptorFactory(classDescriptorMap));
+ classDescriptorMap.addFactory(new DataObjectDescriptorFactory(classDescriptorMap, faultFactory));
+
+ // since ClassDescriptorMap is not synchronized, we need to
+ // prefill
+ // it with entity proxies here.
+ for (DataMap map : maps) {
+ for (String entityName : map.getObjEntityMap().keySet()) {
+ classDescriptorMap.getDescriptor(entityName);
+ }
+ }
+
+ this.classDescriptorMap = classDescriptorMap;
}
}
-
- this.classDescriptorMap = classDescriptorMap;
}
return classDescriptorMap;
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/ClassDescriptorMap.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/ClassDescriptorMap.java?rev=1495775&r1=1495774&r2=1495775&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/ClassDescriptorMap.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/ClassDescriptorMap.java Sat Jun 22 19:46:16 2013
@@ -28,10 +28,11 @@ import org.apache.cayenne.CayenneRuntime
import org.apache.cayenne.map.EntityResolver;
/**
- * An object that holds class descriptors for mapped entities, compiling new descriptors
- * on demand using an internal chain of descriptor factories. Note that the object is ot
- * synchronized internally, so it has to be prefilled with descriptors by the caller on
- * initialization via calling 'getDescriptor' for all mapped entities.
+ * An object that holds class descriptors for mapped entities, compiling new
+ * descriptors on demand using an internal chain of descriptor factories. Note
+ * that the object is not synchronized internally, so it has to be prefilled
+ * with descriptors by the caller on initialization via calling 'getDescriptor'
+ * for all mapped entities.
*
* @since 3.0
*/
@@ -83,8 +84,7 @@ public class ClassDescriptorMap {
public void addDescriptor(String entityName, ClassDescriptor descriptor) {
if (descriptor == null) {
removeDescriptor(entityName);
- }
- else {
+ } else {
descriptors.put(entityName, descriptor);
}
}
@@ -103,9 +103,9 @@ public class ClassDescriptorMap {
}
/**
- * Creates a descriptor wrapper that will compile the underlying descriptor on demand.
- * Using proxy indirection is needed to compile relationships of descriptors to other
- * descriptors that are not compiled yet.
+ * Creates a descriptor wrapper that will compile the underlying descriptor
+ * on demand. Using proxy indirection is needed to compile relationships of
+ * descriptors to other descriptors that are not compiled yet.
*/
protected ClassDescriptor createProxyDescriptor(String entityName) {
ClassDescriptor descriptor = new LazyClassDescriptorDecorator(this, entityName);
@@ -118,11 +118,12 @@ public class ClassDescriptorMap {
*/
protected ClassDescriptor createDescriptor(String entityName) {
- // scan the factory chain until some factory returns a non-null descriptor;
- // scanning is done in reverse order so that the factories added last take higher
+ // scan the factory chain until some factory returns a non-null
+ // descriptor;
+ // scanning is done in reverse order so that the factories added last
+ // take higher
// precedence...
- ListIterator<ClassDescriptorFactory> it = factories
- .listIterator(factories.size());
+ ListIterator<ClassDescriptorFactory> it = factories.listIterator(factories.size());
while (it.hasPrevious()) {
ClassDescriptorFactory factory = it.previous();
ClassDescriptor descriptor = factory.getDescriptor(entityName);
@@ -132,7 +133,6 @@ public class ClassDescriptorMap {
}
}
- throw new CayenneRuntimeException("Failed to create descriptor for entity: "
- + entityName);
+ throw new CayenneRuntimeException("Failed to create descriptor for entity: " + entityName);
}
}