Author: tolusha
Date: 2010-09-07 09:00:55 -0400 (Tue, 07 Sep 2010)
New Revision: 3065
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/IndexerCacheLoader.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/IndexerSingletonStoreCacheLoader.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexChangesFilter.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexInfos.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexUpdateMonitor.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/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/ParentNodeEvictionActionPolicy.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/jbosscache/ExoJBossCacheFactory.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestJBossCacheWorkspaceStorageCache.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/lab/cluster/prepare/TestIndexUpdateMonitor.java
Log:
EXOJCR--942: Reply on JBC regions to avoid having too many JBC instances
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java 2010-09-07
09:36:10 UTC (rev 3064)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java 2010-09-07
13:00:55 UTC (rev 3065)
@@ -51,6 +51,7 @@
import org.exoplatform.services.jcr.impl.storage.jdbc.DialectDetecter;
import org.exoplatform.services.jcr.impl.util.io.PrivilegedCacheHelper;
import org.exoplatform.services.jcr.jbosscache.ExoJBossCacheFactory;
+import org.exoplatform.services.jcr.jbosscache.ExoJBossCacheFactory.CacheType;
import org.exoplatform.services.jcr.observation.ExtendedEvent;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
@@ -217,7 +218,7 @@
InitialContextInitializer context, TransactionManager transactionManager,
ConfigurationManager cfm)
throws RepositoryConfigurationException, RepositoryException
{
- lockRoot = Fqn.fromElements(LOCKS);
+ lockRoot = Fqn.fromElements(config.getUniqueName(), LOCKS);
List<SimpleParameterEntry> paramenerts =
config.getLockManager().getParameters();
@@ -258,13 +259,16 @@
cache = factory.createCache(config.getLockManager());
- PrivilegedCacheHelper.create(cache);
+ Fqn<String> rootFqn = Fqn.fromElements(config.getUniqueName());
+ cache = ExoJBossCacheFactory.getUniqueInstance(CacheType.LOCK_CACHE, rootFqn,
cache);
+ cache.create();
+ if (cache.getCacheStatus().startAllowed())
+ {
+ // Add the cache loader needed to prevent TimeoutException
+ addCacheLoader();
+ cache.start();
+ }
- // Add the cache loader needed to prevent TimeoutException
- addCacheLoader();
-
- PrivilegedCacheHelper.start(cache);
-
createStructuredNode(lockRoot);
// Context recall is a workaround of JDBCCacheLoader starting.
@@ -480,7 +484,7 @@
{
public Integer execute(Object arg)
{
- return ((CacheSPI<Serializable, Object>)cache).getNumberOfNodes() - 1;
+ return ((CacheSPI<Serializable,
Object>)cache).getNode(lockRoot).getChildrenDirect().size();
}
};
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java 2010-09-07
09:36:10 UTC (rev 3064)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java 2010-09-07
13:00:55 UTC (rev 3065)
@@ -26,6 +26,7 @@
import org.exoplatform.services.jcr.config.QueryHandlerEntry;
import org.exoplatform.services.jcr.config.QueryHandlerParams;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
import org.exoplatform.services.jcr.core.nodetype.NodeTypeDataManager;
import org.exoplatform.services.jcr.dataflow.ItemDataConsumer;
import org.exoplatform.services.jcr.dataflow.ItemState;
@@ -136,6 +137,11 @@
protected IndexerChangesFilter changesFilter;
/**
+ * The unique name of the related workspace
+ */
+ protected final String wsId;
+
+ /**
* Creates a new <code>SearchManager</code>.
*
* @param config
@@ -159,12 +165,12 @@
* @throws RepositoryConfigurationException
*/
- public SearchManager(QueryHandlerEntry config, NamespaceRegistryImpl nsReg,
NodeTypeDataManager ntReg,
+ public SearchManager(WorkspaceEntry wsConfig, QueryHandlerEntry config,
NamespaceRegistryImpl nsReg, NodeTypeDataManager ntReg,
WorkspacePersistentDataManager itemMgr, SystemSearchManagerHolder
parentSearchManager,
DocumentReaderService extractor, ConfigurationManager cfm, final
RepositoryIndexSearcherHolder indexSearcherHolder)
throws RepositoryException, RepositoryConfigurationException
{
-
+ this.wsId = wsConfig.getUniqueName();
this.extractor = extractor;
indexSearcherHolder.addIndexSearcher(this);
this.config = config;
@@ -843,4 +849,9 @@
return false;
}
+ public String getWsId()
+ {
+ return wsId;
+ }
+
}
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java 2010-09-07
09:36:10 UTC (rev 3064)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java 2010-09-07
13:00:55 UTC (rev 3065)
@@ -20,6 +20,7 @@
import org.exoplatform.services.document.DocumentReaderService;
import org.exoplatform.services.jcr.config.QueryHandlerEntry;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.WorkspaceEntry;
import org.exoplatform.services.jcr.core.nodetype.NodeTypeDataManager;
import org.exoplatform.services.jcr.datamodel.NodeData;
import org.exoplatform.services.jcr.datamodel.QPath;
@@ -56,11 +57,11 @@
public static final String INDEX_DIR_SUFFIX = "system";
- public SystemSearchManager(QueryHandlerEntry config, NamespaceRegistryImpl nsReg,
NodeTypeDataManager ntReg,
+ public SystemSearchManager(WorkspaceEntry wsConfig, QueryHandlerEntry config,
NamespaceRegistryImpl nsReg, NodeTypeDataManager ntReg,
WorkspacePersistentDataManager itemMgr, DocumentReaderService service,
ConfigurationManager cfm,
RepositoryIndexSearcherHolder indexSearcherHolder) throws RepositoryException,
RepositoryConfigurationException
{
- super(config, nsReg, ntReg, itemMgr, null, service, cfm, indexSearcherHolder);
+ super(wsConfig, config, nsReg, ntReg, itemMgr, null, service, cfm,
indexSearcherHolder);
}
@Override
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/IndexerCacheLoader.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/IndexerCacheLoader.java 2010-09-07
09:36:10 UTC (rev 3064)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/IndexerCacheLoader.java 2010-09-07
13:00:55 UTC (rev 3065)
@@ -29,6 +29,7 @@
import org.jboss.cache.Modification;
import java.io.IOException;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -42,16 +43,13 @@
*/
public class IndexerCacheLoader extends AbstractWriteOnlyCacheLoader
{
- private final Log log =
ExoLogger.getLogger("exo.jcr.component.core.IndexerCacheLoader");
+ private static final Log log =
ExoLogger.getLogger("exo.jcr.component.core.IndexerCacheLoader");
- private SearchManager searchManager;
+ /**
+ * A map of all the indexers that has been registered
+ */
+ private final Map<Fqn<String>, Indexer> indexers = new
HashMap<Fqn<String>, Indexer>();
- private SearchManager parentSearchManager;
-
- private QueryHandler handler;
-
- private QueryHandler parentHandler;
-
private volatile IndexerIoModeHandler modeHandler;
/**
@@ -62,9 +60,9 @@
{
// do nothing. Everything is done on prepare phase.
}
-
+
/**
- * Inject dependencies needed for CacheLoader: SearchManagers and QueryHandlers.
+ * This method will register a new Indexer according to the given parameters.
*
* @param searchManager
* @param parentSearchManager
@@ -72,13 +70,11 @@
* @param parentHandler
* @throws RepositoryConfigurationException
*/
- public void init(SearchManager searchManager, SearchManager parentSearchManager,
QueryHandler handler,
+ public void register(SearchManager searchManager, SearchManager parentSearchManager,
QueryHandler handler,
QueryHandler parentHandler) throws RepositoryConfigurationException
{
- this.searchManager = searchManager;
- this.parentSearchManager = parentSearchManager;
- this.handler = handler;
- this.parentHandler = parentHandler;
+ indexers.put(Fqn.fromElements(searchManager.getWsId()), new Indexer(searchManager,
parentSearchManager, handler,
+ parentHandler));
}
/**
@@ -96,7 +92,8 @@
ChangesFilterListsWrapper wrapper = (ChangesFilterListsWrapper)value;
try
{
- updateIndex(wrapper.getAddedNodes(), wrapper.getRemovedNodes(),
wrapper.getParentAddedNodes(), wrapper
+ Indexer indexer = indexers.get(name.getParent());
+ indexer.updateIndex(wrapper.getAddedNodes(), wrapper.getRemovedNodes(),
wrapper.getParentAddedNodes(), wrapper
.getParentRemovedNodes());
}
finally
@@ -172,63 +169,86 @@
}
/**
- * Flushes lists of added/removed nodes to SearchManagers, starting indexing.
- *
- * @param addedNodes
- * @param removedNodes
- * @param parentAddedNodes
- * @param parentRemovedNodes
+ * This class will update the indexes of the related workspace
*/
- protected void updateIndex(Set<String> addedNodes, Set<String>
removedNodes, Set<String> parentAddedNodes,
- Set<String> parentRemovedNodes)
+ private static class Indexer
{
- // pass lists to search manager
- if (searchManager != null && (addedNodes.size() > 0 ||
removedNodes.size() > 0))
+
+ private final SearchManager searchManager;
+
+ private final SearchManager parentSearchManager;
+
+ private final QueryHandler handler;
+
+ private final QueryHandler parentHandler;
+
+ public Indexer(SearchManager searchManager, SearchManager parentSearchManager,
QueryHandler handler,
+ QueryHandler parentHandler) throws RepositoryConfigurationException
{
- try
+ this.searchManager = searchManager;
+ this.parentSearchManager = parentSearchManager;
+ this.handler = handler;
+ this.parentHandler = parentHandler;
+ }
+ /**
+ * Flushes lists of added/removed nodes to SearchManagers, starting indexing.
+ *
+ * @param addedNodes
+ * @param removedNodes
+ * @param parentAddedNodes
+ * @param parentRemovedNodes
+ */
+ protected void updateIndex(Set<String> addedNodes, Set<String>
removedNodes, Set<String> parentAddedNodes,
+ Set<String> parentRemovedNodes)
+ {
+ // pass lists to search manager
+ if (searchManager != null && (addedNodes.size() > 0 ||
removedNodes.size() > 0))
{
- searchManager.updateIndex(removedNodes, addedNodes);
- }
- catch (RepositoryException e)
- {
- log.error("Error indexing changes " + e, e);
- }
- catch (IOException e)
- {
- log.error("Error indexing changes " + e, e);
try
{
- handler.logErrorChanges(removedNodes, addedNodes);
+ searchManager.updateIndex(removedNodes, addedNodes);
}
- catch (IOException ioe)
+ catch (RepositoryException e)
{
- log.warn("Exception occure when errorLog writed. Error log is not
complete. " + ioe, ioe);
+ log.error("Error indexing changes " + e, e);
}
+ catch (IOException e)
+ {
+ log.error("Error indexing changes " + e, e);
+ try
+ {
+ handler.logErrorChanges(removedNodes, addedNodes);
+ }
+ catch (IOException ioe)
+ {
+ log.warn("Exception occure when errorLog writed. Error log is not
complete. " + ioe, ioe);
+ }
+ }
}
- }
- // pass lists to parent search manager
- if (parentSearchManager != null && (parentAddedNodes.size() > 0 ||
parentRemovedNodes.size() > 0))
- {
- try
+ // pass lists to parent search manager
+ if (parentSearchManager != null && (parentAddedNodes.size() > 0 ||
parentRemovedNodes.size() > 0))
{
- parentSearchManager.updateIndex(parentRemovedNodes, parentAddedNodes);
- }
- catch (RepositoryException e)
- {
- log.error("Error indexing changes " + e, e);
- }
- catch (IOException e)
- {
- log.error("Error indexing changes " + e, e);
try
{
- parentHandler.logErrorChanges(removedNodes, addedNodes);
+ parentSearchManager.updateIndex(parentRemovedNodes, parentAddedNodes);
}
- catch (IOException ioe)
+ catch (RepositoryException e)
{
- log.warn("Exception occure when errorLog writed. Error log is not
complete. " + ioe, ioe);
+ log.error("Error indexing changes " + e, e);
}
+ catch (IOException e)
+ {
+ log.error("Error indexing changes " + e, e);
+ try
+ {
+ parentHandler.logErrorChanges(removedNodes, addedNodes);
+ }
+ catch (IOException ioe)
+ {
+ log.warn("Exception occure when errorLog writed. Error log is not
complete. " + ioe, ioe);
+ }
+ }
}
- }
+ }
}
}
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/IndexerSingletonStoreCacheLoader.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/IndexerSingletonStoreCacheLoader.java 2010-09-07
09:36:10 UTC (rev 3064)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/IndexerSingletonStoreCacheLoader.java 2010-09-07
13:00:55 UTC (rev 3065)
@@ -64,32 +64,36 @@
if (debugEnabled)
log.debug("start pushing in-memory state to cache cacheLoader
collection");
- final Set<String> removedNodes = new HashSet<String>();
- final Set<String> addedNodes = new HashSet<String>();
- final Set<String> parentRemovedNodes = new HashSet<String>();
- final Set<String> parentAddedNodes = new HashSet<String>();
// merging all lists stored in memory
Collection<NodeSPI> children = cache.getRoot().getChildren();
- for (NodeSPI aChildren : children)
+ for (NodeSPI wsChildren : children)
{
- Fqn<?> fqn = aChildren.getFqn();
- Object value = cache.get(fqn, JBossCacheIndexChangesFilter.LISTWRAPPER);
- if (value != null && value instanceof ChangesFilterListsWrapper)
+ final Set<String> removedNodes = new HashSet<String>();
+ final Set<String> addedNodes = new HashSet<String>();
+ final Set<String> parentRemovedNodes = new HashSet<String>();
+ final Set<String> parentAddedNodes = new HashSet<String>();
+ Collection<NodeSPI> changes = wsChildren.getChildren();
+ for (NodeSPI aChildren : changes)
{
- // get wrapper object
- ChangesFilterListsWrapper listsWrapper =
(ChangesFilterListsWrapper)value;
- // get search manager lists
- addedNodes.addAll(listsWrapper.getAddedNodes());
- removedNodes.addAll(listsWrapper.getRemovedNodes());
- // parent search manager lists
- parentAddedNodes.addAll(listsWrapper.getParentAddedNodes());
- parentRemovedNodes.addAll(listsWrapper.getParentAddedNodes());
- };
+ Fqn<?> fqn = aChildren.getFqn();
+ Object value = cache.get(fqn,
JBossCacheIndexChangesFilter.LISTWRAPPER);
+ if (value != null && value instanceof
ChangesFilterListsWrapper)
+ {
+ // get wrapper object
+ ChangesFilterListsWrapper listsWrapper =
(ChangesFilterListsWrapper)value;
+ // get search manager lists
+ addedNodes.addAll(listsWrapper.getAddedNodes());
+ removedNodes.addAll(listsWrapper.getRemovedNodes());
+ // parent search manager lists
+ parentAddedNodes.addAll(listsWrapper.getParentAddedNodes());
+ parentRemovedNodes.addAll(listsWrapper.getParentAddedNodes());
+ }
+ }
+ //TODO: recover logic is here, lists are: removedNodes and addedNodes
String id = IdGenerator.generate();
+ String id = IdGenerator.generate();
+ cache.put(Fqn.fromRelativeElements(wsChildren.getFqn(), id),
JBossCacheIndexChangesFilter.LISTWRAPPER, new ChangesFilterListsWrapper(addedNodes,
+ removedNodes, parentAddedNodes, parentRemovedNodes));
}
- //TODO: recover logic is here, lists are: removedNodes and addedNodes
String id = IdGenerator.generate();
- String id = IdGenerator.generate();
- cache.put(id, JBossCacheIndexChangesFilter.LISTWRAPPER, new
ChangesFilterListsWrapper(addedNodes,
- removedNodes, parentAddedNodes, parentRemovedNodes));
if (debugEnabled)
log.debug("in-memory state passed to cache cacheLoader
successfully");
return null;
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexChangesFilter.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexChangesFilter.java 2010-09-07
09:36:10 UTC (rev 3064)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexChangesFilter.java 2010-09-07
13:00:55 UTC (rev 3065)
@@ -30,15 +30,19 @@
import org.exoplatform.services.jcr.impl.core.query.SearchManager;
import org.exoplatform.services.jcr.impl.util.io.PrivilegedCacheHelper;
import org.exoplatform.services.jcr.jbosscache.ExoJBossCacheFactory;
+import org.exoplatform.services.jcr.jbosscache.ExoJBossCacheFactory.CacheType;
import org.exoplatform.services.jcr.util.IdGenerator;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.jboss.cache.Cache;
import org.jboss.cache.CacheException;
import org.jboss.cache.CacheSPI;
+import org.jboss.cache.Fqn;
import org.jboss.cache.config.CacheLoaderConfig;
import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
import
org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig.SingletonStoreConfig;
+import org.jboss.cache.config.Configuration.CacheMode;
+import org.jboss.cache.loader.SingletonStoreCacheLoader.PushStateException;
import java.io.IOException;
import java.io.Serializable;
@@ -61,6 +65,8 @@
private final Cache<Serializable, Object> cache;
+ private final Fqn<String> rootFqn;
+
public static final String LISTWRAPPER = "$lists".intern();
/**
@@ -77,12 +83,10 @@
super(searchManager, parentSearchManager, config, indexingTree, parentIndexingTree,
handler, parentHandler, cfm);
// create cache using custom factory
ExoJBossCacheFactory<Serializable, Object> factory = new
ExoJBossCacheFactory<Serializable, Object>(cfm);
- this.cache = factory.createCache(config);
+ Cache<Serializable, Object> initCache = factory.createCache(config);
// initialize IndexerCacheLoader
IndexerCacheLoader indexerCacheLoader = new IndexerCacheLoader();
- // inject dependencies
- indexerCacheLoader.init(searchManager, parentSearchManager, handler,
parentHandler);
// set SingltonStoreCacheLoader
SingletonStoreConfig singletonStoreConfig = new SingletonStoreConfig();
singletonStoreConfig.setSingletonStoreClass(IndexerSingletonStoreCacheLoader.class.getName());
@@ -114,31 +118,53 @@
cacheLoaderConfig.setPassivation(false);
cacheLoaderConfig.addIndividualCacheLoaderConfig(individualCacheLoaderConfig);
// insert CacheLoaderConfig
- this.cache.getConfiguration().setCacheLoaderConfig(cacheLoaderConfig);
+ initCache.getConfiguration().setCacheLoaderConfig(cacheLoaderConfig);
+ this.rootFqn = Fqn.fromElements(searchManager.getWsId());
+ this.cache = ExoJBossCacheFactory.getUniqueInstance(CacheType.INDEX_CACHE, rootFqn,
initCache);
+ this.cache.create();
+ this.cache.start();
- PrivilegedCacheHelper.create(cache);
- PrivilegedCacheHelper.start(cache);
-
// start will invoke cache listener which will notify handler that mode is changed
IndexerIoMode ioMode =
((CacheSPI)cache).getRPCManager().isCoordinator() ? IndexerIoMode.READ_WRITE :
IndexerIoMode.READ_ONLY;
+
+ // Could have change of cache
+ IndexerSingletonStoreCacheLoader issCacheLoader =
+
(IndexerSingletonStoreCacheLoader)((CacheSPI)cache).getCacheLoaderManager().getCacheLoader();
+
+ // This code make it possible to use the JBossCacheIndexChangesFilter in
+ // a non-cluster environment
+ if (cache.getConfiguration().getCacheMode() == CacheMode.LOCAL)
+ {
+ // Activate the cache loader
+ try
+ {
+ issCacheLoader.activeStatusChanged(true);
+ }
+ catch (PushStateException e)
+ {
+ // ignore me;
+ }
+ }
+ indexerCacheLoader = (IndexerCacheLoader)issCacheLoader.getCacheLoader();
+
+ indexerCacheLoader.register(searchManager, parentSearchManager, handler,
parentHandler);
IndexerIoModeHandler modeHandler = indexerCacheLoader.getModeHandler();
handler.setIndexerIoModeHandler(modeHandler);
parentHandler.setIndexerIoModeHandler(modeHandler);
if (!parentHandler.isInitialized())
{
- parentHandler.setIndexInfos(new JBossCacheIndexInfos(cache, true,
modeHandler));
- parentHandler.setIndexUpdateMonitor(new JBossCacheIndexUpdateMonitor(cache,
true, modeHandler));
+ parentHandler.setIndexInfos(new JBossCacheIndexInfos(rootFqn, cache, true,
modeHandler));
+ parentHandler.setIndexUpdateMonitor(new JBossCacheIndexUpdateMonitor(rootFqn,
cache, true, modeHandler));
parentHandler.init();
}
if (!handler.isInitialized())
{
- handler.setIndexInfos(new JBossCacheIndexInfos(cache, false, modeHandler));
- handler.setIndexUpdateMonitor(new JBossCacheIndexUpdateMonitor(cache, false,
modeHandler));
+ handler.setIndexInfos(new JBossCacheIndexInfos(rootFqn, cache, false,
modeHandler));
+ handler.setIndexUpdateMonitor(new JBossCacheIndexUpdateMonitor(rootFqn, cache,
false, modeHandler));
handler.init();
}
-
}
/**
@@ -151,8 +177,8 @@
String id = IdGenerator.generate();
try
{
- PrivilegedCacheHelper.put(cache, id, LISTWRAPPER, new
ChangesFilterListsWrapper(addedNodes, removedNodes,
- parentAddedNodes, parentRemovedNodes));
+ PrivilegedCacheHelper.put(cache, Fqn.fromRelativeElements(rootFqn, id),
LISTWRAPPER,
+ new ChangesFilterListsWrapper(addedNodes, removedNodes, parentAddedNodes,
parentRemovedNodes));
}
catch (CacheException e)
{
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexInfos.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexInfos.java 2010-09-07
09:36:10 UTC (rev 3064)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexInfos.java 2010-09-07
13:00:55 UTC (rev 3065)
@@ -84,16 +84,16 @@
/**
* @param cache instance of JbossCache that is used to deliver index names
*/
- public JBossCacheIndexInfos(Cache<Serializable, Object> cache, boolean system,
IndexerIoModeHandler modeHandler)
+ public JBossCacheIndexInfos(Fqn<String> rootFqn, Cache<Serializable,
Object> cache, boolean system, IndexerIoModeHandler modeHandler)
{
- this(DEFALUT_NAME, cache, system, modeHandler);
+ this(rootFqn, DEFALUT_NAME, cache, system, modeHandler);
}
/**
* @param fileName where index names are stored.
* @param cache instance of JbossCache that is used to deliver index names
*/
- public JBossCacheIndexInfos(String fileName, Cache<Serializable, Object> cache,
boolean system,
+ public JBossCacheIndexInfos(Fqn<String> rootFqn, String fileName,
Cache<Serializable, Object> cache, boolean system,
IndexerIoModeHandler modeHandler)
{
super(fileName);
@@ -101,7 +101,7 @@
this.modeHandler = modeHandler;
modeHandler.addIndexerIoModeListener(this);
// store parsed FQN to avoid it's parsing each time cache event is generated
- namesFqn = Fqn.fromString(system ? SYSINDEX_NAMES : INDEX_NAMES);
+ namesFqn = Fqn.fromRelativeElements(rootFqn, system ? SYSINDEX_NAMES :
INDEX_NAMES);
Node<Serializable, Object> cacheRoot = cache.getRoot();
// prepare cache structures
if (!cacheRoot.hasChild(namesFqn))
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexUpdateMonitor.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexUpdateMonitor.java 2010-09-07
09:36:10 UTC (rev 3064)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexUpdateMonitor.java 2010-09-07
13:00:55 UTC (rev 3065)
@@ -78,14 +78,14 @@
/**
* @param cache instance of JbossCache that is used to deliver index names
*/
- public JBossCacheIndexUpdateMonitor(Cache<Serializable, Object> cache, boolean
system,
+ public JBossCacheIndexUpdateMonitor(Fqn<String> rootFqn, Cache<Serializable,
Object> cache, boolean system,
IndexerIoModeHandler modeHandler)
{
this.cache = cache;
this.modeHandler = modeHandler;
this.listeners = new CopyOnWriteArrayList<IndexUpdateMonitorListener>();
// store parsed FQN to avoid it's parsing each time cache event is generated
- this.parametersFqn = Fqn.fromString(system ? INDEX_PARAMETERS :
SYSINDEX_PARAMETERS);
+ this.parametersFqn = Fqn.fromRelativeElements(rootFqn, system ? INDEX_PARAMETERS :
SYSINDEX_PARAMETERS);
modeHandler.addIndexerIoModeListener(this);
Node<Serializable, Object> cacheRoot = cache.getRoot();
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-09-07
09:36:10 UTC (rev 3064)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java 2010-09-07
13:00:55 UTC (rev 3065)
@@ -36,6 +36,7 @@
import org.exoplatform.services.jcr.impl.dataflow.TransientNodeData;
import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
import org.exoplatform.services.jcr.jbosscache.ExoJBossCacheFactory;
+import org.exoplatform.services.jcr.jbosscache.ExoJBossCacheFactory.CacheType;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.transaction.TransactionService;
@@ -305,16 +306,19 @@
LOG.info("Using BufferedJBossCache compatible with Expiration
algorithm.");
}
+ Fqn<String> rootFqn = Fqn.fromElements(wsConfig.getUniqueName());
+ parentCache = ExoJBossCacheFactory.getUniqueInstance(CacheType.JCR_CACHE, rootFqn,
parentCache);
+
// 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()
+ new BufferedJBossCache(parentCache, useExpiration, wsConfig.getCache()
.getParameterTime(JBOSSCACHE_EXPIRATION, JBOSSCACHE_EXPIRATION_DEFAULT));
- this.itemsRoot = Fqn.fromElements(ITEMS);
- this.childNodes = Fqn.fromElements(CHILD_NODES);
- this.childProps = Fqn.fromElements(CHILD_PROPS);
- this.childNodesList = Fqn.fromElements(CHILD_NODES_LIST);
- this.childPropsList = Fqn.fromElements(CHILD_PROPS_LIST);
+ this.itemsRoot = Fqn.fromRelativeElements(rootFqn, ITEMS);
+ this.childNodes = Fqn.fromRelativeElements(rootFqn, CHILD_NODES);
+ this.childProps = Fqn.fromRelativeElements(rootFqn, CHILD_PROPS);
+ this.childNodesList = Fqn.fromRelativeElements(rootFqn, CHILD_NODES_LIST);
+ this.childPropsList = Fqn.fromRelativeElements(rootFqn, CHILD_PROPS_LIST);
this.cache.create();
this.cache.start();
@@ -722,7 +726,7 @@
public long getSize()
{
// Total number of JBC nodes in the cache - the total amount of resident nodes
- return cache.getNumberOfNodes() - 5;
+ return cache.getNumberOfNodes() - 5 * cache.getRoot().getChildrenNames().size();
}
/**
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/ParentNodeEvictionActionPolicy.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/ParentNodeEvictionActionPolicy.java 2010-09-07
09:36:10 UTC (rev 3064)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/ParentNodeEvictionActionPolicy.java 2010-09-07
13:00:55 UTC (rev 3065)
@@ -63,15 +63,15 @@
log.debug("Unable to evict " + fqn, e);
result = false;
}
- if (fqn.size() != 3)
+ if (fqn.size() != 4)
{
return result;
}
try
{
Fqn parentFqn = fqn.getParent();
- if (parentFqn.get(0).equals(JBossCacheWorkspaceStorageCache.CHILD_NODES)
- || parentFqn.get(0).equals(JBossCacheWorkspaceStorageCache.CHILD_PROPS))
+ if (parentFqn.get(1).equals(JBossCacheWorkspaceStorageCache.CHILD_NODES)
+ || parentFqn.get(1).equals(JBossCacheWorkspaceStorageCache.CHILD_PROPS))
{
// The expected data structure is of type
$CHILD_NODES/${node-id}/${sub-node-name} or
// $CHILD_PROPS/${node-id}/${sub-property-name}
@@ -83,7 +83,7 @@
if (node != null)
{
Set<Object> names = node.getChildrenNamesDirect();
- if (names.isEmpty() || (names.size() == 1 &&
names.contains(fqn.get(2))))
+ if (names.isEmpty() || (names.size() == 1 &&
names.contains(fqn.get(3))))
{
if (log.isTraceEnabled())
log.trace("Evicting Fqn " + fqn);
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/jbosscache/ExoJBossCacheFactory.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/jbosscache/ExoJBossCacheFactory.java 2010-09-07
09:36:10 UTC (rev 3064)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/jbosscache/ExoJBossCacheFactory.java 2010-09-07
13:00:55 UTC (rev 3065)
@@ -18,6 +18,8 @@
*/
package org.exoplatform.services.jcr.jbosscache;
+import org.exoplatform.container.ExoContainer;
+import org.exoplatform.container.ExoContainerContext;
import org.exoplatform.container.configuration.ConfigurationManager;
import org.exoplatform.services.jcr.config.MappedParametrizedObjectEntry;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
@@ -27,12 +29,19 @@
import org.jboss.cache.Cache;
import org.jboss.cache.CacheFactory;
import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Region;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.EvictionConfig;
+import org.jboss.cache.config.EvictionRegionConfig;
import org.jgroups.JChannelFactory;
import java.io.IOException;
import java.io.InputStream;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.util.HashMap;
+import java.util.Map;
import javax.transaction.TransactionManager;
@@ -60,13 +69,20 @@
public static final String JGROUPS_MUX_ENABLED =
"jgroups-multiplexer-stack";
+ /**
+ * A Map that contains all the registered JBC instances, ordered by
+ * {@link ExoContainer} instances, {@link CacheType} and JBC Configuration.
+ */
+ private static Map<ExoContainer, Map<CacheType, Map<Configuration,
Cache>>> CACHES =
+ new HashMap<ExoContainer, Map<CacheType, Map<Configuration,
Cache>>>();
+
private final TemplateConfigurationHelper configurationHelper;
private final TransactionManager transactionManager;
private ConfigurationManager configurationManager;
- private final Log log =
ExoLogger.getLogger("exo.jcr.component.core.ExoJBossCacheFactory");
+ private static final Log log =
ExoLogger.getLogger("exo.jcr.component.core.ExoJBossCacheFactory");
/**
* Creates ExoJbossCacheFactory with provided configuration transaction managers.
@@ -156,6 +172,7 @@
// Create and inject multiplexer factory
JChannelFactory muxFactory = new JChannelFactory();
muxFactory.setMultiplexerConfig(configurationManager.getResource(jgroupsConfigurationFilePath));
+
cache.getConfiguration().getRuntimeConfig().setMuxChannelFactory(muxFactory);
log.info("Multiplexer stack successfully enabled for the
cache.");
}
@@ -188,4 +205,84 @@
}
return cache;
}
+
+ /**
+ * Add a region to the given cache
+ * @param fqn the roof fqn of the region to add
+ * @param cache the cache to which we want to add the region
+ * @param cfg the configuration from which the Eviction Algorithm Config must be
extracted
+ */
+ private static <K, V> void addEvictionRegion(Fqn<String> fqn, Cache<K,
V> cache, Configuration cfg)
+ {
+ EvictionConfig ec = cfg.getEvictionConfig();
+ // Create the region and set the config
+ Region region = cache.getRegion(fqn, true);
+ if (ec != null && ec.getDefaultEvictionRegionConfig() != null
+ && ec.getDefaultEvictionRegionConfig().getEvictionAlgorithmConfig() !=
null)
+ {
+ EvictionRegionConfig erc =
+ new EvictionRegionConfig(fqn,
ec.getDefaultEvictionRegionConfig().getEvictionAlgorithmConfig());
+ region.setEvictionRegionConfig(erc);
+ }
+ }
+
+ /**
+ * Try to find if a Cache of the same type (i.e. their {@link Configuration} are
equals)
+ * has already been registered for the same current container and the same {@link
CacheType}.
+ * If no cache has been registered, we register the given cache otherwise we
+ * use the previously registered cache and we create a dedicated region to the shared
cache
+ * for the given cache.
+ * @param cacheType The type of the target cache
+ * @param rootFqn the rootFq
+ * @param cache the cache to register
+ * @return the unique instance of the same cache registered
+ * @throws RepositoryConfigurationException
+ */
+ @SuppressWarnings("unchecked")
+ public static synchronized <K, V> Cache<K, V> getUniqueInstance(CacheType
cacheType, Fqn<String> rootFqn,
+ Cache<K, V> cache) throws RepositoryConfigurationException
+ {
+ ExoContainer container = ExoContainerContext.getCurrentContainer();
+ Map<CacheType, Map<Configuration, Cache>> allCacheTypes =
CACHES.get(container);
+ if (allCacheTypes == null)
+ {
+ allCacheTypes = new HashMap<CacheType, Map<Configuration,
Cache>>();
+ CACHES.put(container, allCacheTypes);
+ }
+ Map<Configuration, Cache> caches = allCacheTypes.get(cacheType);
+ if (caches == null)
+ {
+ caches = new HashMap<Configuration, Cache>();
+ allCacheTypes.put(cacheType, caches);
+ }
+ Configuration cfg;
+ try
+ {
+ cfg = cache.getConfiguration().clone();
+ }
+ catch (CloneNotSupportedException e)
+ {
+ throw new RepositoryConfigurationException("Cannot clone the
configuration.", e);
+ }
+ if (caches.containsKey(cfg))
+ {
+ cache = caches.get(cfg);
+ if (log.isInfoEnabled())
+ log.info("The region " + rootFqn + " has been registered for a
cache of type " + cacheType
+ + " and the container " + container.getContext().getName());
+ }
+ else
+ {
+ caches.put(cfg, cache);
+ }
+ addEvictionRegion(rootFqn, cache, cfg);
+ return cache;
+ }
+
+ /**
+ * All the known cache types
+ */
+ public enum CacheType {
+ JCR_CACHE, INDEX_CACHE, LOCK_CACHE
+ };
}
Modified:
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestJBossCacheWorkspaceStorageCache.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestJBossCacheWorkspaceStorageCache.java 2010-09-07
09:36:10 UTC (rev 3064)
+++
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/dataflow/persistent/TestJBossCacheWorkspaceStorageCache.java 2010-09-07
13:00:55 UTC (rev 3065)
@@ -49,6 +49,7 @@
CacheEntry entry = new CacheEntry(list);
WorkspaceEntry workspaceEntry = new WorkspaceEntry();
+ workspaceEntry.setUniqueName("WS_UUID");
workspaceEntry.setCache(entry);
return new JBossCacheWorkspaceStorageCache(workspaceEntry,
transactionService == null ? null : transactionService, new
ConfigurationManagerImpl());
Modified:
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/lab/cluster/prepare/TestIndexUpdateMonitor.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/lab/cluster/prepare/TestIndexUpdateMonitor.java 2010-09-07
09:36:10 UTC (rev 3064)
+++
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/lab/cluster/prepare/TestIndexUpdateMonitor.java 2010-09-07
13:00:55 UTC (rev 3065)
@@ -29,6 +29,7 @@
import org.jboss.cache.Cache;
import org.jboss.cache.CacheFactory;
import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.Fqn;
import java.io.Serializable;
@@ -58,7 +59,7 @@
super.setUp();
cache = createCache();
indexUpdateMonitor =
- new JBossCacheIndexUpdateMonitor(cache, false, new
IndexerIoModeHandler(IndexerIoMode.READ_WRITE));
+ new JBossCacheIndexUpdateMonitor(Fqn.fromString("root"),cache, false,
new IndexerIoModeHandler(IndexerIoMode.READ_WRITE));
}
/**