On 28 May 2014 18:06, <rmannibu...@apache.org> wrote: > Author: rmannibucau > Date: Wed May 28 17:06:12 2014 > New Revision: 1598071 > > URL: http://svn.apache.org/r1598071 > Log: > using reentrant locks instead of old synchronized
-1 This commit mixes two completely different changes: - re-entrant locks - addition of LogHelper I think the LogHelper class is a bad idea. It is also not thread-safe. If the cache is enabled, then it is not possible to change the logging level during a run. > Added: > > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/logger/ > > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/logger/LogHelper.java > Modified: > > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/LRUMapJCS.java > > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCache.java > > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/AbstractDoubleLinkedListMemoryCache.java > > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/AbstractMemoryCache.java > > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/struct/LRUMap.java > > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/struct/SingleLinkedList.java > > Modified: > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/LRUMapJCS.java > URL: > http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/LRUMapJCS.java?rev=1598071&r1=1598070&r2=1598071&view=diff > ============================================================================== > --- > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/LRUMapJCS.java > (original) > +++ > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/LRUMapJCS.java > Wed May 28 17:06:12 2014 > @@ -19,6 +19,7 @@ package org.apache.commons.jcs.auxiliary > * under the License. > */ > > +import org.apache.commons.jcs.utils.logger.LogHelper; > import org.apache.commons.jcs.utils.struct.LRUMap; > import org.apache.commons.logging.Log; > import org.apache.commons.logging.LogFactory; > @@ -35,6 +36,7 @@ public class LRUMapJCS<K, V> > > /** The logger */ > private static final Log log = LogFactory.getLog( LRUMapJCS.class ); > + private static final LogHelper LOG_HELPER = new LogHelper(log); > > /** > * This creates an unbounded version. > @@ -69,7 +71,7 @@ public class LRUMapJCS<K, V> > @Override > protected void processRemovedLRU(K key, V value) > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "Removing key [" + key + "] from key store, value [" > + value + "]" ); > log.debug( "Key store size [" + this.size() + "]" ); > > Modified: > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCache.java > URL: > http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCache.java?rev=1598071&r1=1598070&r2=1598071&view=diff > ============================================================================== > --- > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCache.java > (original) > +++ > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCache.java > Wed May 28 17:06:12 2014 > @@ -46,6 +46,7 @@ import org.apache.commons.jcs.engine.sta > import org.apache.commons.jcs.engine.stats.behavior.ICacheStats; > import org.apache.commons.jcs.engine.stats.behavior.IStatElement; > import org.apache.commons.jcs.engine.stats.behavior.IStats; > +import org.apache.commons.jcs.utils.logger.LogHelper; > import org.apache.commons.logging.Log; > import org.apache.commons.logging.LogFactory; > > @@ -70,6 +71,7 @@ public class CompositeCache<K, V> > { > /** log instance */ > private static final Log log = LogFactory.getLog( CompositeCache.class ); > + private static final LogHelper LOG_HELPER = new LogHelper(log); > > /** > * EventQueue for handling element events. Lazy initialized. One for > each region. To be more efficient, the manager > @@ -228,7 +230,7 @@ public class CompositeCache<K, V> > throw new IllegalArgumentException( "key cannot be a GroupId " + > " for a put operation" ); > } > > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "Updating memory cache " + cacheElement.getKey() ); > } > @@ -271,7 +273,7 @@ public class CompositeCache<K, V> > // You could run a database cache as either a remote or a local disk. > // The types would describe the purpose. > > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > if ( auxCaches.length > 0 ) > { > @@ -287,7 +289,7 @@ public class CompositeCache<K, V> > { > ICache<K, V> aux = auxCaches[i]; > > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "Auxilliary cache type: " + aux.getCacheType() ); > } > @@ -300,7 +302,7 @@ public class CompositeCache<K, V> > // SEND TO REMOTE STORE > if ( aux.getCacheType() == CacheType.REMOTE_CACHE ) > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "ce.getElementAttributes().getIsRemote() = " > + cacheElement.getElementAttributes().getIsRemote() > ); > @@ -313,7 +315,7 @@ public class CompositeCache<K, V> > // need to make sure the group cache understands that > // the key is a group attribute on update > aux.update( cacheElement ); > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "Updated remote store for " + > cacheElement.getKey() + cacheElement ); > } > @@ -329,7 +331,7 @@ public class CompositeCache<K, V> > { > // lateral can't do the checking since it is dependent on the > // cache region restrictions > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "lateralcache in aux list: cattr " + > cacheAttr.isUseLateral() ); > } > @@ -339,7 +341,7 @@ public class CompositeCache<K, V> > // Currently always multicast even if the value is > // unchanged, to cause the cache item to move to the > front. > aux.update( cacheElement ); > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "updated lateral cache for " + > cacheElement.getKey() ); > } > @@ -348,7 +350,7 @@ public class CompositeCache<K, V> > // update disk if the usage pattern permits > else if ( aux.getCacheType() == CacheType.DISK_CACHE ) > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "diskcache in aux list: cattr " + > cacheAttr.isUseDisk() ); > } > @@ -357,7 +359,7 @@ public class CompositeCache<K, V> > && cacheElement.getElementAttributes().getIsSpool() ) > { > aux.update( cacheElement ); > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "updated disk cache for " + > cacheElement.getKey() ); > } > @@ -414,14 +416,14 @@ public class CompositeCache<K, V> > { > // swallow > } > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "spoolToDisk done for: " + ce.getKey() + > " on disk cache[" + i + "]" ); > } > } > else > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "DiskCache avaialbe, but JCS is not > configured to use the DiskCache as a swap." ); > } > @@ -483,7 +485,7 @@ public class CompositeCache<K, V> > > boolean found = false; > > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "get: key = " + key + ", localOnly = " + localOnly ); > } > @@ -500,7 +502,7 @@ public class CompositeCache<K, V> > // Found in memory cache > if ( isExpired( element ) ) > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( cacheAttr.getCacheName() + " - Memory > cache hit, but element expired" ); > } > @@ -513,7 +515,7 @@ public class CompositeCache<K, V> > } > else > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( cacheAttr.getCacheName() + " - Memory > cache hit" ); > } > @@ -539,7 +541,7 @@ public class CompositeCache<K, V> > > if ( !localOnly || cacheType == > CacheType.DISK_CACHE ) > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "Attempting to get from aux > [" + aux.getCacheName() + "] which is of type: " > + cacheType ); > @@ -555,7 +557,7 @@ public class CompositeCache<K, V> > } > } > > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "Got CacheElement: " + element ); > } > @@ -565,7 +567,7 @@ public class CompositeCache<K, V> > { > if ( isExpired( element ) ) > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( cacheAttr.getCacheName() > + " - Aux cache[" + i + "] hit, but element expired." ); > } > @@ -582,7 +584,7 @@ public class CompositeCache<K, V> > } > else > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( cacheAttr.getCacheName() > + " - Aux cache[" + i + "] hit" ); > } > @@ -610,7 +612,7 @@ public class CompositeCache<K, V> > { > missCountNotFound++; > > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( cacheAttr.getCacheName() + " - Miss" ); > } > @@ -666,7 +668,7 @@ public class CompositeCache<K, V> > { > Map<K, ICacheElement<K, V>> elements = new HashMap<K, > ICacheElement<K, V>>(); > > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "get: key = " + keys + ", localOnly = " + localOnly ); > } > @@ -693,7 +695,7 @@ public class CompositeCache<K, V> > { > missCountNotFound += keys.size() - elements.size(); > > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( cacheAttr.getCacheName() + " - " + ( keys.size() > - elements.size() ) + " Misses" ); > } > @@ -725,7 +727,7 @@ public class CompositeCache<K, V> > // Found in memory cache > if ( isExpired( element ) ) > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( cacheAttr.getCacheName() + " - Memory > cache hit, but element expired" ); > } > @@ -737,7 +739,7 @@ public class CompositeCache<K, V> > } > else > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( cacheAttr.getCacheName() + " - Memory > cache hit" ); > } > @@ -777,7 +779,7 @@ public class CompositeCache<K, V> > > if ( !localOnly || cacheType == CacheType.DISK_CACHE ) > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "Attempting to get from aux [" + > aux.getCacheName() + "] which is of type: " > + cacheType ); > @@ -793,7 +795,7 @@ public class CompositeCache<K, V> > } > } > > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "Got CacheElements: " + elementsFromAuxiliary > ); > } > @@ -859,7 +861,7 @@ public class CompositeCache<K, V> > { > Map<K, ICacheElement<K, V>> elements = new HashMap<K, > ICacheElement<K, V>>(); > > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "get: pattern [" + pattern + "], localOnly = " + > localOnly ); > } > @@ -932,7 +934,7 @@ public class CompositeCache<K, V> > > if ( !localOnly || cacheType == CacheType.DISK_CACHE ) > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "Attempting to get from aux [" + > aux.getCacheName() + "] which is of type: " > + cacheType ); > @@ -947,7 +949,7 @@ public class CompositeCache<K, V> > log.error( "Error getting from aux", e ); > } > > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "Got CacheElements: " + > elementsFromAuxiliary ); > } > @@ -983,7 +985,7 @@ public class CompositeCache<K, V> > { > if ( isExpired( element ) ) > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( cacheAttr.getCacheName() + " - Aux > cache[" + i + "] hit, but element expired." ); > } > @@ -999,7 +1001,7 @@ public class CompositeCache<K, V> > } > else > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( cacheAttr.getCacheName() + " - Aux > cache[" + i + "] hit" ); > } > @@ -1028,7 +1030,7 @@ public class CompositeCache<K, V> > } > else > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "Skipping memory update since no items are > allowed in memory" ); > } > @@ -1175,7 +1177,7 @@ public class CompositeCache<K, V> > } > try > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "Removing " + key + " from cacheType" + > cacheType ); > } > @@ -1234,7 +1236,7 @@ public class CompositeCache<K, V> > { > memCache.removeAll(); > > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "Removed All keys from the memory cache." ); > } > @@ -1253,7 +1255,7 @@ public class CompositeCache<K, V> > { > try > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "Removing All keys from cacheType" + > aux.getCacheType() ); > } > @@ -1416,7 +1418,7 @@ public class CompositeCache<K, V> > } > } > } > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "Called save for [" + cacheAttr.getCacheName() + "]" > ); > } > @@ -1621,7 +1623,7 @@ public class CompositeCache<K, V> > > if ( maxLifeSeconds != -1 && ( timestamp - createTime ) > ( > maxLifeSeconds * timeFactorForMilliseconds) ) > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "Exceeded maxLife: " + element.getKey() ); > } > @@ -1640,7 +1642,7 @@ public class CompositeCache<K, V> > > if ( ( idleTime != -1 ) && ( timestamp - lastAccessTime ) > > idleTime * timeFactorForMilliseconds ) > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.info( "Exceeded maxIdle: " + element.getKey() ); > } > @@ -1675,7 +1677,7 @@ public class CompositeCache<K, V> > ArrayList<IElementEventHandler> eventHandlers = > element.getElementAttributes().getElementEventHandlers(); > if ( eventHandlers != null ) > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "Element Handlers are registered. Create event > type " + eventType ); > } > > Modified: > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/AbstractDoubleLinkedListMemoryCache.java > URL: > http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/AbstractDoubleLinkedListMemoryCache.java?rev=1598071&r1=1598070&r2=1598071&view=diff > ============================================================================== > --- > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/AbstractDoubleLinkedListMemoryCache.java > (original) > +++ > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/AbstractDoubleLinkedListMemoryCache.java > Wed May 28 17:06:12 2014 > @@ -28,6 +28,7 @@ import org.apache.commons.jcs.engine.sta > import org.apache.commons.jcs.engine.stats.Stats; > import org.apache.commons.jcs.engine.stats.behavior.IStatElement; > import org.apache.commons.jcs.engine.stats.behavior.IStats; > +import org.apache.commons.jcs.utils.logger.LogHelper; > import org.apache.commons.jcs.utils.struct.DoubleLinkedList; > import org.apache.commons.logging.Log; > import org.apache.commons.logging.LogFactory; > @@ -41,6 +42,8 @@ import java.util.Map; > import java.util.Map.Entry; > import java.util.Set; > import java.util.concurrent.ConcurrentHashMap; > +import java.util.concurrent.locks.Lock; > +import java.util.concurrent.locks.ReentrantLock; > > /** > * This class contains methods that are common to memory caches using the > double linked list, such > @@ -58,18 +61,19 @@ public abstract class AbstractDoubleLink > > /** The logger. */ > private static final Log log = LogFactory.getLog( > AbstractDoubleLinkedListMemoryCache.class ); > + private static final LogHelper LOG_HELPER = new LogHelper(log); > > /** thread-safe double linked list for lru */ > protected DoubleLinkedList<MemoryElementDescriptor<K, V>> list; // TODO > privatise > > /** number of hits */ > - private int hitCnt = 0; > + private volatile int hitCnt = 0; > > /** number of misses */ > - private int missCnt = 0; > + private volatile int missCnt = 0; > > /** number of puts */ > - private int putCnt = 0; > + private volatile int putCnt = 0; > > /** > * For post reflection creation initialization. > @@ -77,11 +81,19 @@ public abstract class AbstractDoubleLink > * @param hub > */ > @Override > - public synchronized void initialize( CompositeCache<K, V> hub ) > + public void initialize( CompositeCache<K, V> hub ) > { > - super.initialize( hub ); > - list = new DoubleLinkedList<MemoryElementDescriptor<K, V>>(); > - log.info( "initialized MemoryCache for " + cacheName ); > + lock.lock(); > + try > + { > + super.initialize(hub); > + list = new DoubleLinkedList<MemoryElementDescriptor<K, V>>(); > + log.info("initialized MemoryCache for " + cacheName); > + } > + finally > + { > + lock.unlock(); > + } > } > > /** > @@ -110,17 +122,24 @@ public abstract class AbstractDoubleLink > public final void update( ICacheElement<K, V> ce ) > throws IOException > { > - putCnt++; > + lock.lock(); > + try > + { > + putCnt++; > > - MemoryElementDescriptor<K, V> newNode = adjustListForUpdate( ce ); > + MemoryElementDescriptor<K, V> newNode = adjustListForUpdate(ce); > > - // this should be synchronized if we were not using a > ConcurrentHashMap > - MemoryElementDescriptor<K, V> oldNode = map.put( > newNode.ce.getKey(), newNode ); > + // this should be synchronized if we were not using a > ConcurrentHashMap > + MemoryElementDescriptor<K, V> oldNode = > map.put(newNode.ce.getKey(), newNode); > > - // If the node was the same as an existing node, remove it. > - if ( oldNode != null && newNode.ce.getKey().equals( > oldNode.ce.getKey() ) ) > + // If the node was the same as an existing node, remove it. > + if (oldNode != null && > newNode.ce.getKey().equals(oldNode.ce.getKey())) { > + list.remove(oldNode); > + } > + } > + finally > { > - list.remove( oldNode ); > + lock.unlock(); > } > > // If we are over the max spool some > @@ -153,7 +172,7 @@ public abstract class AbstractDoubleLink > return; > } > > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "In memory limit reached, spooling" ); > } > @@ -161,7 +180,7 @@ public abstract class AbstractDoubleLink > // Write the last 'chunkSize' items to disk. > int chunkSizeCorrected = Math.min( size, chunkSize ); > > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "About to spool to disk cache, map size: " + size + > ", max objects: " > + this.cacheAttributes.getMaxObjects() + ", items to spool: > " + chunkSizeCorrected ); > @@ -175,7 +194,7 @@ public abstract class AbstractDoubleLink > spoolLastElement(); > } > > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "update: After spool map size: " + map.size() + " > linked list size = " + dumpCacheSize() ); > } > @@ -194,7 +213,7 @@ public abstract class AbstractDoubleLink > { > ICacheElement<K, V> ce = null; > > - final boolean debugEnabled = log.isDebugEnabled(); > + final boolean debugEnabled = LOG_HELPER.isDebugEnabled();; > > if (debugEnabled) > { > @@ -205,19 +224,37 @@ public abstract class AbstractDoubleLink > > if ( me != null ) > { > - ce = me.ce; > - hitCnt++; > + lock.lock(); > + try > + { > + ce = me.ce; > + hitCnt++; > + > + // ABSTRACT > + adjustListForGet( me ); > + } > + finally > + { > + lock.unlock(); > + } > + > if (debugEnabled) > { > log.debug( cacheName + ": LRUMemoryCache hit for " + > ce.getKey() ); > } > - > - // ABSTRACT > - adjustListForGet( me ); > } > else > { > - missCnt++; > + lock.lock(); > + try > + { > + missCnt++; > + } > + finally > + { > + lock.unlock(); > + } > + > if (debugEnabled) > { > log.debug( cacheName + ": LRUMemoryCache miss for " + key ); > @@ -274,22 +311,28 @@ public abstract class AbstractDoubleLink > final MemoryElementDescriptor<K, V> last = list.getLast(); > if ( last != null ) > { > - toSpool = last.ce; > - if ( toSpool != null ) > + lock.lock(); > + try > { > - cache.spoolToDisk( last.ce ); > - if ( map.remove( last.ce.getKey() ) == null ) > + toSpool = last.ce; > + if (toSpool != null) { > + cache.spoolToDisk(last.ce); > + if (map.remove(last.ce.getKey()) == null) { > + log.warn("update: remove failed for key: " > + + last.ce.getKey()); > + verifyCache(); > + } > + } > + else > { > - log.warn( "update: remove failed for key: " > - + last.ce.getKey() ); > - verifyCache(); > + throw new Error("update: last.ce is null!"); > } > + list.remove(last); > } > - else > + finally > { > - throw new Error( "update: last.ce is null!" ); > + lock.unlock(); > } > - list.remove(last); > } > else > { > @@ -320,7 +363,7 @@ public abstract class AbstractDoubleLink > public boolean remove( K key ) > throws IOException > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "removing item for key: " + key ); > } > @@ -336,11 +379,19 @@ public abstract class AbstractDoubleLink > Map.Entry<K, MemoryElementDescriptor<K, V>> entry = > itr.next(); > K k = entry.getKey(); > > - if ( k instanceof String && ( (String) k ).startsWith( > key.toString() ) ) > + if (k instanceof String && ((String) > k).startsWith(key.toString())) > { > - list.remove( entry.getValue() ); > - itr.remove(); > - removed = true; > + lock.lock(); > + try > + { > + list.remove(entry.getValue()); > + itr.remove(); > + removed = true; > + } > + finally > + { > + lock.unlock(); > + } > } > } > } > @@ -355,21 +406,36 @@ public abstract class AbstractDoubleLink > if ( k instanceof GroupAttrName && > > ((GroupAttrName<?>)k).groupId.equals(((GroupAttrName<?>)key).groupId)) > { > - list.remove( entry.getValue() ); > - itr.remove(); > - removed = true; > + lock.lock(); > + try > + { > + list.remove(entry.getValue()); > + itr.remove(); > + removed = true; > + } > + finally > + { > + lock.unlock(); > + } > } > } > } > else > { > // remove single item. > - MemoryElementDescriptor<K, V> me = map.remove( key ); > - > - if ( me != null ) > + lock.lock(); > + try > { > - list.remove( me ); > - removed = true; > + MemoryElementDescriptor<K, V> me = map.remove(key); > + if (me != null) > + { > + list.remove(me); > + removed = true; > + } > + } > + finally > + { > + lock.unlock(); > } > } > > @@ -386,8 +452,16 @@ public abstract class AbstractDoubleLink > public void removeAll() > throws IOException > { > - list.removeAll(); > - map.clear(); > + lock.lock(); > + try > + { > + list.removeAll(); > + map.clear(); > + } > + finally > + { > + lock.unlock(); > + } > } > > // --------------------------- internal methods (linked list > implementation) > @@ -399,10 +473,18 @@ public abstract class AbstractDoubleLink > */ > protected MemoryElementDescriptor<K, V> addFirst( ICacheElement<K, V> ce > ) > { > - MemoryElementDescriptor<K, V> me = new MemoryElementDescriptor<K, > V>( ce ); > - list.addFirst( me ); > - verifyCache( ce.getKey() ); > - return me; > + lock.lock(); > + try > + { > + MemoryElementDescriptor<K, V> me = new > MemoryElementDescriptor<K, V>(ce); > + list.addFirst(me); > + verifyCache(ce.getKey()); > + return me; > + } > + finally > + { > + lock.unlock(); > + } > } > > /** > @@ -413,10 +495,18 @@ public abstract class AbstractDoubleLink > */ > protected MemoryElementDescriptor<K, V> addLast( ICacheElement<K, V> ce ) > { > - MemoryElementDescriptor<K, V> me = new MemoryElementDescriptor<K, > V>( ce ); > - list.addLast( me ); > - verifyCache( ce.getKey() ); > - return me; > + lock.lock(); > + try > + { > + MemoryElementDescriptor<K, V> me = new > MemoryElementDescriptor<K, V>(ce); > + list.addLast(me); > + verifyCache(ce.getKey()); > + return me; > + } > + finally > + { > + lock.unlock(); > + } > } > > // ---------------------------------------------------------- debug > methods > @@ -451,7 +541,7 @@ public abstract class AbstractDoubleLink > @SuppressWarnings("unchecked") // No generics for public fields > protected void verifyCache() > { > - if ( !log.isDebugEnabled() ) > + if ( !LOG_HELPER.isDebugEnabled() ) > { > return; > } > @@ -534,7 +624,7 @@ public abstract class AbstractDoubleLink > @SuppressWarnings("unchecked") // No generics for public fields > private void verifyCache( K key ) > { > - if ( !log.isDebugEnabled() ) > + if ( !LOG_HELPER.isDebugEnabled() ) > { > return; > } > @@ -684,12 +774,7 @@ public abstract class AbstractDoubleLink > @Override > public Set<K> getKeySet() > { > - // need a better locking strategy here. > - synchronized ( this ) > - { > - // may need to lock to map here? > - return new LinkedHashSet<K>(map.keySet()); > - } > + return new LinkedHashSet<K>(map.keySet()); > } > > /** > @@ -699,18 +784,26 @@ public abstract class AbstractDoubleLink > * @see > org.apache.commons.jcs.engine.memory.behavior.IMemoryCache#getStatistics() > */ > @Override > - public synchronized IStats getStatistics() > + public IStats getStatistics() > { > IStats stats = new Stats(); > stats.setTypeName( /*add algorithm name*/"Memory Cache" ); > > ArrayList<IStatElement<?>> elems = new ArrayList<IStatElement<?>>(); > > - elems.add(new StatElement<Integer>( "List Size", > Integer.valueOf(list.size()) ) ); > - elems.add(new StatElement<Integer>( "Map Size", > Integer.valueOf(map.size()) ) ); > - elems.add(new StatElement<Integer>( "Put Count", > Integer.valueOf(putCnt) ) ); > - elems.add(new StatElement<Integer>( "Hit Count", > Integer.valueOf(hitCnt) ) ); > - elems.add(new StatElement<Integer>( "Miss Count", > Integer.valueOf(missCnt) ) ); > + lock.lock(); // not sure that's really relevant here but not that > important > + try > + { > + elems.add(new StatElement<Integer>("List Size", > Integer.valueOf(list.size()))); > + elems.add(new StatElement<Integer>("Map Size", > Integer.valueOf(map.size()))); > + elems.add(new StatElement<Integer>("Put Count", > Integer.valueOf(putCnt))); > + elems.add(new StatElement<Integer>("Hit Count", > Integer.valueOf(hitCnt))); > + elems.add(new StatElement<Integer>("Miss Count", > Integer.valueOf(missCnt))); > + } > + finally > + { > + lock.unlock(); > + } > > stats.setStatElements( elems ); > > > Modified: > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/AbstractMemoryCache.java > URL: > http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/AbstractMemoryCache.java?rev=1598071&r1=1598070&r2=1598071&view=diff > ============================================================================== > --- > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/AbstractMemoryCache.java > (original) > +++ > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/AbstractMemoryCache.java > Wed May 28 17:06:12 2014 > @@ -28,6 +28,7 @@ import org.apache.commons.jcs.engine.mem > import org.apache.commons.jcs.engine.memory.util.MemoryElementDescriptor; > import org.apache.commons.jcs.engine.stats.Stats; > import org.apache.commons.jcs.engine.stats.behavior.IStats; > +import org.apache.commons.jcs.utils.logger.LogHelper; > import org.apache.commons.logging.Log; > import org.apache.commons.logging.LogFactory; > > @@ -35,6 +36,8 @@ import java.io.IOException; > import java.util.HashMap; > import java.util.Map; > import java.util.Set; > +import java.util.concurrent.locks.Lock; > +import java.util.concurrent.locks.ReentrantLock; > > /** > * This base includes some common code for memory caches. > @@ -47,6 +50,7 @@ public abstract class AbstractMemoryCach > { > /** Log instance */ > private static final Log log = LogFactory.getLog( > AbstractMemoryCache.class ); > + private static final LogHelper LOG_HELPER = new LogHelper(log); > > /** The region name. This defines a namespace of sorts. */ > protected String cacheName; // TODO privatise (mainly seems to be used > externally for debugging) > @@ -69,21 +73,31 @@ public abstract class AbstractMemoryCach > /** How many to spool at a time. */ > protected int chunkSize; > > + protected final Lock lock = new ReentrantLock(); > + > /** > * For post reflection creation initialization > * <p> > * @param hub > */ > @Override > - public synchronized void initialize( CompositeCache<K, V> hub ) > + public void initialize( CompositeCache<K, V> hub ) > { > - this.cacheName = hub.getCacheName(); > - this.cacheAttributes = hub.getCacheAttributes(); > - this.cache = hub; > - map = createMap(); > + lock.lock(); > + try > + { > + this.cacheName = hub.getCacheName(); > + this.cacheAttributes = hub.getCacheAttributes(); > + this.cache = hub; > + map = createMap(); > > - chunkSize = cacheAttributes.getSpoolChunkSize(); > - status = CacheStatus.ALIVE; > + chunkSize = cacheAttributes.getSpoolChunkSize(); > + status = CacheStatus.ALIVE; > + } > + finally > + { > + lock.unlock(); > + } > } > > /** > @@ -163,14 +177,14 @@ public abstract class AbstractMemoryCach > MemoryElementDescriptor<K, V> me = map.get( key ); > if ( me != null ) > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( cacheName + ": MemoryCache quiet hit for " + key > ); > } > > ce = me.ce; > } > - else if ( log.isDebugEnabled() ) > + else if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( cacheName + ": MemoryCache quiet miss for " + key ); > } > @@ -261,7 +275,7 @@ public abstract class AbstractMemoryCach > { > String attributeCacheName = this.cacheAttributes.getCacheName(); > if(attributeCacheName != null) > - return attributeCacheName; > + return attributeCacheName; > return cacheName; > } > > > Added: > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/logger/LogHelper.java > URL: > http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/logger/LogHelper.java?rev=1598071&view=auto > ============================================================================== > --- > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/logger/LogHelper.java > (added) > +++ > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/logger/LogHelper.java > Wed May 28 17:06:12 2014 > @@ -0,0 +1,42 @@ > +/* > + * 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.commons.jcs.utils.logger; > + > +import org.apache.commons.logging.Log; > + > +// when cached isDebugEnabled will save a lot of time > +public class LogHelper > +{ > + protected static final boolean cacheDebug = > Boolean.getBoolean("jcs.logger.cacheDebug"); // TODO: move it over cache > config if really used (=default not nice enough) > + > + private boolean debug; > + private Log log; > + > + public LogHelper(final Log log) > + { > + this.debug = log.isDebugEnabled(); > + this.log = log; > + } > + > + // faster than several log calls by default > + public boolean isDebugEnabled() > + { > + return cacheDebug ? debug : log.isDebugEnabled(); > + } > +} > > Modified: > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/struct/LRUMap.java > URL: > http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/struct/LRUMap.java?rev=1598071&r1=1598070&r2=1598071&view=diff > ============================================================================== > --- > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/struct/LRUMap.java > (original) > +++ > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/struct/LRUMap.java > Wed May 28 17:06:12 2014 > @@ -24,6 +24,7 @@ import org.apache.commons.jcs.engine.sta > import org.apache.commons.jcs.engine.stats.Stats; > import org.apache.commons.jcs.engine.stats.behavior.IStatElement; > import org.apache.commons.jcs.engine.stats.behavior.IStats; > +import org.apache.commons.jcs.utils.logger.LogHelper; > import org.apache.commons.logging.Log; > import org.apache.commons.logging.LogFactory; > > @@ -37,6 +38,8 @@ import java.util.Map; > import java.util.NoSuchElementException; > import java.util.Set; > import java.util.concurrent.ConcurrentHashMap; > +import java.util.concurrent.locks.Lock; > +import java.util.concurrent.locks.ReentrantLock; > > /** > * This is a simple LRUMap. It implements most of the map methods. It is not > recommended that you > @@ -57,6 +60,7 @@ public class LRUMap<K, V> > { > /** The logger */ > private static final Log log = LogFactory.getLog( LRUMap.class ); > + private static final LogHelper LOG_HELPER = new LogHelper(log); > > /** double linked list for lru */ > private final DoubleLinkedList<LRUElementDescriptor<K, V>> list; > @@ -79,6 +83,8 @@ public class LRUMap<K, V> > /** make configurable */ > private int chunkSize = 1; > > + private final Lock lock = new ReentrantLock(); > + > /** > * This creates an unbounded version. Setting the max objects will > result in spooling on > * subsequent puts. > @@ -123,8 +129,16 @@ public class LRUMap<K, V> > @Override > public void clear() > { > - map.clear(); > - list.removeAll(); > + lock.lock(); > + try > + { > + map.clear(); > + list.removeAll(); > + } > + finally > + { > + lock.unlock(); > + } > } > > /** > @@ -200,7 +214,7 @@ public class LRUMap<K, V> > { > V retVal = null; > > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "getting item for key " + key ); > } > @@ -244,14 +258,14 @@ public class LRUMap<K, V> > LRUElementDescriptor<K, V> me = map.get( key ); > if ( me != null ) > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "LRUMap quiet hit for " + key ); > } > > ce = me.getPayload(); > } > - else if ( log.isDebugEnabled() ) > + else if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "LRUMap quiet miss for " + key ); > } > @@ -266,18 +280,26 @@ public class LRUMap<K, V> > @Override > public V remove( Object key ) > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "removing item for key: " + key ); > } > > // remove single item. > - LRUElementDescriptor<K, V> me = map.remove( key ); > + lock.lock(); > + try > + { > + LRUElementDescriptor<K, V> me = map.remove(key); > > - if ( me != null ) > + if (me != null) > + { > + list.remove(me); > + return me.getPayload(); > + } > + } > + finally > { > - list.remove( me ); > - return me.getPayload(); > + lock.unlock(); > } > > return null; > @@ -294,7 +316,8 @@ public class LRUMap<K, V> > putCnt++; > > LRUElementDescriptor<K, V> old = null; > - synchronized ( this ) > + lock.lock(); > + try > { > // TODO address double synchronization of addFirst, use write > lock > addFirst( key, value ); > @@ -308,13 +331,18 @@ public class LRUMap<K, V> > list.remove( old ); > } > } > + finally > + { > + lock.unlock(); > + } > > int size = map.size(); > // If the element limit is reached, we need to spool > > if ( this.maxObjects >= 0 && size > this.maxObjects ) > { > - if ( log.isDebugEnabled() ) > + final boolean debugEnabled = LOG_HELPER.isDebugEnabled(); > + if (debugEnabled) > { > log.debug( "In memory limit reached, removing least recently > used." ); > } > @@ -322,7 +350,7 @@ public class LRUMap<K, V> > // Write the last 'chunkSize' items to disk. > int chunkSizeCorrected = Math.min( size, getChunkSize() ); > > - if ( log.isDebugEnabled() ) > + if (debugEnabled) > { > log.debug( "About to remove the least recently used. map > size: " + size + ", max objects: " > + this.maxObjects + ", items to spool: " + > chunkSizeCorrected ); > @@ -334,33 +362,41 @@ public class LRUMap<K, V> > > for ( int i = 0; i < chunkSizeCorrected; i++ ) > { > - LRUElementDescriptor<K, V> last = list.getLast(); > - if ( last != null ) > + lock.lock(); > + try > { > - processRemovedLRU(last.getKey(), last.getPayload()); > - if ( map.remove( last.getKey() ) == null ) > + LRUElementDescriptor<K, V> last = list.getLast(); > + if (last != null) > + { > + processRemovedLRU(last.getKey(), last.getPayload()); > + if (map.remove(last.getKey()) == null) > + { > + log.warn("update: remove failed for key: " > + + last.getKey()); > + verifyCache(); > + } > + list.removeLast(); > + } > + else > { > - log.warn( "update: remove failed for key: " > - + last.getKey() ); > verifyCache(); > + throw new Error("update: last is null!"); > } > - list.remove(last); > } > - else > + finally > { > - verifyCache(); > - throw new Error( "update: last is null!" ); > + lock.unlock(); > } > } > > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "update: After spool map size: " + map.size() ); > } > if ( map.size() != dumpCacheSize() ) > { > - log.error( "update: After spool, size mismatch: map.size() = > " + map.size() + ", linked list size = " > - + dumpCacheSize() ); > + log.error("update: After spool, size mismatch: map.size() = > " + map.size() + ", linked list size = " > + + dumpCacheSize()); > } > } > > @@ -379,8 +415,16 @@ public class LRUMap<K, V> > */ > private void addFirst(K key, V val) > { > - LRUElementDescriptor<K, V> me = new LRUElementDescriptor<K, V>(key, > val); > - list.addFirst( me ); > + lock.lock(); > + try > + { > + LRUElementDescriptor<K, V> me = new LRUElementDescriptor<K, > V>(key, val); > + list.addFirst( me ); > + } > + finally > + { > + lock.unlock(); > + } > } > > /** > @@ -402,7 +446,7 @@ public class LRUMap<K, V> > log.debug( "dumpingCacheEntries" ); > for ( LRUElementDescriptor<K, V> me = list.getFirst(); me != null; > me = (LRUElementDescriptor<K, V>) me.next ) > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "dumpCacheEntries> key=" + me.getKey() + ", val=" > + me.getPayload() ); > } > @@ -418,7 +462,7 @@ public class LRUMap<K, V> > for (Map.Entry<K, LRUElementDescriptor<K, V>> e : map.entrySet()) > { > LRUElementDescriptor<K, V> me = e.getValue(); > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "dumpMap> key=" + e.getKey() + ", val=" + > me.getPayload() ); > } > @@ -432,7 +476,7 @@ public class LRUMap<K, V> > @SuppressWarnings("unchecked") // No generics for public fields > protected void verifyCache() > { > - if ( !log.isDebugEnabled() ) > + if ( !LOG_HELPER.isDebugEnabled() ) > { > return; > } > @@ -524,7 +568,7 @@ public class LRUMap<K, V> > @SuppressWarnings("unchecked") // No generics for public fields > protected void verifyCache( Object key ) > { > - if ( !log.isDebugEnabled() ) > + if ( !LOG_HELPER.isDebugEnabled() ) > { > return; > } > @@ -556,7 +600,7 @@ public class LRUMap<K, V> > */ > protected void processRemovedLRU(K key, V value ) > { > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "Removing key: [" + key + "] from LRUMap store, value > = [" + value + "]" ); > log.debug( "LRUMap store size: '" + this.size() + "'." ); > @@ -615,18 +659,25 @@ public class LRUMap<K, V> > @Override > public Set<Map.Entry<K, V>> entrySet() > { > - // todo, we should return a defensive copy > - Set<Map.Entry<K, LRUElementDescriptor<K, V>>> entries = > map.entrySet(); > + lock.lock(); > + try > + { > + // todo, we should return a defensive copy > + Set<Map.Entry<K, LRUElementDescriptor<K, V>>> entries = > map.entrySet(); > > - Set<Map.Entry<K, V>> unWrapped = new HashSet<Map.Entry<K, V>>(); > + Set<Map.Entry<K, V>> unWrapped = new HashSet<Map.Entry<K, V>>(); > > - for (Map.Entry<K, LRUElementDescriptor<K, V>> pre : entries ) > + for (Map.Entry<K, LRUElementDescriptor<K, V>> pre : entries) { > + Map.Entry<K, V> post = new LRUMapEntry<K, V>(pre.getKey(), > pre.getValue().getPayload()); > + unWrapped.add(post); > + } > + > + return unWrapped; > + } > + finally > { > - Map.Entry<K, V> post = new LRUMapEntry<K, V>(pre.getKey(), > pre.getValue().getPayload()); > - unWrapped.add(post); > + lock.unlock(); > } > - > - return unWrapped; > } > > /** > > Modified: > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/struct/SingleLinkedList.java > URL: > http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/struct/SingleLinkedList.java?rev=1598071&r1=1598070&r2=1598071&view=diff > ============================================================================== > --- > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/struct/SingleLinkedList.java > (original) > +++ > commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/struct/SingleLinkedList.java > Wed May 28 17:06:12 2014 > @@ -19,6 +19,7 @@ package org.apache.commons.jcs.utils.str > * under the License. > */ > > +import org.apache.commons.jcs.utils.logger.LogHelper; > import org.apache.commons.logging.Log; > import org.apache.commons.logging.LogFactory; > > @@ -32,6 +33,7 @@ public class SingleLinkedList<T> > { > /** The logger */ > private static final Log log = LogFactory.getLog( SingleLinkedList.class > ); > + private static final LogHelper LOG_HELPER = new LogHelper(log); > > /** for sync */ > private final Object lock = new Object(); > @@ -64,7 +66,7 @@ public class SingleLinkedList<T> > > T value = node.payload; > > - if ( log.isDebugEnabled() ) > + if ( LOG_HELPER.isDebugEnabled() ) > { > log.debug( "head.payload = " + head.payload ); > log.debug( "node.payload = " + node.payload ); > > --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org For additional commands, e-mail: dev-h...@commons.apache.org