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");