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.getItemStateCacheFactory()); } /** 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) @@ -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.getItemStateCacheFactory()); } /** 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(ItemStateCacheFactory cacheFactory) { + this(cacheFactory.newItemStateCache()); } /** Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/Cache.java =================================================================== --- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/Cache.java (revision 472064) +++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/Cache.java (working copy) @@ -52,4 +52,10 @@ * Reset the access counter. */ void resetAccessCount(); + + /** + * Add a listener to this cache that is informed after a number of accesses. + */ + void setAccessListener(CacheAccessListener listener); + } 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, ItemStateCacheFactory cacheFactory) { + cache = new ItemStateReferenceCache(cacheFactory); 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, + ItemStateCacheFactory cacheFactory) throws ItemStateException { - cache = new ItemStateReferenceCache(); + cache = new ItemStateReferenceCache(cacheFactory); 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) @@ -53,6 +53,9 @@ /** the access count */ private long accessCount = 0; + /** the cache access listeners */ + private CacheAccessListener accessListener; + /** * A cache for ItemState instances */ @@ -72,9 +75,8 @@ * * @param maxMem the maximum amount of memory this cache may use. */ - public MLRUItemStateCache(int maxMem) { + private MLRUItemStateCache(int maxMem) { this.maxMem = maxMem; - CacheManager.getInstance().add(this); } //-------------------------------------------------------< ItemStateCache > @@ -215,6 +217,11 @@ private void touch() { accessCount++; + if ((accessCount & CacheAccessListener.ACCESS_INTERVAL_MASK) == 0) { + if (accessListener != null) { + accessListener.cacheAccessed(); + } + } } /** @@ -267,8 +274,17 @@ } /** - * Internal cache entry + * Set the cache access listener. Only one listener per cache is supported. + * + * @param listener the new listener */ + public void setAccessListener(CacheAccessListener listener) { + this.accessListener = listener; + } + + /** + * Internal cache entry. + */ private static class Entry { private final ItemState state; @@ -284,4 +300,5 @@ size = 64 + state.calculateMemoryFootprint(); } } + } Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/ManagedMLRUItemStateCacheFactory.java =================================================================== --- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/ManagedMLRUItemStateCacheFactory.java (revision 0) +++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/ManagedMLRUItemStateCacheFactory.java (revision 0) @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.core.state; + +/** + * This class constructs new MLRUItemStateCache. + * This class adds the new caches to the cache manager, + * and links the caches to the cache manager. + */ +public class ManagedMLRUItemStateCacheFactory implements ItemStateCacheFactory { + + /** The cache manager. */ + private CacheManager cacheMgr; + + /** + * Construct a new factory using a cache manager. + * + * @param cacheMgr the cache manager + */ + public ManagedMLRUItemStateCacheFactory(CacheManager cacheMgr) { + this.cacheMgr = cacheMgr; + } + + /** + * Create a new cache instance and link it to the cache manager. + */ + public ItemStateCache newItemStateCache() { + MLRUItemStateCache cache = new MLRUItemStateCache(); + cacheMgr.add(cache); + cache.setAccessListener(cacheMgr); + return cache; + } + +} Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/CacheAccessListener.java =================================================================== --- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/CacheAccessListener.java (revision 0) +++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/CacheAccessListener.java (revision 0) @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.core.state; + +/** + * The cache access listener can be registerd to a class. + * From time to time, the method cacheAccess is called. + */ +public interface CacheAccessListener { + + /** + * The access listener is only called each x accesses. + * This is a bitmap (all bits set). + */ + static final int ACCESS_INTERVAL_MASK = 127; + + /** + * The cache calls this method after a number of accessed. + */ + void cacheAccessed(); + +} Index: C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/ItemStateCacheFactory.java =================================================================== --- C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/ItemStateCacheFactory.java (revision 0) +++ C:/dev/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/ItemStateCacheFactory.java (revision 0) @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.core.state; + +/** + * An item state cache factory to construct new item state caches. + */ +public interface ItemStateCacheFactory { + + /** + * Construct a new item state cache. + * + * @return the new cache + */ + ItemStateCache newItemStateCache(); +} 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, ItemStateCacheFactory cacheFactory) { + this(sharedStateMgr, factory, DEFAULT_ATTRIBUTE_NAME, cacheFactory); } /** @@ -99,8 +99,9 @@ */ public XAItemStateManager(SharedItemStateManager sharedStateMgr, EventStateCollectionFactory factory, - String attributeName) { - super(sharedStateMgr, factory); + String attributeName, + ItemStateCacheFactory cacheFactory) { + super(sharedStateMgr, factory, cacheFactory); 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) @@ -24,71 +24,62 @@ import org.slf4j.LoggerFactory; /** - * This class manages the size of the caches used in Jackrabbit. - * The combined size of all caches must be limited to avoid out of memory problems. - * The available memory is dynamically distributed across the caches each second. - * This class tries to calculates the best cache sizes by comparing the access counts of each cache, - * and the used memory. The idea is, the more a cache is accessed, the more memory it should get, - * while the cache should not shrink too quickly. A minimum and maximum size per cache is defined as well. - * After distributing the memory in this way, there might be some unused memory - * (if one or more caches did not use some of the allocated memory). - * This unused memory is distributed evenly across the full caches. + * This class manages the size of the caches used in Jackrabbit. The combined + * size of all caches must be limited to avoid out of memory problems. The + * available memory is dynamically distributed across the caches each second. + * This class tries to calculates the best cache sizes by comparing the access + * counts of each cache, and the used memory. The idea is, the more a cache is + * accessed, the more memory it should get, while the cache should not shrink + * too quickly. A minimum and maximum size per cache is defined as well. After + * distributing the memory in this way, there might be some unused memory (if + * one or more caches did not use some of the allocated memory). This unused + * memory is distributed evenly across the full caches. * */ -public class CacheManager implements Runnable { +public class CacheManager implements CacheAccessListener { - /** Logger instance */ + /** The 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 */ + /** The amount of memory to distribute accross the caches. */ private static final long MAX_MEMORY = 16 * 1024 * 1024; - /** Minimum size of a cache */ + /** The minimum size of a cache. */ private static final long MIN_MEMORY_PER_CACHE = 128 * 1024; - /** Maximum memory per cache (unless, there is some unused memory) */ + /** The maximum memory per cache (unless, there is some unused memory). */ private static final long MAX_MEMORY_PER_CACHE = 4 * 1024 * 1024; + + /** The set of caches (weakly referenced). */ private WeakHashMap caches = new WeakHashMap(); - /** Rebalance the caches each ... milliseconds */ + /** Rebalance the caches each ... milliseconds at most. */ private static final int SLEEP = 1000; - /** The size of a big object, to detect if a cache is full or not */ + /** 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; - } + /** The last time the caches where resized. */ + private volatile long nextResize = System.currentTimeMillis() + SLEEP; /** - * Constructs a new cache manager. Singleton pattern, so the constructor is private. - * A daemon thread is started. + * After one of the caches is accessed a number of times, this method is called. + * Resize the caches if required. */ - private CacheManager() { - Thread t = new Thread(this); - t.setDaemon(true); - t.setName(getClass().getName()); - t.start(); - } - - /** - * Run the (daemon) thread. - */ - public void run() { - while(true) { - try { - Thread.sleep(SLEEP); - } catch (InterruptedException e) { - // ignore + public void cacheAccessed() { + long now = System.currentTimeMillis(); + if (now < nextResize) { + return; + } + synchronized (this) { + // the previous test was not synchronized (for speed) + // so we need another synchronized test + if (now < nextResize) { + return; } - try { - resizeAll(); - } catch(Throwable e) { - log.error("Error resizing caches", e); - } + nextResize = now + SLEEP; + resizeAll(); + nextResize = System.currentTimeMillis() + SLEEP; } } @@ -96,43 +87,46 @@ * Re-calcualte the maximum memory for each cache, and set the new limits. * */ - private synchronized void resizeAll() { + private void resizeAll() { // get strong references // entries in a weak hash map may disappear any time // so can't use size() / keySet() directly // only using the iterator guarantees that we don't get null references ArrayList list = new ArrayList(); - for(Iterator it = caches.keySet().iterator(); it.hasNext(); ) { + for (Iterator it = caches.keySet().iterator(); it.hasNext();) { list.add(it.next()); } - if(list.size() == 0) { + if (list.size() == 0) { // nothing to do return; } CacheInfo[] infos = new CacheInfo[list.size()]; - for(int i=0; i 0 && fullCacheCount > 0) { - for(int i=0; i 0 && fullCacheCount > 0) { + for (int i = 0; i < infos.length; i++) { CacheInfo info = infos[i]; - if(info.wasFull()) { - info.setMemory(info.getMemory() + unusedMemory / fullCacheCount); + if (info.wasFull()) { + info.setMemory(info.getMemory() + unusedMemory + / fullCacheCount); } } } - // set the new limit and reset the access counters - for(int i=0; i= memory; + wasFull = (memoryUsed + BIG_OBJECT_SIZE) >= memory; } boolean wasFull() { 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,9 @@ 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.ItemStateCacheFactory; +import org.apache.jackrabbit.core.state.ManagedMLRUItemStateCacheFactory; import org.apache.jackrabbit.core.state.SharedItemStateManager; import org.apache.jackrabbit.core.state.ChangeLog; import org.apache.jackrabbit.core.version.VersionManager; @@ -210,6 +213,16 @@ 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(); + + /** + * There is only one item state cache factory + */ + private final ItemStateCacheFactory cacheFactory = new ManagedMLRUItemStateCacheFactory(cacheMgr); + + /** * private constructor * * @param repConfig @@ -321,6 +334,15 @@ } /** + * Get the item state cache factory of this repository. + * + * @return the cache manager + */ + public ItemStateCacheFactory getItemStateCacheFactory() { + return cacheFactory; + } + + /** * Creates the version manager. * * @param vConfig the versioning config @@ -341,7 +363,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, cacheFactory); if (clusterNode != null) { vMgr.setEventChannel(clusterNode.createUpdateChannel()); } @@ -1703,7 +1725,7 @@ // create item state manager try { itemStateMgr = - new SharedItemStateManager(persistMgr, rootNodeId, ntReg, true); + new SharedItemStateManager(persistMgr, rootNodeId, ntReg, true, cacheFactory); 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) @@ -21,24 +21,25 @@ import org.apache.jackrabbit.core.NodeImpl; import org.apache.jackrabbit.core.PropertyId; import org.apache.jackrabbit.core.SessionImpl; -import org.apache.jackrabbit.core.persistence.PersistenceManager; +import org.apache.jackrabbit.core.cluster.UpdateEventChannel; +import org.apache.jackrabbit.core.cluster.UpdateEventListener; import org.apache.jackrabbit.core.fs.FileSystem; import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; 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.persistence.PersistenceManager; import org.apache.jackrabbit.core.state.ChangeLog; +import org.apache.jackrabbit.core.state.ItemState; +import org.apache.jackrabbit.core.state.ItemStateCacheFactory; import org.apache.jackrabbit.core.state.ItemStateException; +import org.apache.jackrabbit.core.state.ItemStateListener; import org.apache.jackrabbit.core.state.LocalItemStateManager; import org.apache.jackrabbit.core.state.NodeReferences; import org.apache.jackrabbit.core.state.NodeReferencesId; import org.apache.jackrabbit.core.state.NodeState; import org.apache.jackrabbit.core.state.PropertyState; import org.apache.jackrabbit.core.state.SharedItemStateManager; -import org.apache.jackrabbit.core.state.ItemStateListener; -import org.apache.jackrabbit.core.state.ItemState; -import org.apache.jackrabbit.core.cluster.UpdateEventChannel; -import org.apache.jackrabbit.core.cluster.UpdateEventListener; import org.apache.jackrabbit.core.value.InternalValue; import org.apache.jackrabbit.core.virtual.VirtualItemStateProvider; import org.apache.jackrabbit.name.MalformedPathException; @@ -129,7 +130,8 @@ public VersionManagerImpl(PersistenceManager pMgr, FileSystem fs, NodeTypeRegistry ntReg, DelegatingObservationDispatcher obsMgr, NodeId rootId, - NodeId rootParentId) throws RepositoryException { + NodeId rootParentId, + ItemStateCacheFactory cacheFactory) 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, cacheFactory); - stateMgr = new LocalItemStateManager(sharedStateMgr, escFactory); + stateMgr = new LocalItemStateManager(sharedStateMgr, escFactory, cacheFactory); stateMgr.addListener(this); NodeState nodeState = (NodeState) stateMgr.getItemState(rootId); @@ -515,9 +517,10 @@ public VersionItemStateManager(PersistenceManager persistMgr, NodeId rootNodeId, - NodeTypeRegistry ntReg) + NodeTypeRegistry ntReg, + ItemStateCacheFactory cacheFactory) throws ItemStateException { - super(persistMgr, rootNodeId, ntReg, false); + super(persistMgr, rootNodeId, ntReg, false, cacheFactory); } 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) @@ -24,17 +24,18 @@ import org.apache.jackrabbit.core.TransactionContext; import org.apache.jackrabbit.core.TransactionException; import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; +import org.apache.jackrabbit.core.observation.EventStateCollection; import org.apache.jackrabbit.core.observation.EventStateCollectionFactory; -import org.apache.jackrabbit.core.observation.EventStateCollection; import org.apache.jackrabbit.core.state.ChangeLog; import org.apache.jackrabbit.core.state.ItemState; +import org.apache.jackrabbit.core.state.ItemStateCacheFactory; import org.apache.jackrabbit.core.state.ItemStateException; +import org.apache.jackrabbit.core.state.ItemStateListener; import org.apache.jackrabbit.core.state.NoSuchItemStateException; import org.apache.jackrabbit.core.state.NodeReferences; import org.apache.jackrabbit.core.state.NodeReferencesId; import org.apache.jackrabbit.core.state.NodeState; import org.apache.jackrabbit.core.state.XAItemStateManager; -import org.apache.jackrabbit.core.state.ItemStateListener; import org.apache.jackrabbit.core.virtual.VirtualItemStateProvider; import org.apache.jackrabbit.core.virtual.VirtualNodeState; import org.apache.jackrabbit.core.virtual.VirtualPropertyState; @@ -96,14 +97,14 @@ * Creates a new instance of this class. */ public XAVersionManager(VersionManagerImpl vMgr, NodeTypeRegistry ntReg, - SessionImpl session) + SessionImpl session, ItemStateCacheFactory cacheFactory) 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, cacheFactory); 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) @@ -21,13 +21,12 @@ import org.apache.jackrabbit.core.lock.LockManager; import org.apache.jackrabbit.core.observation.EventStateCollection; import org.apache.jackrabbit.core.observation.EventStateCollectionFactory; -import org.apache.jackrabbit.core.observation.ObservationDispatcher; import org.apache.jackrabbit.core.observation.ObservationManagerImpl; import org.apache.jackrabbit.core.query.QueryManagerImpl; import org.apache.jackrabbit.core.state.LocalItemStateManager; import org.apache.jackrabbit.core.state.SharedItemStateManager; -import org.apache.jackrabbit.core.version.VersionImpl; import org.apache.jackrabbit.core.version.DateVersionSelector; +import org.apache.jackrabbit.core.version.VersionImpl; import org.apache.jackrabbit.core.version.VersionSelector; import org.apache.jackrabbit.core.xml.ImportHandler; import org.apache.jackrabbit.core.xml.Importer; @@ -757,7 +756,7 @@ * @return local item state manager */ protected LocalItemStateManager createItemStateManager(SharedItemStateManager shared) { - return new LocalItemStateManager(shared, this); + return new LocalItemStateManager(shared, this, rep.getItemStateCacheFactory()); } //------------------------------------------< EventStateCollectionFactory >