Author: aadamchik
Date: Thu Mar  1 08:23:55 2012
New Revision: 1295463

URL: http://svn.apache.org/viewvc?rev=1295463&view=rev
Log:
CAY-1680 Get rid of shared locks in DataDomain metadata lookups

Modified:
    cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt
    
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomain.java
    
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataNode.java
    
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataDomainTest.java

Modified: cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt
URL: 
http://svn.apache.org/viewvc/cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt?rev=1295463&r1=1295462&r2=1295463&view=diff
==============================================================================
--- cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt (original)
+++ cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt Thu Mar  1 
08:23:55 2012
@@ -41,6 +41,7 @@ CAY-1666 Fix problem with tests on ingre
 CAY-1667 Expression parser performance optimization
 CAY-1669 RuntimeProperties use of System properties becomes a contention point 
when creating query translators 
 CAY-1670 Non-blocking DataRowStore
+CAY-1680 Get rid of shared locks in DataDomain metadata lookups
 
 Bug Fixes Since 3.1M3:
 

Modified: 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomain.java
URL: 
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomain.java?rev=1295463&r1=1295462&r2=1295463&view=diff
==============================================================================
--- 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomain.java
 (original)
+++ 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomain.java
 Thu Mar  1 08:23:55 2012
@@ -25,7 +25,7 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.TreeMap;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 import org.apache.cayenne.CayenneRuntimeException;
@@ -81,18 +81,9 @@ public class DataDomain implements Query
      */
     protected List<DataChannelFilter> filters;
 
-    /** Stores mapping of data nodes to DataNode name keys. */
-    protected Map<String, DataNode> nodes = Collections
-            .synchronizedMap(new TreeMap<String, DataNode>());
-    protected Map<String, DataNode> nodesByDataMapName = Collections
-            .synchronizedMap(new HashMap<String, DataNode>());
-
-    /**
-     * Properties configured for DataDomain. These include properties of the 
DataRowStore
-     * and remote notifications.
-     */
-    protected Map<String, String> properties = Collections
-            .synchronizedMap(new TreeMap<String, String>());
+    protected Map<String, DataNode> nodes;
+    protected Map<String, DataNode> nodesByDataMapName;
+    protected Map<String, String> properties;
 
     protected EntityResolver entityResolver;
     protected DataRowStore sharedSnapshotCache;
@@ -129,8 +120,7 @@ public class DataDomain implements Query
      * Creates a DataDomain and assigns it a name.
      */
     public DataDomain(String name) {
-        this.filters = new CopyOnWriteArrayList<DataChannelFilter>();
-        setName(name);
+        init(name);
         resetProperties();
     }
 
@@ -142,9 +132,21 @@ public class DataDomain implements Query
      * @param properties A Map containing domain configuration properties.
      */
     public DataDomain(String name, Map properties) {
+        init(name);
+        initWithProperties(properties);
+    }
+
+    private void init(String name) {
+
         this.filters = new CopyOnWriteArrayList<DataChannelFilter>();
+        this.nodesByDataMapName = new ConcurrentHashMap<String, DataNode>();
+        this.nodes = new ConcurrentHashMap<String, DataNode>();
+
+        // properties are read-only, so no need for concurrent map, or any 
specific map
+        // for that matter
+        this.properties = Collections.EMPTY_MAP;
+
         setName(name);
-        initWithProperties(properties);
     }
 
     /**
@@ -178,9 +180,7 @@ public class DataDomain implements Query
      * @since 1.1
      */
     protected void resetProperties() {
-        if (properties != null) {
-            properties.clear();
-        }
+        properties = Collections.EMPTY_MAP;
 
         sharedCacheEnabled = SHARED_CACHE_ENABLED_DEFAULT;
         validatingObjectsOnCommit = VALIDATING_OBJECTS_ON_COMMIT_DEFAULT;
@@ -193,18 +193,16 @@ public class DataDomain implements Query
      * @since 1.1
      */
     public void initWithProperties(Map<String, String> properties) {
-        // create map with predictable modification and synchronization 
behavior
-        Map<String, String> localMap = new HashMap<String, String>();
-        if (properties != null) {
-            localMap.putAll(properties);
-        }
 
-        this.properties = localMap;
+        // clone properties to ensure that it is read-only internally
+        properties = properties != null
+                ? new HashMap<String, String>(properties)
+                : Collections.EMPTY_MAP;
 
-        String sharedCacheEnabled = 
localMap.get(SHARED_CACHE_ENABLED_PROPERTY);
-        String validatingObjectsOnCommit = localMap
+        String sharedCacheEnabled = 
properties.get(SHARED_CACHE_ENABLED_PROPERTY);
+        String validatingObjectsOnCommit = properties
                 .get(VALIDATING_OBJECTS_ON_COMMIT_PROPERTY);
-        String usingExternalTransactions = localMap
+        String usingExternalTransactions = properties
                 .get(USING_EXTERNAL_TRANSACTIONS_PROPERTY);
 
         // init ivars from properties
@@ -216,6 +214,8 @@ public class DataDomain implements Query
         this.usingExternalTransactions = (usingExternalTransactions != null)
                 ? "true".equalsIgnoreCase(usingExternalTransactions)
                 : USING_EXTERNAL_TRANSACTIONS_DEFAULT;
+
+        this.properties = properties;
     }
 
     /**
@@ -313,8 +313,7 @@ public class DataDomain implements Query
 
     /**
      * @since 1.1
-     * @return a Map of properties for this DataDomain. There is no guarantees 
of specific
-     *         synchronization behavior of this map.
+     * @return a Map of properties for this DataDomain.
      */
     public Map<String, String> getProperties() {
         return properties;
@@ -453,7 +452,7 @@ public class DataDomain implements Query
      * Removes a DataNode from DataDomain. Any maps previously associated with 
this node
      * within domain will still be kept around, however they wan't be mapped 
to any node.
      */
-    public synchronized void removeDataNode(String nodeName) {
+    public void removeDataNode(String nodeName) {
         DataNode removed = nodes.remove(nodeName);
         if (removed != null) {
 
@@ -484,23 +483,27 @@ public class DataDomain implements Query
 
     /**
      * Closes all data nodes, removes them from the list of available nodes.
+     * 
+     * @deprecated since 3.1 unused and unneeded
      */
+    @Deprecated
     public void reset() {
-        synchronized (nodes) {
-            nodes.clear();
-            nodesByDataMapName.clear();
 
-            if (entityResolver != null) {
-                entityResolver.clearCache();
-                entityResolver = null;
-            }
+        nodes.clear();
+        nodesByDataMapName.clear();
+
+        if (entityResolver != null) {
+            entityResolver.clearCache();
+            entityResolver = null;
         }
     }
 
     /**
-     * Clears the list of internal DataMaps. In most cases it is wise to call 
"reset"
-     * before doing that.
+     * Clears the list of internal DataMaps.
+     * 
+     * @deprecated since 3.1 unused and unneeded
      */
+    @Deprecated
     public void clearDataMaps() {
         getEntityResolver().setDataMaps(Collections.EMPTY_LIST);
     }
@@ -508,7 +511,7 @@ public class DataDomain implements Query
     /**
      * Adds new DataNode.
      */
-    public synchronized void addNode(DataNode node) {
+    public void addNode(DataNode node) {
 
         // add node to name->node map
         nodes.put(node.getName(), node);
@@ -597,8 +600,11 @@ public class DataDomain implements Query
 
     /**
      * Updates internal index of DataNodes stored by the entity name.
+     * 
+     * @deprecated since 3.1 - unneeded and unused.
      */
-    public synchronized void reindexNodes() {
+    @Deprecated
+    public void reindexNodes() {
         nodesByDataMapName.clear();
 
         for (DataNode node : getDataNodes()) {
@@ -615,16 +621,27 @@ public class DataDomain implements Query
      * @since 1.1
      */
     public DataNode lookupDataNode(DataMap map) {
-        synchronized (nodesByDataMapName) {
-            DataNode node = nodesByDataMapName.get(map.getName());
-            if (node == null) {
-                reindexNodes();
-                return nodesByDataMapName.get(map.getName());
-            }
-            else {
-                return node;
+
+        DataNode node = nodesByDataMapName.get(map.getName());
+        if (node == null) {
+
+            // see if one of the node states has changed, and the map is now 
linked...
+            for (DataNode n : getDataNodes()) {
+                for (DataMap m : n.getDataMaps()) {
+                    if (m == map) {
+                        nodesByDataMapName.put(map.getName(), n);
+                        node = n;
+                        break;
+                    }
+                }
+
+                if (node != null) {
+                    break;
+                }
             }
         }
+
+        return node;
     }
 
     /**
@@ -799,9 +816,8 @@ public class DataDomain implements Query
 
         DataDomainFlushAction action = new DataDomainFlushAction(this);
         action.setJdbcEventLogger(jdbcEventLogger);
-        
-        return action.flush((DataContext) originatingContext,
-                childChanges);
+
+        return action.flush((DataContext) originatingContext, childChanges);
     }
 
     /**

Modified: 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataNode.java
URL: 
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataNode.java?rev=1295463&r1=1295462&r2=1295463&view=diff
==============================================================================
--- 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataNode.java
 (original)
+++ 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataNode.java
 Thu Mar  1 08:23:55 2012
@@ -316,7 +316,7 @@ public class DataNode implements QueryEn
      * 
      * @since 1.1
      */
-    public void setEntityResolver(org.apache.cayenne.map.EntityResolver 
entityResolver) {
+    public void setEntityResolver(EntityResolver entityResolver) {
         this.entityResolver = entityResolver;
     }
 

Modified: 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataDomainTest.java
URL: 
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataDomainTest.java?rev=1295463&r1=1295462&r2=1295463&view=diff
==============================================================================
--- 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataDomainTest.java
 (original)
+++ 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataDomainTest.java
 Thu Mar  1 08:23:55 2012
@@ -84,6 +84,7 @@ public class DataDomainTest extends Serv
         assertNull(d1.getDataMap(m1.getName()));
     }
 
+    @Deprecated
     public void testReindexNodes() throws Exception {
         DataDomain domain = new DataDomain("dom1");
         DataMap map = new DataMap("map");


Reply via email to