Author: tolusha
Date: 2010-04-29 10:34:43 -0400 (Thu, 29 Apr 2010)
New Revision: 2343
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/persistent/WorkspaceStorageCache.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/LinkedWorkspaceStorageCacheImpl.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCacheableWorkspaceDataManager.java
Log:
EXOJCR-692: improve Node.hasNodes()
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/persistent/WorkspaceStorageCache.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/persistent/WorkspaceStorageCache.java 2010-04-28
15:20:24 UTC (rev 2342)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/persistent/WorkspaceStorageCache.java 2010-04-29
14:34:43 UTC (rev 2343)
@@ -65,6 +65,13 @@
List<NodeData> getChildNodes(NodeData parent);
/**
+ * @param parent
+ * @return child nodes count for parent if found; 0 if no items found; -1 if no items
+ * initialized
+ */
+ int getChildNodesCount(NodeData parent);
+
+ /**
* Get node child properties.<br/>
*
* @param parent
@@ -136,23 +143,20 @@
* @return long value
*/
long getSize();
-
+
/**
* Start buffering process.
*/
public void beginTransaction();
-
/**
* Sort changes and commit data to the cache.
*/
public void commitTransaction();
-
/**
* Forget about changes
*/
public void rollbackTransaction();
-
}
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java 2010-04-28
15:20:24 UTC (rev 2342)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java 2010-04-29
14:34:43 UTC (rev 2343)
@@ -94,7 +94,7 @@
* GET_LIST_PROPERTIES type.
*/
static private final int GET_LIST_PROPERTIES = 5;
-
+
/**
* Request type.
*/
@@ -341,10 +341,10 @@
{
if (cache.isEnabled())
{
- List<NodeData> childNodes = cache.getChildNodes(parent);
- if (childNodes != null)
+ int childCount = cache.getChildNodesCount(parent);
+ if (childCount >= 0)
{
- return childNodes.size();
+ return childCount;
}
}
@@ -386,7 +386,7 @@
if (data == null)
{
final DataRequest request = new DataRequest(parentData.getIdentifier(), name);
-
+
try
{
request.start();
@@ -395,12 +395,12 @@
data = getCachedItemData(parentData, name);
if (data == null)
{
- data = getPersistedItemData(parentData, name);
+ data = getPersistedItemData(parentData, name);
}
else if (!data.isNode())
{
fixPropertyValues((PropertyData)data);
- }
+ }
}
finally
{
@@ -427,7 +427,7 @@
if (data == null)
{
final DataRequest request = new DataRequest(identifier);
-
+
try
{
request.start();
@@ -436,7 +436,7 @@
data = getCachedItemData(identifier);
if (data == null)
{
- data = getPersistedItemData(identifier);
+ data = getPersistedItemData(identifier);
}
else if (!data.isNode())
{
@@ -733,7 +733,7 @@
finally
{
request.done();
- }
+ }
}
protected boolean isTxAware()
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/LinkedWorkspaceStorageCacheImpl.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/LinkedWorkspaceStorageCacheImpl.java 2010-04-28
15:20:24 UTC (rev 2342)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/LinkedWorkspaceStorageCacheImpl.java 2010-04-29
14:34:43 UTC (rev 2343)
@@ -1439,6 +1439,59 @@
/**
* {@inheritDoc}
*/
+ public int getChildNodesCount(NodeData parentData)
+ {
+ if (enabled && parentData != null)
+ {
+ long start = System.currentTimeMillis();
+ try
+ {
+ // we assume that parent cached too
+ final List<NodeData> cn = nodesCache.get(parentData.getIdentifier());
+
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug(name + ", getChildNodesCount() " +
parentData.getQPath().getAsString() + " "
+ + parentData.getIdentifier());
+ final StringBuffer blog = new StringBuffer();
+ if (cn != null)
+ {
+ blog.append("\n");
+ for (NodeData nd : cn)
+ {
+ blog.append("\t\t" + nd.getQPath().getAsString() + "
" + nd.getIdentifier() + "\n");
+ }
+ LOG.debug("\t-->" + blog.toString());
+ }
+ else
+ {
+ LOG.debug("\t--> null");
+ }
+ }
+
+ if (cn != null)
+ hits++;
+ else
+ miss++;
+ return cn != null ? cn.size() : -1;
+ }
+ catch (Exception e)
+ {
+ LOG.error(name + ", Error in getChildNodesCount() parentData: "
+ + (parentData != null ? parentData.getQPath().getAsString() :
"[null]"), e);
+ }
+ finally
+ {
+ totalGetTime += System.currentTimeMillis() - start;
+ }
+ }
+
+ return -1; // nothing cached
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public List<PropertyData> getChildProperties(final NodeData parentData)
{
if (enabled && parentData != null)
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java 2010-04-28
15:20:24 UTC (rev 2342)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java 2010-04-29
14:34:43 UTC (rev 2343)
@@ -260,7 +260,7 @@
*/
public JBossCacheWorkspaceStorageCache(WorkspaceEntry wsConfig, TransactionService
transactionService,
ConfigurationManager cfm) throws RepositoryException,
RepositoryConfigurationException
- {
+ {
if (wsConfig.getCache() == null)
{
throw new RepositoryConfigurationException("Cache configuration not
found");
@@ -294,7 +294,7 @@
{
// force set expiration key to default value in all Expiration configurations
(if any)
((ExpirationAlgorithmConfig)evictionRegionConfig.getEvictionAlgorithmConfig())
- .setExpirationKeyName(ExpirationAlgorithmConfig.EXPIRATION_KEY);
+ .setExpirationKeyName(ExpirationAlgorithmConfig.EXPIRATION_KEY);
useExpiration = true;
}
}
@@ -306,8 +306,8 @@
// if expiration is used, set appropriate factory with with timeout set via
configuration (or default one 15minutes)
this.cache =
- new BufferedJBossCache(factory.createCache(wsConfig.getCache()), useExpiration,
- wsConfig.getCache().getParameterTime(JBOSSCACHE_EXPIRATION,
JBOSSCACHE_EXPIRATION_DEFAULT));
+ new BufferedJBossCache(factory.createCache(wsConfig.getCache()), useExpiration,
wsConfig.getCache()
+ .getParameterTime(JBOSSCACHE_EXPIRATION, JBOSSCACHE_EXPIRATION_DEFAULT));
this.itemsRoot = Fqn.fromElements(ITEMS);
this.childNodes = Fqn.fromElements(CHILD_NODES);
@@ -323,7 +323,7 @@
createResidentNode(childProps);
createResidentNode(childPropsList);
createResidentNode(itemsRoot);
- }
+ }
/**
* Cache constructor with JBossCache JTA transaction support.
@@ -333,7 +333,7 @@
* @throws RepositoryConfigurationException if error of configuration
*/
public JBossCacheWorkspaceStorageCache(WorkspaceEntry wsConfig, ConfigurationManager
cfm)
- throws RepositoryException, RepositoryConfigurationException
+ throws RepositoryException, RepositoryConfigurationException
{
this(wsConfig, null, cfm);
}
@@ -621,12 +621,13 @@
*/
public List<NodeData> getChildNodes(final NodeData parent)
{
- final List<NodeData> childs = new ArrayList<NodeData>();
// get list of children uuids
final Set<Object> set =
(Set<Object>)cache.get(makeChildListFqn(childNodesList,
parent.getIdentifier()), ITEM_LIST);
if (set != null)
{
+ final List<NodeData> childs = new ArrayList<NodeData>();
+
for (Object child : set)
{
NodeData node = (NodeData)cache.get(makeItemFqn((String)child), ITEM_DATA);
@@ -652,6 +653,18 @@
/**
* {@inheritDoc}
*/
+ public int getChildNodesCount(NodeData parent)
+ {
+ // get list of children uuids
+ final Set<Object> set =
+ (Set<Object>)cache.get(makeChildListFqn(childNodesList,
parent.getIdentifier()), ITEM_LIST);
+
+ return set != null ? set.size() : -1;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public List<PropertyData> getChildProperties(NodeData parent)
{
return getChildProps(parent.getIdentifier(), true);
@@ -674,11 +687,12 @@
*/
protected List<PropertyData> getChildProps(String parentId, boolean withValue)
{
- final List<PropertyData> childs = new ArrayList<PropertyData>();
// get set of property uuids
final Set<Object> set =
(Set<Object>)cache.get(makeChildListFqn(childPropsList, parentId), ITEM_LIST);
if (set != null)
{
+ final List<PropertyData> childs = new ArrayList<PropertyData>();
+
for (Object child : set)
{
PropertyData prop = (PropertyData)cache.get(makeItemFqn((String)child),
ITEM_DATA);
@@ -813,7 +827,7 @@
{
// add in CHILD_NODES
cache.put(makeChildFqn(childNodes, node.getParentIdentifier(),
node.getQPath().getEntries()[node.getQPath()
-
.getEntries().length - 1]), ITEM_ID, node.getIdentifier());
+ .getEntries().length - 1]), ITEM_ID, node.getIdentifier());
// if MODIFY and List present OR FORCE_MODIFY, then write
if ((modifyListsOfChild == ModifyChildOption.MODIFY &&
cache.getNode(makeChildListFqn(childNodesList, node
.getParentIdentifier())) != null)
@@ -834,7 +848,7 @@
{
// add in CHILD_NODES
cache.put(makeChildFqn(childNodes, node.getParentIdentifier(),
node.getQPath().getEntries()[node.getQPath()
-
.getEntries().length - 1]), ITEM_ID, node.getIdentifier());
+ .getEntries().length - 1]), ITEM_ID, node.getIdentifier());
// if MODIFY and List present OR FORCE_MODIFY, then write
if ((modifyListsOfChild == ModifyChildOption.MODIFY &&
cache.getNode(makeChildListFqn(childNodesList, node
.getParentIdentifier())) != null)
@@ -858,7 +872,7 @@
{
// add in CHILD_PROPS
cache.put(makeChildFqn(childProps, prop.getParentIdentifier(),
prop.getQPath().getEntries()[prop.getQPath()
-
.getEntries().length - 1]), ITEM_ID, prop.getIdentifier());
+ .getEntries().length - 1]), ITEM_ID, prop.getIdentifier());
// if MODIFY and List present OR FORCE_MODIFY, then write
if ((modifyListsOfChild == ModifyChildOption.MODIFY &&
cache.getNode(makeChildListFqn(childPropsList, prop
.getParentIdentifier())) != null)
@@ -880,7 +894,7 @@
// remove from CHILD_NODES of parent
cache.removeNode(makeChildFqn(childNodes, item.getParentIdentifier(),
item.getQPath().getEntries()[item
-
.getQPath().getEntries().length - 1]));
+ .getQPath().getEntries().length - 1]));
// remove from CHILD_NODES_LIST of parent
cache.removeFromList(makeChildListFqn(childNodesList,
item.getParentIdentifier()), ITEM_LIST, item
@@ -903,7 +917,7 @@
{
// remove from CHILD_PROPS
cache.removeNode(makeChildFqn(childProps, item.getParentIdentifier(),
item.getQPath().getEntries()[item
-
.getQPath().getEntries().length - 1]));
+ .getQPath().getEntries().length - 1]));
// remove from CHILD_PROPS_LIST
cache.removeFromList(makeChildListFqn(childPropsList,
item.getParentIdentifier()), ITEM_LIST, item
@@ -948,7 +962,7 @@
// get previously cached NodeData and using its name remove child on the parent
Fqn<String> prevFqn =
makeChildFqn(childNodes, node.getParentIdentifier(),
prevNode.getQPath().getEntries()[prevNode.getQPath()
-
.getEntries().length - 1]);
+ .getEntries().length - 1]);
if (node.getIdentifier().equals(cache.get(prevFqn, ITEM_ID)))
{
// it's same-name siblings re-ordering, delete previous child
@@ -978,7 +992,7 @@
// get previously cached NodeData and using its name remove child on the parent
Fqn<String> prevFqn =
makeChildFqn(childNodes, node.getParentIdentifier(),
prevNode.getQPath().getEntries()[prevNode.getQPath()
-
.getEntries().length - 1]);
+ .getEntries().length - 1]);
if (node.getIdentifier().equals(cache.getFromBuffer(prevFqn, ITEM_ID)))
{
// it's same-name siblings re-ordering, delete previous child
@@ -1014,15 +1028,15 @@
PropertyData prevProp = iter.next();
if (inheritACL
- &&
(prevProp.getQPath().getName().equals(Constants.EXO_PERMISSIONS) ||
prevProp.getQPath().getName()
- .equals(Constants.EXO_OWNER)))
+ && (prevProp.getQPath().getName().equals(Constants.EXO_PERMISSIONS)
|| prevProp.getQPath().getName()
+ .equals(Constants.EXO_OWNER)))
{
inheritACL = false;
}
// recreate with new path for child Props only
QPath newPath =
QPath
- .makeChildPath(rootPath,
prevProp.getQPath().getEntries()[prevProp.getQPath().getEntries().length - 1]);
+ .makeChildPath(rootPath,
prevProp.getQPath().getEntries()[prevProp.getQPath().getEntries().length - 1]);
TransientPropertyData newProp =
new TransientPropertyData(newPath, prevProp.getIdentifier(),
prevProp.getPersistedVersion(), prevProp
.getType(), prevProp.getParentIdentifier(), prevProp.isMultiValued(),
prevProp.getValues());
@@ -1036,7 +1050,7 @@
// recreate with new path for child Nodes only
QPath newPath =
QPath
- .makeChildPath(rootPath,
prevNode.getQPath().getEntries()[prevNode.getQPath().getEntries().length - 1]);
+ .makeChildPath(rootPath,
prevNode.getQPath().getEntries()[prevNode.getQPath().getEntries().length - 1]);
TransientNodeData newNode =
new TransientNodeData(newPath, prevNode.getIdentifier(),
prevNode.getPersistedVersion(), prevNode
.getPrimaryTypeName(), prevNode.getMixinTypeNames(),
prevNode.getOrderNumber(), prevNode
@@ -1071,7 +1085,7 @@
TransientNodeData newNode =
new TransientNodeData(prevNode.getQPath(), prevNode.getIdentifier(),
prevNode.getPersistedVersion(),
prevNode.getPrimaryTypeName(), prevNode.getMixinTypeNames(),
prevNode.getOrderNumber(), prevNode
- .getParentIdentifier(), acl);
+ .getParentIdentifier(), acl);
// update this node
cache.put(makeItemFqn(newNode.getIdentifier()), ITEM_DATA, newNode);
// update childs recursive
@@ -1110,4 +1124,5 @@
private enum ModifyChildOption {
NOT_MODIFY, MODIFY, FORCE_MODIFY
}
+
}
Modified:
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCacheableWorkspaceDataManager.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCacheableWorkspaceDataManager.java 2010-04-28
15:20:24 UTC (rev 2342)
+++
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCacheableWorkspaceDataManager.java 2010-04-29
14:34:43 UTC (rev 2343)
@@ -53,6 +53,7 @@
{
private static final int READER = 100;
+
private static final int TIMES = 20;
private CacheableWorkspaceDataManager cwdm;
@@ -96,7 +97,7 @@
startSignal.await();
for (int i = 0; i < TIMES; i++)
{
- task.execute();
+ task.execute();
}
}
catch (Exception e)
@@ -120,9 +121,9 @@
e.printStackTrace();
}
throw errors.get(0);
- }
+ }
}
-
+
public void testGetItemById() throws Exception
{
assertEquals(0, con.getItemDataByIdCalls.get());
@@ -132,15 +133,15 @@
{
ItemData item = cwdm.getItemData("getItemData");
assertNotNull(item);
- }
+ }
};
multiThreadingTest(task);
assertEquals(1, con.getItemDataByIdCalls.get());
}
-
+
public void testGetItemDataByNodeDataNQPathEntry() throws Exception
{
- final NodeData nodeData = new PersistedNodeData("getItemData", null,
null, 0, 1, null, null, null);
+ final NodeData nodeData = new PersistedNodeData("getItemData", null,
null, 0, 1, null, null, null);
assertEquals(0, con.getItemDataByNodeDataNQPathEntryCalls.get());
MyTask task = new MyTask()
{
@@ -148,15 +149,15 @@
{
ItemData item = cwdm.getItemData(nodeData, new
QPathEntry("http://www.foo.com", "foo", 0));
assertNotNull(item);
- }
+ }
};
multiThreadingTest(task);
assertEquals(1, con.getItemDataByNodeDataNQPathEntryCalls.get());
}
-
+
public void testGetChildPropertiesData() throws Exception
{
- final NodeData nodeData = new PersistedNodeData("getChildPropertiesData",
null, null, 0, 1, null, null, null);
+ final NodeData nodeData = new PersistedNodeData("getChildPropertiesData",
null, null, 0, 1, null, null, null);
assertEquals(0, con.getChildPropertiesDataCalls.get());
MyTask task = new MyTask()
{
@@ -165,7 +166,7 @@
List<PropertyData> properties = cwdm.getChildPropertiesData(nodeData);
assertNotNull(properties);
assertFalse(properties.isEmpty());
- }
+ }
};
multiThreadingTest(task);
assertEquals(1, con.getChildPropertiesDataCalls.get());
@@ -176,15 +177,15 @@
List<PropertyData> properties = cwdm.getChildPropertiesData(nodeData,
true);
assertNotNull(properties);
assertFalse(properties.isEmpty());
- }
+ }
};
multiThreadingTest(task);
assertEquals(1 + READER * TIMES, con.getChildPropertiesDataCalls.get());
}
-
+
public void testListChildPropertiesData() throws Exception
{
- final NodeData nodeData = new
PersistedNodeData("listChildPropertiesData", null, null, 0, 1, null, null,
null);
+ final NodeData nodeData = new
PersistedNodeData("listChildPropertiesData", null, null, 0, 1, null, null,
null);
assertEquals(0, con.listChildPropertiesDataCalls.get());
MyTask task = new MyTask()
{
@@ -193,7 +194,7 @@
List<PropertyData> properties =
cwdm.listChildPropertiesData(nodeData);
assertNotNull(properties);
assertFalse(properties.isEmpty());
- }
+ }
};
multiThreadingTest(task);
assertEquals(1, con.listChildPropertiesDataCalls.get());
@@ -204,15 +205,15 @@
List<PropertyData> properties = cwdm.listChildPropertiesData(nodeData,
true);
assertNotNull(properties);
assertFalse(properties.isEmpty());
- }
+ }
};
multiThreadingTest(task);
assertEquals(1 + READER * TIMES, con.listChildPropertiesDataCalls.get());
}
-
+
public void testGetChildNodes() throws Exception
{
- final NodeData nodeData = new PersistedNodeData("getChildNodes", null,
null, 0, 1, null, null, null);
+ final NodeData nodeData = new PersistedNodeData("getChildNodes", null,
null, 0, 1, null, null, null);
assertEquals(0, con.getChildNodesDataCalls.get());
MyTask task = new MyTask()
{
@@ -221,7 +222,7 @@
List<NodeData> nodes = cwdm.getChildNodesData(nodeData);
assertNotNull(nodes);
assertFalse(nodes.isEmpty());
- }
+ }
};
multiThreadingTest(task);
assertEquals(1, con.getChildNodesDataCalls.get());
@@ -232,15 +233,15 @@
List<NodeData> nodes = cwdm.getChildNodesData(nodeData, true);
assertNotNull(nodes);
assertFalse(nodes.isEmpty());
- }
+ }
};
multiThreadingTest(task);
assertEquals(1 + READER * TIMES, con.getChildNodesDataCalls.get());
}
-
+
public void testGetChildNodesCount() throws Exception
{
- final NodeData nodeData = new PersistedNodeData("getChildNodesCount",
null, null, 0, 1, null, null, null);
+ final NodeData nodeData = new PersistedNodeData("getChildNodesCount",
null, null, 0, 1, null, null, null);
assertEquals(0, con.getChildNodesCountCalls.get());
MyTask task = new MyTask()
{
@@ -248,7 +249,7 @@
{
int result = cwdm.getChildNodesCount(nodeData);
assertEquals(1, result);
- }
+ }
};
multiThreadingTest(task);
assertEquals(READER * TIMES, con.getChildNodesCountCalls.get());
@@ -260,7 +261,7 @@
{
int result = cwdm.getChildNodesCount(nodeData);
assertEquals(1, result);
- }
+ }
};
multiThreadingTest(task);
assertEquals(READER * TIMES, con.getChildNodesCountCalls.get());
@@ -270,7 +271,7 @@
{
void execute() throws Exception;
}
-
+
private static class MyWorkspaceStorageCache implements WorkspaceStorageCache
{
@@ -363,6 +364,11 @@
{
}
+ public int getChildNodesCount(NodeData parent)
+ {
+ return childNodes != null ? childNodes.size() : -1;
+ }
+
}
private static class MyWorkspaceStorageConnection implements
WorkspaceStorageConnection
@@ -463,8 +469,10 @@
IllegalStateException
{
listChildPropertiesDataCalls.incrementAndGet();
- return Arrays.asList((PropertyData)new
PersistedPropertyData("listChildPropertiesData", null, null, 0,
PropertyType.STRING,
- false, Arrays.asList((ValueData)new ByteArrayPersistedValueData(1,
"foo".getBytes()))));
+ return Arrays
+ .asList((PropertyData)new
PersistedPropertyData("listChildPropertiesData", null, null, 0,
+ PropertyType.STRING, false, Arrays
+ .asList((ValueData)new ByteArrayPersistedValueData(1,
"foo".getBytes()))));
}
public void rename(NodeData data) throws RepositoryException,
UnsupportedOperationException,