Author: tolusha
Date: 2010-11-02 05:39:26 -0400 (Tue, 02 Nov 2010)
New Revision: 3377
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-1029: Storing result of the method getReferencesData into the cache
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-11-02
08:59:39 UTC (rev 3376)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/persistent/WorkspaceStorageCache.java 2010-11-02
09:39:26 UTC (rev 3377)
@@ -108,6 +108,26 @@
List<PropertyData> listChildProperties(final NodeData parentData);
/**
+ * Get referenced properties.
+ *
+ * @param identifier
+ * referenceable id
+ * @return
+ * list of REFERENCE properties
+ */
+ List<PropertyData> getReferencedProperties(String identifier);
+
+ /**
+ * Add referenced properties.
+ *
+ * @param identifier
+ * referenceable id
+ * @param refProperties
+ * list of properties
+ */
+ void addReferencedProperties(String identifier, List<PropertyData>
refProperties);
+
+ /**
* Adds (or updates if found) ItemData.
*
* @param item
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-11-02
08:59:39 UTC (rev 3376)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/CacheableWorkspaceDataManager.java 2010-11-02
09:39:26 UTC (rev 3377)
@@ -18,14 +18,6 @@
*/
package org.exoplatform.services.jcr.impl.dataflow.persistent;
-import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.CountDownLatch;
-
-import javax.jcr.RepositoryException;
-import javax.transaction.TransactionManager;
-
import org.exoplatform.services.jcr.dataflow.ItemStateChangesLog;
import
org.exoplatform.services.jcr.dataflow.persistent.MandatoryItemsPersistenceListener;
import org.exoplatform.services.jcr.dataflow.persistent.WorkspaceStorageCache;
@@ -36,12 +28,22 @@
import org.exoplatform.services.jcr.datamodel.PropertyData;
import org.exoplatform.services.jcr.datamodel.QPathEntry;
import org.exoplatform.services.jcr.datamodel.ValueData;
+import org.exoplatform.services.jcr.impl.Constants;
import
org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache;
import org.exoplatform.services.jcr.impl.storage.SystemDataContainerHolder;
import org.exoplatform.services.jcr.impl.storage.jdbc.JDBCStorageConnection;
import org.exoplatform.services.jcr.storage.WorkspaceDataContainer;
import org.exoplatform.services.transaction.TransactionService;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CountDownLatch;
+
+import javax.jcr.RepositoryException;
+import javax.transaction.TransactionManager;
+
/**
* Created by The eXo Platform SAS.
*
@@ -73,7 +75,6 @@
protected class DataRequest
{
/**
- /**
* GET_NODES type.
*/
static public final int GET_NODES = 1;
@@ -99,6 +100,11 @@
static private final int GET_LIST_PROPERTIES = 5;
/**
+ * GET_REFERENCES type.
+ */
+ static public final int GET_REFERENCES = 6;
+
+ /**
* Request type.
*/
protected final int type;
@@ -520,7 +526,21 @@
public List<PropertyData> getReferencesData(String identifier, boolean
skipVersionStorage)
throws RepositoryException
{
- return super.getReferencesData(identifier, skipVersionStorage);
+ List<PropertyData> props = getReferencedPropertiesData(identifier);
+
+ if (skipVersionStorage)
+ {
+ Iterator<PropertyData> iterator = props.iterator();
+ while (iterator.hasNext())
+ {
+ if
(iterator.next().getQPath().isDescendantOf(Constants.JCR_VERSION_STORAGE_PATH))
+ {
+ iterator.remove();
+ }
+ }
+ }
+
+ return props;
}
/**
@@ -644,6 +664,55 @@
}
/**
+ * Get referenced properties data.
+ *
+ * @param identifier
+ * referenceable identifier
+ * @return List<PropertyData>
+ * @throws RepositoryException
+ * Repository error
+ */
+ protected List<PropertyData> getReferencedPropertiesData(String identifier)
+ throws RepositoryException
+ {
+ List<PropertyData> refProps = null;
+ if (!cache.isEnabled())
+ {
+ refProps = cache.getReferencedProperties(identifier);
+ if (refProps != null)
+ {
+ return refProps;
+ }
+ }
+ final DataRequest request = new DataRequest(identifier,
DataRequest.GET_REFERENCES);
+
+ try
+ {
+ request.start();
+ if (cache.isEnabled())
+ {
+ // Try first to get the value from the cache since a
+ // request could have been launched just before
+ refProps = cache.getReferencedProperties(identifier);
+ if (refProps != null)
+ {
+ return refProps;
+ }
+ }
+ refProps = super.getReferencesData(identifier, false);
+ if (cache.isEnabled())
+ {
+ cache.addReferencedProperties(identifier, refProps);
+ }
+ return refProps;
+ }
+ finally
+ {
+ request.done();
+ }
+ }
+
+ /**
* Get child PropertyData.
*
* @param nodeData
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-11-02
08:59:39 UTC (rev 3376)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/LinkedWorkspaceStorageCacheImpl.java 2010-11-02
09:39:26 UTC (rev 3377)
@@ -1648,6 +1648,21 @@
/**
* {@inheritDoc}
*/
+ public List<PropertyData> getReferencedProperties(String identifier)
+ {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addReferencedProperties(String identifier, List<PropertyData>
refProperties)
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public List<PropertyData> listChildProperties(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-11-02
08:59:39 UTC (rev 3376)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java 2010-11-02
09:39:26 UTC (rev 3377)
@@ -18,19 +18,6 @@
*/
package org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.Set;
-
-import javax.jcr.RepositoryException;
-import javax.transaction.TransactionManager;
-
import org.exoplatform.container.configuration.ConfigurationManager;
import org.exoplatform.services.jcr.access.AccessControlList;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
@@ -47,6 +34,7 @@
import org.exoplatform.services.jcr.datamodel.PropertyData;
import org.exoplatform.services.jcr.datamodel.QPath;
import org.exoplatform.services.jcr.datamodel.QPathEntry;
+import org.exoplatform.services.jcr.datamodel.ValueData;
import org.exoplatform.services.jcr.impl.Constants;
import org.exoplatform.services.jcr.impl.dataflow.TransientNodeData;
import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
@@ -61,6 +49,21 @@
import org.jboss.cache.config.EvictionRegionConfig;
import org.jboss.cache.eviction.ExpirationAlgorithmConfig;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.transaction.TransactionManager;
+
/**
* Created by The eXo Platform SAS.<p/>
*
@@ -127,6 +130,8 @@
public static final String LOCKS = "$LOCKS".intern();
+ public static final String REFERENCE = "$REFERENCE".intern();
+
public static final String ITEM_DATA = "$data".intern();
public static final String ITEM_ID = "$id".intern();
@@ -137,6 +142,8 @@
protected final Fqn<String> itemsRoot;
+ protected final Fqn<String> refRoot;
+
protected final Fqn<String> nullItemsRoot;
protected final Fqn<String> childNodes;
@@ -336,6 +343,7 @@
JBOSSCACHE_EXPIRATION_DEFAULT));
this.itemsRoot = Fqn.fromRelativeElements(rootFqn, ITEMS);
+ this.refRoot = Fqn.fromRelativeElements(rootFqn, REFERENCE);
this.nullItemsRoot = Fqn.fromRelativeElements(rootFqn, NULL_ITEMS);
this.childNodes = Fqn.fromRelativeElements(rootFqn, CHILD_NODES);
this.childProps = Fqn.fromRelativeElements(rootFqn, CHILD_PROPS);
@@ -346,6 +354,7 @@
this.cache.start();
createResidentNode(childNodes);
+ createResidentNode(refRoot);
createResidentNode(childNodesList);
createResidentNode(childProps);
createResidentNode(childPropsList);
@@ -729,6 +738,89 @@
}
/**
+ * {@inheritDoc}
+ */
+ public List<PropertyData> getReferencedProperties(String identifier)
+ {
+ // get set of property uuids
+ final Set<String> set = (Set<String>)cache.get(makeRefFqn(identifier),
ITEM_LIST);
+ if (set != null)
+ {
+ final List<PropertyData> props = new ArrayList<PropertyData>();
+
+ for (String propId : set)
+ {
+ PropertyData prop = (PropertyData)cache.get(makeItemFqn(propId), ITEM_DATA);
+ if (prop == null)
+ {
+ return null;
+ }
+
+ // add property as many times as has referenced values
+ for (ValueData vdata : prop.getValues())
+ {
+ try
+ {
+ if (new String(vdata.getAsByteArray()).equals(identifier))
+ {
+ props.add(prop);
+ }
+ }
+ catch (IllegalStateException e)
+ {
+ // Do not nothing.
+ }
+ catch (IOException e)
+ {
+ // Do not nothing.
+ }
+ }
+ }
+ return props;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addReferencedProperties(String identifier, List<PropertyData>
refProperties)
+ {
+ boolean inTransaction = cache.isTransactionActive();
+ try
+ {
+ if (!inTransaction)
+ {
+ cache.beginTransaction();
+ }
+
+ cache.setLocal(true);
+
+ // remove previous all
+ cache.removeNode(makeRefFqn(identifier));
+
+ Set<Object> set = new HashSet<Object>();
+ for (PropertyData prop : refProperties)
+ {
+ putProperty(prop, ModifyChildOption.NOT_MODIFY);
+ set.add(prop.getIdentifier());
+ }
+ cache.put(makeRefFqn(identifier), ITEM_LIST, set);
+ }
+ finally
+ {
+ cache.setLocal(false);
+ if (!inTransaction)
+ {
+ cache.commitTransaction();
+ }
+ }
+ }
+
+ /**
* Internal get child properties.
*
* @param parentId String
@@ -771,7 +863,7 @@
public long getSize()
{
// Total number of JBC nodes in the cache - the total amount of resident nodes
- return numNodes(cache.getNode(rootFqn)) - 6;
+ return numNodes(cache.getNode(rootFqn)) - 7;
}
/**
@@ -812,6 +904,17 @@
}
/**
+ * Make Item absolute Fqn, i.e. /$REF/itemID.
+ *
+ * @param itemId String
+ * @return Fqn
+ */
+ protected Fqn<String> makeRefFqn(String itemId)
+ {
+ return Fqn.fromRelativeElements(refRoot, itemId);
+ }
+
+ /**
* Make Item absolute Fqn, i.e. /$NULL_ITEMS/itemID.
*
* @param itemId String
@@ -1022,6 +1125,35 @@
get(prop.getParentIdentifier(),
prop.getQPath().getEntries()[prop.getQPath().getEntries().length - 1]);
+ // add referenced property
+ if (prop.getType() == PropertyType.REFERENCE)
+ {
+ for (ValueData vdata : prop.getValues())
+ {
+ String nodeIdentifier = null;
+ try
+ {
+ nodeIdentifier = new String(vdata.getAsByteArray());
+ }
+ catch (IllegalStateException e)
+ {
+ // Do nothing. Never happens.
+ }
+ catch (IOException e)
+ {
+ // Do nothing. Never happens.
+ }
+
+ Fqn refFqn = makeRefFqn(nodeIdentifier);
+ Set<String> set = (Set<String>)cache.get(refFqn, ITEM_LIST);
+ if (set != null)
+ {
+ set.add(prop.getIdentifier());
+ cache.put(refFqn, ITEM_LIST, set);
+ }
+ }
+ }
+
// add in ITEMS
return (PropertyData)cache.put(makeItemFqn(prop.getIdentifier()), ITEM_DATA,
prop);
}
@@ -1054,6 +1186,8 @@
// remove from CHILD_PROPS_LIST as parent
cache.removeNode(makeChildListFqn(childPropsList, item.getIdentifier()));
}
+
+ cache.removeNode(makeRefFqn(item.getIdentifier()));
}
else
{
@@ -1064,6 +1198,23 @@
// remove from CHILD_PROPS_LIST
cache.removeFromList(makeChildListFqn(childPropsList,
item.getParentIdentifier()), ITEM_LIST, item
.getIdentifier());
+
+ // remove referenced property
+ PropertyData prop = (PropertyData)item;
+ if (prop.getType() == PropertyType.REFERENCE)
+ {
+ // value data is empty on delete, so will try to remove from all lists
+ for (Object child : cache.getChildrenNames(refRoot))
+ {
+ Fqn refFqn = makeRefFqn((String)child);
+ Set<String> set = (Set<String>)cache.get(refFqn, ITEM_LIST);
+ if (set != null && set.contains(prop.getIdentifier()))
+ {
+ set.remove(prop.getIdentifier());
+ cache.put(refFqn, ITEM_LIST, set);
+ }
+ }
+ }
}
// remove from ITEMS
cache.removeNode(makeItemFqn(item.getIdentifier()));
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-11-02
08:59:39 UTC (rev 3376)
+++
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestCacheableWorkspaceDataManager.java 2010-11-02
09:39:26 UTC (rev 3377)
@@ -25,7 +25,6 @@
import org.exoplatform.services.jcr.datamodel.ItemData;
import org.exoplatform.services.jcr.datamodel.ItemType;
import org.exoplatform.services.jcr.datamodel.NodeData;
-import org.exoplatform.services.jcr.datamodel.NullNodeData;
import org.exoplatform.services.jcr.datamodel.PropertyData;
import org.exoplatform.services.jcr.datamodel.QPath;
import org.exoplatform.services.jcr.datamodel.QPathEntry;
@@ -387,6 +386,15 @@
return childNodes != null ? childNodes.size() : -1;
}
+ public List<PropertyData> getReferencedProperties(String identifier)
+ {
+ return null;
+ }
+
+ public void addReferencedProperties(String identifier, List<PropertyData>
refProperties)
+ {
+ }
+
}
private static class MyWorkspaceStorageConnection implements
WorkspaceStorageConnection