Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/XAWorkspace.java =================================================================== --- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/XAWorkspace.java (revision 472064) +++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/XAWorkspace.java (working copy) @@ -53,7 +53,7 @@ * {@inheritDoc} */ protected LocalItemStateManager createItemStateManager(SharedItemStateManager shared) { - return new XAItemStateManager(shared, this); + return new XAItemStateManager(shared, this, rep.getCacheManager()); } /** Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/XASessionImpl.java =================================================================== --- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/XASessionImpl.java (revision 472064) +++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/XASessionImpl.java (working copy) @@ -131,7 +131,7 @@ * Create array that contains all resources that paricipate in this * transactions. Because some resources depend on each other, there is * also a workspace scoped lock resource inserted, that guards the - * entire transaction from deadlocks (see JCR-335) + * entire transaction from deadlocks (see JCR-335) */ txResources = new InternalXAResource[] { ((XAWorkspace) wsp).getXAResourceBegin(), @@ -158,7 +158,7 @@ throws RepositoryException { VersionManagerImpl vMgr = (VersionManagerImpl) rep.getVersionManager(); - return new XAVersionManager(vMgr, rep.getNodeTypeRegistry(), this); + return new XAVersionManager(vMgr, rep.getNodeTypeRegistry(), this, rep.getCacheManager()); } /** Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/ItemStateReferenceCache.java =================================================================== --- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/ItemStateReferenceCache.java (revision 472064) +++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/ItemStateReferenceCache.java (working copy) @@ -66,8 +66,8 @@ * LRUItemStateCache instance as internal secondary * cache. */ - public ItemStateReferenceCache() { - this(new MLRUItemStateCache()); + public ItemStateReferenceCache(CacheManager cacheMgr) { + this(new MLRUItemStateCache(cacheMgr)); } /** Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java =================================================================== --- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java (revision 472064) +++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java (working copy) @@ -70,8 +70,8 @@ * @param factory event state collection factory */ public LocalItemStateManager(SharedItemStateManager sharedStateMgr, - EventStateCollectionFactory factory) { - cache = new ItemStateReferenceCache(); + EventStateCollectionFactory factory, CacheManager cacheMgr) { + cache = new ItemStateReferenceCache(cacheMgr); this.sharedStateMgr = sharedStateMgr; this.factory = factory; Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java =================================================================== --- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java (revision 472064) +++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java (working copy) @@ -196,9 +196,10 @@ public SharedItemStateManager(PersistenceManager persistMgr, NodeId rootNodeId, NodeTypeRegistry ntReg, - boolean usesReferences) + boolean usesReferences, + CacheManager cacheMgr) throws ItemStateException { - cache = new ItemStateReferenceCache(); + cache = new ItemStateReferenceCache(cacheMgr); this.persistMgr = persistMgr; this.ntReg = ntReg; this.usesReferences = usesReferences; Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/MLRUItemStateCache.java =================================================================== --- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/MLRUItemStateCache.java (revision 472064) +++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/MLRUItemStateCache.java (working copy) @@ -62,8 +62,8 @@ * Constructs a new, empty ItemStateCache with a maximum amount * of memory of {@link #DEFAULT_MAX_MEM}. */ - public MLRUItemStateCache() { - this(DEFAULT_MAX_MEM); + public MLRUItemStateCache(CacheManager cacheMgr) { + this(cacheMgr, DEFAULT_MAX_MEM); } /** @@ -72,9 +72,9 @@ * * @param maxMem the maximum amount of memory this cache may use. */ - public MLRUItemStateCache(int maxMem) { + private MLRUItemStateCache(CacheManager cacheMgr, int maxMem) { this.maxMem = maxMem; - CacheManager.getInstance().add(this); + cacheMgr.add(this); } //-------------------------------------------------------< ItemStateCache > Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/XAItemStateManager.java =================================================================== --- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/XAItemStateManager.java (revision 472064) +++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/XAItemStateManager.java (working copy) @@ -86,8 +86,8 @@ * @param factory event state collection factory */ public XAItemStateManager(SharedItemStateManager sharedStateMgr, - EventStateCollectionFactory factory) { - this(sharedStateMgr, factory, DEFAULT_ATTRIBUTE_NAME); + EventStateCollectionFactory factory, CacheManager cacheMgr) { + this(sharedStateMgr, factory, DEFAULT_ATTRIBUTE_NAME, cacheMgr); } /** @@ -99,8 +99,9 @@ */ public XAItemStateManager(SharedItemStateManager sharedStateMgr, EventStateCollectionFactory factory, - String attributeName) { - super(sharedStateMgr, factory); + String attributeName, + CacheManager cacheMgr) { + super(sharedStateMgr, factory, cacheMgr); this.attributeName = attributeName; } Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/CacheManager.java =================================================================== --- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/CacheManager.java (revision 472064) +++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/CacheManager.java (working copy) @@ -40,9 +40,6 @@ /** Logger instance */ private static Logger log = LoggerFactory.getLogger(CacheManager.class); - /** The single instance */ - private static CacheManager instance = new CacheManager(); - /** Amount of memory to distribute accross the caches */ private static final long MAX_MEMORY = 16 * 1024 * 1024; @@ -59,37 +56,53 @@ /** The size of a big object, to detect if a cache is full or not */ private static final int BIG_OBJECT_SIZE = 16 * 1024; - public static CacheManager getInstance() { - return instance; + /** Stop the daemon thread */ + private volatile boolean stop; + + /** The thread that re-distributes the memory */ + private Thread thread; + + /** + * Constructs a new cache manager. + * A daemon thread is started that re-distributes the memory among the caches. + */ + public CacheManager() { + thread = new Thread(this); + thread.setDaemon(true); + thread.setName(getClass().getName()); + thread.start(); } /** - * Constructs a new cache manager. Singleton pattern, so the constructor is private. - * A daemon thread is started. + * Stop re-distributing the memory */ - private CacheManager() { - Thread t = new Thread(this); - t.setDaemon(true); - t.setName(getClass().getName()); - t.start(); + public synchronized void stop() { + stop = true; + try { + thread.interrupt(); + } catch(SecurityException e) { + // ignore (it will give up automatically) + } } /** * Run the (daemon) thread. */ public void run() { - while(true) { + log.info("CacheManager thead started"); + while(!stop) { try { + resizeAll(); + } catch(Throwable e) { + log.error("Error resizing caches", e); + } + try { Thread.sleep(SLEEP); } catch (InterruptedException e) { // ignore } - try { - resizeAll(); - } catch(Throwable e) { - log.error("Error resizing caches", e); - } } + log.info("CacheManager thead stopped"); } /** Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java =================================================================== --- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java (revision 472064) +++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java (working copy) @@ -45,6 +45,7 @@ import org.apache.jackrabbit.core.state.ItemStateException; import org.apache.jackrabbit.core.persistence.PMContext; import org.apache.jackrabbit.core.persistence.PersistenceManager; +import org.apache.jackrabbit.core.state.CacheManager; import org.apache.jackrabbit.core.state.SharedItemStateManager; import org.apache.jackrabbit.core.state.ChangeLog; import org.apache.jackrabbit.core.version.VersionManager; @@ -210,6 +211,11 @@ private final ReadWriteLock shutdownLock = new WriterPreferenceReadWriteLock(); /** + * There is one cache manager per repository that manages the sizes of the caches used. + */ + private final CacheManager cacheMgr = new CacheManager(); + + /** * private constructor * * @param repConfig @@ -321,6 +327,15 @@ } /** + * Get the cache manager of this repository. + * + * @return the cache manager + */ + public CacheManager getCacheManager() { + return cacheMgr; + } + + /** * Creates the version manager. * * @param vConfig the versioning config @@ -341,7 +356,7 @@ ntReg); VersionManagerImpl vMgr = new VersionManagerImpl(pm, fs, ntReg, delegatingDispatcher, - VERSION_STORAGE_NODE_ID, SYSTEM_ROOT_NODE_ID); + VERSION_STORAGE_NODE_ID, SYSTEM_ROOT_NODE_ID, cacheMgr); if (clusterNode != null) { vMgr.setEventChannel(clusterNode.createUpdateChannel()); } @@ -991,6 +1006,9 @@ log.error("error while closing repository file system", e); } + // stop the cache manager thread + cacheMgr.stop(); + // make sure this instance is not used anymore disposed = true; @@ -1703,7 +1721,7 @@ // create item state manager try { itemStateMgr = - new SharedItemStateManager(persistMgr, rootNodeId, ntReg, true); + new SharedItemStateManager(persistMgr, rootNodeId, ntReg, true, cacheMgr); try { itemStateMgr.addVirtualItemStateProvider( vMgr.getVirtualItemStateProvider()); Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java =================================================================== --- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java (revision 472064) +++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java (working copy) @@ -27,6 +27,7 @@ import org.apache.jackrabbit.core.observation.DelegatingObservationDispatcher; import org.apache.jackrabbit.core.observation.EventStateCollection; import org.apache.jackrabbit.core.observation.EventStateCollectionFactory; +import org.apache.jackrabbit.core.state.CacheManager; import org.apache.jackrabbit.core.state.ChangeLog; import org.apache.jackrabbit.core.state.ItemStateException; import org.apache.jackrabbit.core.state.LocalItemStateManager; @@ -129,7 +130,8 @@ public VersionManagerImpl(PersistenceManager pMgr, FileSystem fs, NodeTypeRegistry ntReg, DelegatingObservationDispatcher obsMgr, NodeId rootId, - NodeId rootParentId) throws RepositoryException { + NodeId rootParentId, + CacheManager cacheMgr) throws RepositoryException { try { this.pMgr = pMgr; this.fs = fs; @@ -156,9 +158,9 @@ pMgr.store(cl); } sharedStateMgr = - new VersionItemStateManager(pMgr, rootId, ntReg); + new VersionItemStateManager(pMgr, rootId, ntReg, cacheMgr); - stateMgr = new LocalItemStateManager(sharedStateMgr, escFactory); + stateMgr = new LocalItemStateManager(sharedStateMgr, escFactory, cacheMgr); stateMgr.addListener(this); NodeState nodeState = (NodeState) stateMgr.getItemState(rootId); @@ -515,9 +517,10 @@ public VersionItemStateManager(PersistenceManager persistMgr, NodeId rootNodeId, - NodeTypeRegistry ntReg) + NodeTypeRegistry ntReg, + CacheManager cacheMgr) throws ItemStateException { - super(persistMgr, rootNodeId, ntReg, false); + super(persistMgr, rootNodeId, ntReg, false, cacheMgr); } protected void checkReferentialIntegrity(ChangeLog changes) Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java =================================================================== --- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java (revision 472064) +++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java (working copy) @@ -26,6 +26,7 @@ import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; import org.apache.jackrabbit.core.observation.EventStateCollectionFactory; import org.apache.jackrabbit.core.observation.EventStateCollection; +import org.apache.jackrabbit.core.state.CacheManager; import org.apache.jackrabbit.core.state.ChangeLog; import org.apache.jackrabbit.core.state.ItemState; import org.apache.jackrabbit.core.state.ItemStateException; @@ -96,14 +97,14 @@ * Creates a new instance of this class. */ public XAVersionManager(VersionManagerImpl vMgr, NodeTypeRegistry ntReg, - SessionImpl session) + SessionImpl session, CacheManager cacheMgr) throws RepositoryException { this.vMgr = vMgr; this.ntReg = ntReg; this.session = session; this.stateMgr = new XAItemStateManager(vMgr.getSharedStateMgr(), - this, CHANGE_LOG_ATTRIBUTE_NAME); + this, CHANGE_LOG_ATTRIBUTE_NAME, cacheMgr); NodeState state; try { Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java =================================================================== --- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java (revision 472064) +++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java (working copy) @@ -757,7 +757,7 @@ * @return local item state manager */ protected LocalItemStateManager createItemStateManager(SharedItemStateManager shared) { - return new LocalItemStateManager(shared, this); + return new LocalItemStateManager(shared, this, rep.getCacheManager()); } //------------------------------------------< EventStateCollectionFactory >