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=1717801&r1=1717800&r2=1717801&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 Thu Dec 3 16:41:49 2015 @@ -20,14 +20,13 @@ package org.apache.commons.jcs.engine.me */ import java.io.IOException; -import java.io.Serializable; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Map; -import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; import org.apache.commons.jcs.engine.CacheConstants; import org.apache.commons.jcs.engine.behavior.ICacheElement; @@ -46,42 +45,45 @@ import org.apache.commons.logging.LogFac * This class contains methods that are common to memory caches using the double linked list, such * as the LRU, MRU, FIFO, and LIFO caches. * <p> - * Children can control the expiration algorithm by controlling the update and get. The last item in - * the list will be the one removed when the list fills. For instance LRU should more items to the - * front as they are used. FIFO should simply add new items to the front of the list. + * Children can control the expiration algorithm by controlling the update and get. The last item in the list will be the one + * removed when the list fills. For instance LRU should more items to the front as they are used. FIFO should simply add new items + * to the front of the list. */ -public abstract class AbstractDoubleLinkedListMemoryCache<K, V> - extends AbstractMemoryCache<K, V> +public abstract class AbstractDoubleLinkedListMemoryCache<K, V> extends AbstractMemoryCache<K, V> { /** The logger. */ - private static final Log log = LogFactory.getLog( AbstractDoubleLinkedListMemoryCache.class ); + private static final Log log = LogFactory.getLog(AbstractDoubleLinkedListMemoryCache.class); /** thread-safe double linked list for lru */ protected DoubleLinkedList<MemoryElementDescriptor<K, V>> list; // TODO privatise /** number of hits */ - private volatile int hitCnt = 0; + private AtomicInteger hitCnt; /** number of misses */ - private volatile int missCnt = 0; + private AtomicInteger missCnt; /** number of puts */ - private volatile int putCnt = 0; + private AtomicInteger putCnt; /** * For post reflection creation initialization. * <p> + * * @param hub */ @Override - public void initialize( CompositeCache<K, V> hub ) + public void initialize(CompositeCache<K, V> hub) { lock.lock(); try { super.initialize(hub); + hitCnt = new AtomicInteger(0); + missCnt = new AtomicInteger(0); + putCnt = new AtomicInteger(0); list = new DoubleLinkedList<MemoryElementDescriptor<K, V>>(); - log.info("initialized MemoryCache for " + cacheName); + log.info("initialized MemoryCache for " + getCacheName()); } finally { @@ -95,6 +97,7 @@ public abstract class AbstractDoubleLink * NOTE: should return a thread safe map * * <p> + * * @return new ConcurrentHashMap() */ @Override @@ -108,25 +111,27 @@ public abstract class AbstractDoubleLink * <p> * If the max size is reached, an element will be put to disk. * <p> - * @param ce The cache element, or entry wrapper + * + * @param ce + * The cache element, or entry wrapper * @throws IOException */ @Override - public final void update( ICacheElement<K, V> ce ) - throws IOException + public final void update(ICacheElement<K, V> ce) throws IOException { + putCnt.incrementAndGet(); + lock.lock(); try { - putCnt++; - 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); // If the node was the same as an existing node, remove it. - if (oldNode != null && newNode.ce.getKey().equals(oldNode.ce.getKey())) { + if (oldNode != null && newNode.ce.getKey().equals(oldNode.ce.getKey())) + { list.remove(oldNode); } } @@ -142,204 +147,218 @@ public abstract class AbstractDoubleLink /** * Children implement this to control the cache expiration algorithm * <p> + * * @param ce * @return MemoryElementDescriptor the new node * @throws IOException */ - protected abstract MemoryElementDescriptor<K, V> adjustListForUpdate( ICacheElement<K, V> ce ) - throws IOException; + protected abstract MemoryElementDescriptor<K, V> adjustListForUpdate(ICacheElement<K, V> ce) throws IOException; /** * If the max size has been reached, spool. * <p> + * * @throws Error */ - private void spoolIfNeeded() - throws Error + private void spoolIfNeeded() throws Error { int size = map.size(); // If the element limit is reached, we need to spool - if ( size <= this.cacheAttributes.getMaxObjects() ) + if (size <= this.getCacheAttributes().getMaxObjects()) { return; } - if ( log.isDebugEnabled() ) + if (log.isDebugEnabled()) { - log.debug( "In memory limit reached, spooling" ); + log.debug("In memory limit reached, spooling"); } // Write the last 'chunkSize' items to disk. - int chunkSizeCorrected = Math.min( size, chunkSize ); + int chunkSizeCorrected = Math.min(size, chunkSize); - if ( log.isDebugEnabled() ) + if (log.isDebugEnabled()) { - log.debug( "About to spool to disk cache, map size: " + size + ", max objects: " - + this.cacheAttributes.getMaxObjects() + ", items to spool: " + chunkSizeCorrected ); + log.debug("About to spool to disk cache, map size: " + size + ", max objects: " + + this.getCacheAttributes().getMaxObjects() + ", maximum items to spool: " + chunkSizeCorrected); } // The spool will put them in a disk event queue, so there is no // need to pre-queue the queuing. This would be a bit wasteful // and wouldn't save much time in this synchronous call. - for ( int i = 0; i < chunkSizeCorrected; i++ ) + lock.lock(); + + try { - spoolLastElement(); + for (int i = 0; i < chunkSizeCorrected; i++) + { + ICacheElement<K, V> lastElement = spoolLastElement(); + if (lastElement == null) + { + break; + } + } + + // If this is out of the sync block it can detect a mismatch + // where there is none. + if (log.isDebugEnabled() && map.size() != list.size()) + { + log.debug("update: After spool, size mismatch: map.size() = " + map.size() + ", linked list size = " + list.size()); + } + } + finally + { + lock.unlock(); } - if ( log.isDebugEnabled() ) + if (log.isDebugEnabled()) { - log.debug( "update: After spool map size: " + map.size() + " linked list size = " + dumpCacheSize() ); + log.debug("update: After spool map size: " + map.size() + " linked list size = " + list.size()); } } /** * Get an item from the cache If the item is found, it is removed from the list and added first. * <p> - * @param key Identifies item to find + * + * @param key + * Identifies item to find * @return ICacheElement<K, V> if found, else null * @throws IOException */ @Override - public final ICacheElement<K, V> get( K key ) - throws IOException + public final ICacheElement<K, V> get(K key) throws IOException { ICacheElement<K, V> ce = null; - final boolean debugEnabled = log.isDebugEnabled(); - - if (debugEnabled) + if (log.isDebugEnabled()) { - log.debug( "getting item from cache " + cacheName + " for key " + key ); + log.debug(getCacheName() + ": getting item for key " + key); } - MemoryElementDescriptor<K, V> me = map.get( key ); + MemoryElementDescriptor<K, V> me = map.get(key); - if ( me != null ) + if (me != null) { + hitCnt.incrementAndGet(); + lock.lock(); try { ce = me.ce; - hitCnt++; - // ABSTRACT - adjustListForGet( me ); + adjustListForGet(me); } finally { lock.unlock(); } - if (debugEnabled) + if (log.isDebugEnabled()) { - log.debug( cacheName + ": LRUMemoryCache hit for " + ce.getKey() ); + log.debug(getCacheName() + ": LRUMemoryCache hit for " + key); } } else { - lock.lock(); - try - { - missCnt++; - } - finally - { - lock.unlock(); - } + missCnt.incrementAndGet(); - if (debugEnabled) + if (log.isDebugEnabled()) { - log.debug( cacheName + ": LRUMemoryCache miss for " + key ); + log.debug(getCacheName() + ": LRUMemoryCache miss for " + key); } } - verifyCache(); + if (log.isDebugEnabled()) + { + verifyCache(); + } + return ce; } /** * Adjust the list as needed for a get. This allows children to control the algorithm * <p> + * * @param me */ - protected abstract void adjustListForGet( MemoryElementDescriptor<K, V> me ); + protected abstract void adjustListForGet(MemoryElementDescriptor<K, V> me); /** * This instructs the memory cache to remove the <i>numberToFree</i> according to its eviction * policy. For example, the LRUMemoryCache will remove the <i>numberToFree</i> least recently * used items. These will be spooled to disk if a disk auxiliary is available. * <p> + * * @param numberToFree * @return the number that were removed. if you ask to free 5, but there are only 3, you will * get 3. * @throws IOException */ @Override - public int freeElements( int numberToFree ) - throws IOException + public int freeElements(int numberToFree) throws IOException { int freed = 0; - for ( ; freed < numberToFree; freed++ ) + + lock.lock(); + + try { - ICacheElement<K, V> element = spoolLastElement(); - if ( element == null ) + for (; freed < numberToFree; freed++) { - break; + ICacheElement<K, V> element = spoolLastElement(); + if (element == null) + { + break; + } } } + finally + { + lock.unlock(); + } + return freed; } /** * This spools the last element in the LRU, if one exists. * <p> + * * @return ICacheElement<K, V> if there was a last element, else null. * @throws Error */ - protected ICacheElement<K, V> spoolLastElement() - throws Error + private ICacheElement<K, V> spoolLastElement() throws Error { ICacheElement<K, V> toSpool = null; + final MemoryElementDescriptor<K, V> last = list.getLast(); - if ( last != null ) + if (last != null) { - lock.lock(); - try + toSpool = last.ce; + if (toSpool != 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()); + getCompositeCache().spoolToDisk(toSpool); + if (map.remove(toSpool.getKey()) == null) + { + log.warn("update: remove failed for key: " + toSpool.getKey()); + + if (log.isDebugEnabled()) + { verifyCache(); } } - else - { - throw new Error("update: last.ce is null!"); - } - list.remove(last); } - finally + else { - lock.unlock(); + throw new Error("update: last.ce is null!"); } - } - else - { - verifyCache(); - throw new Error( "update: last is null!" ); - } - // If this is out of the sync block it can detect a mismatch - // where there is none. - if ( map.size() != dumpCacheSize() ) - { - log.warn( "update: After spool, size mismatch: map.size() = " + map.size() + ", linked list size = " - + dumpCacheSize() ); + list.remove(last); } + return toSpool; } @@ -348,26 +367,26 @@ public abstract class AbstractDoubleLink * String and ends with the CacheConstants.NAME_COMPONENT_DELIMITER, then all items with keys * starting with the argument String will be removed. * <p> + * * @param key * @return true if the removal was successful * @throws IOException */ @Override - public boolean remove( K key ) - throws IOException + public boolean remove(K key) throws IOException { - if ( log.isDebugEnabled() ) + if (log.isDebugEnabled()) { - log.debug( "removing item for key: " + key ); + log.debug("removing item for key: " + key); } boolean removed = false; // handle partial removal - if ( key instanceof String && ( (String) key ).endsWith( CacheConstants.NAME_COMPONENT_DELIMITER ) ) + if (key instanceof String && ((String) key).endsWith(CacheConstants.NAME_COMPONENT_DELIMITER)) { // remove all keys of the same name hierarchy. - for (Iterator<Map.Entry<K, MemoryElementDescriptor<K, V>>> itr = map.entrySet().iterator(); itr.hasNext(); ) + for (Iterator<Map.Entry<K, MemoryElementDescriptor<K, V>>> itr = map.entrySet().iterator(); itr.hasNext();) { Map.Entry<K, MemoryElementDescriptor<K, V>> entry = itr.next(); K k = entry.getKey(); @@ -388,16 +407,15 @@ public abstract class AbstractDoubleLink } } } - else if ( key instanceof GroupAttrName && ((GroupAttrName<?>)key).attrName == null) + else if (key instanceof GroupAttrName && ((GroupAttrName<?>) key).attrName == null) { // remove all keys of the same name hierarchy. - for (Iterator<Map.Entry<K, MemoryElementDescriptor<K, V>>> itr = map.entrySet().iterator(); itr.hasNext(); ) + for (Iterator<Map.Entry<K, MemoryElementDescriptor<K, V>>> itr = map.entrySet().iterator(); itr.hasNext();) { Map.Entry<K, MemoryElementDescriptor<K, V>> entry = itr.next(); K k = entry.getKey(); - if ( k instanceof GroupAttrName && - ((GroupAttrName<?>)k).groupId.equals(((GroupAttrName<?>)key).groupId)) + if (k instanceof GroupAttrName && ((GroupAttrName<?>) k).groupId.equals(((GroupAttrName<?>) key).groupId)) { lock.lock(); try @@ -439,11 +457,11 @@ public abstract class AbstractDoubleLink * Remove all of the elements from both the Map and the linked list implementation. Overrides * base class. * <p> + * * @throws IOException */ @Override - public void removeAll() - throws IOException + public void removeAll() throws IOException { lock.lock(); try @@ -461,17 +479,22 @@ public abstract class AbstractDoubleLink /** * Adds a new node to the start of the link list. * <p> - * @param ce The feature to be added to the First + * + * @param ce + * The feature to be added to the First * @return MemoryElementDescriptor */ - protected MemoryElementDescriptor<K, V> addFirst( ICacheElement<K, V> ce ) + protected MemoryElementDescriptor<K, V> addFirst(ICacheElement<K, V> ce) { lock.lock(); try { MemoryElementDescriptor<K, V> me = new MemoryElementDescriptor<K, V>(ce); list.addFirst(me); - verifyCache(ce.getKey()); + if ( log.isDebugEnabled() ) + { + verifyCache(ce.getKey()); + } return me; } finally @@ -483,17 +506,22 @@ public abstract class AbstractDoubleLink /** * Adds a new node to the end of the link list. * <p> - * @param ce The feature to be added to the First + * + * @param ce + * The feature to be added to the First * @return MemoryElementDescriptor */ - protected MemoryElementDescriptor<K, V> addLast( ICacheElement<K, V> ce ) + protected MemoryElementDescriptor<K, V> addLast(ICacheElement<K, V> ce) { lock.lock(); try { MemoryElementDescriptor<K, V> me = new MemoryElementDescriptor<K, V>(ce); list.addLast(me); - verifyCache(ce.getKey()); + if ( log.isDebugEnabled() ) + { + verifyCache(ce.getKey()); + } return me; } finally @@ -507,103 +535,89 @@ public abstract class AbstractDoubleLink /** * Dump the cache entries from first to list for debugging. */ - @SuppressWarnings("unchecked") // No generics for public fields - public void dumpCacheEntries() + @SuppressWarnings("unchecked") + // No generics for public fields + private void dumpCacheEntries() { - log.debug( "dumpingCacheEntries" ); - for ( MemoryElementDescriptor<K, V> me = list.getFirst(); me != null; me = (MemoryElementDescriptor<K, V>) me.next ) + log.debug("dumpingCacheEntries"); + for (MemoryElementDescriptor<K, V> me = list.getFirst(); me != null; me = (MemoryElementDescriptor<K, V>) me.next) { - log.debug( "dumpCacheEntries> key=" + me.ce.getKey() + ", val=" + me.ce.getVal() ); + log.debug("dumpCacheEntries> key=" + me.ce.getKey() + ", val=" + me.ce.getVal()); } } /** - * Returns the size of the list. - * <p> - * @return the number of items in the map. - */ - protected int dumpCacheSize() - { - return list.size(); - } - - /** * Checks to see if all the items that should be in the cache are. Checks consistency between * List and map. */ - @SuppressWarnings("unchecked") // No generics for public fields - protected void verifyCache() + @SuppressWarnings("unchecked") + // No generics for public fields + private void verifyCache() { - if ( !log.isDebugEnabled() ) - { - return; - } - boolean found = false; - log.debug( "verifycache[" + cacheName + "]: mapContains " + map.size() + " elements, linked list contains " - + dumpCacheSize() + " elements" ); - log.debug( "verifycache: checking linked list by key " ); - for ( MemoryElementDescriptor<K, V> li = list.getFirst(); li != null; li = (MemoryElementDescriptor<K, V>) li.next ) + log.debug("verifycache[" + getCacheName() + "]: mapContains " + map.size() + " elements, linked list contains " + + list.size() + " elements"); + log.debug("verifycache: checking linked list by key "); + for (MemoryElementDescriptor<K, V> li = list.getFirst(); li != null; li = (MemoryElementDescriptor<K, V>) li.next) { Object key = li.ce.getKey(); - if ( !map.containsKey( key ) ) + if (!map.containsKey(key)) { - log.error( "verifycache[" + cacheName + "]: map does not contain key : " + li.ce.getKey() ); - log.error( "li.hashcode=" + li.ce.getKey().hashCode() ); - log.error( "key class=" + key.getClass() ); - log.error( "key hashcode=" + key.hashCode() ); - log.error( "key toString=" + key.toString() ); - if ( key instanceof GroupAttrName ) + log.error("verifycache[" + getCacheName() + "]: map does not contain key : " + li.ce.getKey()); + log.error("li.hashcode=" + li.ce.getKey().hashCode()); + log.error("key class=" + key.getClass()); + log.error("key hashcode=" + key.hashCode()); + log.error("key toString=" + key.toString()); + if (key instanceof GroupAttrName) { GroupAttrName<?> name = (GroupAttrName<?>) key; - log.error( "GroupID hashcode=" + name.groupId.hashCode() ); - log.error( "GroupID.class=" + name.groupId.getClass() ); - log.error( "AttrName hashcode=" + name.attrName.hashCode() ); - log.error( "AttrName.class=" + name.attrName.getClass() ); + log.error("GroupID hashcode=" + name.groupId.hashCode()); + log.error("GroupID.class=" + name.groupId.getClass()); + log.error("AttrName hashcode=" + name.attrName.hashCode()); + log.error("AttrName.class=" + name.attrName.getClass()); } dumpMap(); } - else if ( map.get( li.ce.getKey() ) == null ) + else if (map.get(li.ce.getKey()) == null) { - log.error( "verifycache[" + cacheName + "]: linked list retrieval returned null for key: " - + li.ce.getKey() ); + log.error("verifycache[" + getCacheName() + "]: linked list retrieval returned null for key: " + li.ce.getKey()); } } - log.debug( "verifycache: checking linked list by value " ); - for ( MemoryElementDescriptor<K, V> li3 = list.getFirst(); li3 != null; li3 = (MemoryElementDescriptor<K, V>) li3.next ) + log.debug("verifycache: checking linked list by value "); + for (MemoryElementDescriptor<K, V> li3 = list.getFirst(); li3 != null; li3 = (MemoryElementDescriptor<K, V>) li3.next) { - if ( map.containsValue( li3 ) == false ) + if (map.containsValue(li3) == false) { - log.error( "verifycache[" + cacheName + "]: map does not contain value : " + li3 ); + log.error("verifycache[" + getCacheName() + "]: map does not contain value : " + li3); dumpMap(); } } - log.debug( "verifycache: checking via keysets!" ); + log.debug("verifycache: checking via keysets!"); for (Object val : map.keySet()) { found = false; - for ( MemoryElementDescriptor<K, V> li2 = list.getFirst(); li2 != null; li2 = (MemoryElementDescriptor<K, V>) li2.next ) + for (MemoryElementDescriptor<K, V> li2 = list.getFirst(); li2 != null; li2 = (MemoryElementDescriptor<K, V>) li2.next) { - if ( val.equals( li2.ce.getKey() ) ) + if (val.equals(li2.ce.getKey())) { found = true; break; } } - if ( !found ) + if (!found) { - log.error( "verifycache[" + cacheName + "]: key not found in list : " + val ); + log.error("verifycache[" + getCacheName() + "]: key not found in list : " + val); dumpCacheEntries(); - if ( map.containsKey( val ) ) + if (map.containsKey(val)) { - log.error( "verifycache: map contains key" ); + log.error("verifycache: map contains key"); } else { - log.error( "verifycache: map does NOT contain key, what the HECK!" ); + log.error("verifycache: map does NOT contain key, what the HECK!"); } } } @@ -612,156 +626,34 @@ public abstract class AbstractDoubleLink /** * Logs an error if an element that should be in the cache is not. * <p> + * * @param key */ - @SuppressWarnings("unchecked") // No generics for public fields - private void verifyCache( K key ) + @SuppressWarnings("unchecked") + // No generics for public fields + private void verifyCache(K key) { - if ( !log.isDebugEnabled() ) - { - return; - } - boolean found = false; // go through the linked list looking for the key - for ( MemoryElementDescriptor<K, V> li = list.getFirst(); li != null; li = (MemoryElementDescriptor<K, V>) li.next ) + for (MemoryElementDescriptor<K, V> li = list.getFirst(); li != null; li = (MemoryElementDescriptor<K, V>) li.next) { - if ( li.ce.getKey() == key ) + if (li.ce.getKey() == key) { found = true; - log.debug( "verifycache(key) key match: " + key ); + log.debug("verifycache(key) key match: " + key); break; } } - if ( !found ) - { - log.error( "verifycache(key)[" + cacheName + "], couldn't find key! : " + key ); - } - } - - // --------------------------- iteration methods (iteration helpers) - /** - * iteration aid - */ - public static class IteratorWrapper<K extends Serializable, V extends Serializable> - implements Iterator<Entry<K, MemoryElementDescriptor<K, V>>> - { - /** The internal iterator */ - private final Iterator<Entry<K, MemoryElementDescriptor<K, V>>> i; - - /** - * Wrapped to remove our wrapper object - * @param m - */ - protected IteratorWrapper(Map<K, MemoryElementDescriptor<K, V>> m) - { - i = m.entrySet().iterator(); - } - - /** @return i.hasNext() */ - @Override - public boolean hasNext() - { - return i.hasNext(); - } - - /** @return new MapEntryWrapper( (Map.Entry) i.next() ) */ - @Override - public Entry<K, MemoryElementDescriptor<K, V>> next() - { - // return new MapEntryWrapper<Serializable>( i.next() ); - return i.next(); - } - - /** i.remove(); */ - @Override - public void remove() + if (!found) { - i.remove(); - } - - /** - * @param o - * @return i.equals( o )) - */ - @Override - public boolean equals( Object o ) - { - return i.equals( o ); - } - - /** @return i.hashCode() */ - @Override - public int hashCode() - { - return i.hashCode(); - } - } - - /** - * @author Aaron Smuts - */ - public static class MapEntryWrapper<K extends Serializable, V extends Serializable> - implements Map.Entry<K, ICacheElement<K, V>> - { - /** The internal entry */ - private final Map.Entry<K, MemoryElementDescriptor<K, V>> e; - - /** - * @param e - */ - private MapEntryWrapper( Map.Entry<K, MemoryElementDescriptor<K, V>> e ) - { - this.e = e; - } - - /** - * @param o - * @return e.equals( o ) - */ - @Override - public boolean equals( Object o ) - { - return e.equals( o ); - } - - /** @return e.getKey() */ - @Override - public K getKey() - { - return e.getKey(); - } - - /** @return ( (MemoryElementDescriptor) e.getValue() ).ce */ - @Override - public ICacheElement<K, V> getValue() - { - return e.getValue().ce; - } - - /** @return e.hashCode() */ - @Override - public int hashCode() - { - return e.hashCode(); - } - - /** - * invalid - * @param value - * @return always throws - */ - @Override - public ICacheElement<K, V> setValue(ICacheElement<K, V> value) - { - throw new UnsupportedOperationException( "Use normal cache methods" - + " to alter the contents of the cache." ); + log.error("verifycache(key)[" + getCacheName() + "], couldn't find key! : " + key); } } /** * Get an Array of the keys for all elements in the memory cache + * * @return An Object[] */ @Override @@ -774,13 +666,14 @@ public abstract class AbstractDoubleLink * This returns semi-structured information on the memory cache, such as the size, put count, * hit count, and miss count. * <p> + * * @see org.apache.commons.jcs.engine.memory.behavior.IMemoryCache#getStatistics() */ @Override public IStats getStatistics() { IStats stats = new Stats(); - stats.setTypeName( /*add algorithm name*/"Memory Cache" ); + stats.setTypeName( /* add algorithm name */"Memory Cache"); ArrayList<IStatElement<?>> elems = new ArrayList<IStatElement<?>>(); @@ -789,16 +682,16 @@ public abstract class AbstractDoubleLink { 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))); + elems.add(new StatElement<AtomicInteger>("Put Count", putCnt)); + elems.add(new StatElement<AtomicInteger>("Hit Count", hitCnt)); + elems.add(new StatElement<AtomicInteger>("Miss Count", missCnt)); } finally { lock.unlock(); } - stats.setStatElements( elems ); + stats.setStatElements(elems); return stats; }
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=1717801&r1=1717800&r2=1717801&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 Thu Dec 3 16:41:49 2015 @@ -19,10 +19,16 @@ package org.apache.commons.jcs.engine.me * under the License. */ +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; + import org.apache.commons.jcs.engine.CacheStatus; import org.apache.commons.jcs.engine.behavior.ICacheElement; import org.apache.commons.jcs.engine.behavior.ICompositeCacheAttributes; -import org.apache.commons.jcs.engine.behavior.IElementAttributes; import org.apache.commons.jcs.engine.control.CompositeCache; import org.apache.commons.jcs.engine.memory.behavior.IMemoryCache; import org.apache.commons.jcs.engine.memory.util.MemoryElementDescriptor; @@ -31,13 +37,6 @@ import org.apache.commons.jcs.engine.sta import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -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. * <p> @@ -51,19 +50,13 @@ public abstract class AbstractMemoryCach private static final Log log = LogFactory.getLog( AbstractMemoryCache.class ); /** The region name. This defines a namespace of sorts. */ - protected String cacheName; // TODO privatise (mainly seems to be used externally for debugging) - - /** Map where items are stored by key. This is created by the concrete child class. */ - public Map<K, MemoryElementDescriptor<K, V>> map;// TODO privatise - - /** Region Elemental Attributes, used as a default and copied for each item. */ - public IElementAttributes elementAttributes;// TODO privatise + private String cacheName; /** Cache Attributes. Regions settings. */ - public ICompositeCacheAttributes cacheAttributes;// TODO privatise + private ICompositeCacheAttributes cacheAttributes; /** The cache region this store is associated with */ - public CompositeCache<K, V> cache;// TODO privatise + private CompositeCache<K, V> cache; /** status */ private CacheStatus status; @@ -73,6 +66,9 @@ public abstract class AbstractMemoryCach protected final Lock lock = new ReentrantLock(); + /** Map where items are stored by key. This is created by the concrete child class. */ + protected Map<K, MemoryElementDescriptor<K, V>> map;// TODO privatise + /** * For post reflection creation initialization * <p> Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/lru/LHMLRUMemoryCache.java URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/lru/LHMLRUMemoryCache.java?rev=1717801&r1=1717800&r2=1717801&view=diff ============================================================================== --- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/lru/LHMLRUMemoryCache.java (original) +++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/lru/LHMLRUMemoryCache.java Thu Dec 3 16:41:49 2015 @@ -19,6 +19,16 @@ package org.apache.commons.jcs.engine.me * under the License. */ +import java.io.IOException; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; + import org.apache.commons.jcs.engine.CacheConstants; import org.apache.commons.jcs.engine.behavior.ICacheElement; import org.apache.commons.jcs.engine.control.CompositeCache; @@ -32,15 +42,6 @@ import org.apache.commons.jcs.engine.sta import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import java.io.IOException; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; - /** * This is a test memory manager using the jdk1.4 LinkedHashMap. */ @@ -51,13 +52,13 @@ public class LHMLRUMemoryCache<K extends private static final Log log = LogFactory.getLog( LRUMemoryCache.class ); /** number of hits */ - private int hitCnt = 0; // TODO should these be long values? + private AtomicInteger hitCnt; /** number of misses */ - private int missCnt = 0; + private AtomicInteger missCnt; /** number of puts */ - private int putCnt = 0; + private AtomicInteger putCnt; /** * For post reflection creation initialization @@ -68,7 +69,10 @@ public class LHMLRUMemoryCache<K extends public synchronized void initialize( CompositeCache<K, V> hub ) { super.initialize( hub ); - log.info( "initialized LHMLRUMemoryCache for " + cacheName ); + hitCnt = new AtomicInteger(0); + missCnt = new AtomicInteger(0); + putCnt = new AtomicInteger(0); + log.info( "initialized LHMLRUMemoryCache for " + getCacheName() ); } /** @@ -92,7 +96,7 @@ public class LHMLRUMemoryCache<K extends public void update( ICacheElement<K, V> ce ) throws IOException { - putCnt++; + putCnt.incrementAndGet(); map.put( ce.getKey(), new MemoryElementDescriptor<K, V>(ce) ); } @@ -126,24 +130,27 @@ public class LHMLRUMemoryCache<K extends if ( log.isDebugEnabled() ) { - log.debug( "getting item from cache " + cacheName + " for key " + key ); + log.debug( "getting item from cache " + getCacheName() + " for key " + key ); } me = map.get( key ); if ( me != null ) { - hitCnt++; + hitCnt.incrementAndGet(); if ( log.isDebugEnabled() ) { - log.debug( cacheName + ": LRUMemoryCache hit for " + key ); + log.debug( getCacheName() + ": LHMLRUMemoryCache hit for " + key ); } return me.ce; } else { - missCnt++; - log.debug( cacheName + ": LRUMemoryCache miss for " + key ); + missCnt.incrementAndGet(); + if ( log.isDebugEnabled() ) + { + log.debug( getCacheName() + ": LHMLRUMemoryCache miss for " + key ); + } } return null; @@ -251,9 +258,9 @@ public class LHMLRUMemoryCache<K extends ArrayList<IStatElement<?>> elems = new ArrayList<IStatElement<?>>(); 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) ) ); + elems.add(new StatElement<AtomicInteger>("Put Count", putCnt)); + elems.add(new StatElement<AtomicInteger>("Hit Count", hitCnt)); + elems.add(new StatElement<AtomicInteger>("Miss Count", missCnt)); stats.setStatElements( elems ); @@ -305,7 +312,7 @@ public class LHMLRUMemoryCache<K extends */ public LHMSpooler() { - super( (int) ( cache.getCacheAttributes().getMaxObjects() * .5 ), .75F, true ); + super( (int) ( getCacheAttributes().getMaxObjects() * .5 ), .75F, true ); } /** @@ -320,7 +327,7 @@ public class LHMLRUMemoryCache<K extends { ICacheElement<K, V> element = eldest.getValue().ce; - if ( size() <= cache.getCacheAttributes().getMaxObjects() ) + if ( size() <= getCacheAttributes().getMaxObjects() ) { return false; } @@ -329,7 +336,7 @@ public class LHMLRUMemoryCache<K extends if ( log.isDebugEnabled() ) { - log.debug( "LHMLRU max size: " + cache.getCacheAttributes().getMaxObjects() + log.debug( "LHMLRU max size: " + getCacheAttributes().getMaxObjects() + ". Spooling element, key: " + element.getKey() ); } spoolToDisk( element ); @@ -350,11 +357,11 @@ public class LHMLRUMemoryCache<K extends @SuppressWarnings("synthetic-access") private void spoolToDisk( ICacheElement<K, V> element ) { - cache.spoolToDisk( element ); + getCompositeCache().spoolToDisk( element ); if ( log.isDebugEnabled() ) { - log.debug( cache.getCacheName() + "Spooled element to disk: " + element.getKey() ); + log.debug( getCacheName() + "Spooled element to disk: " + element.getKey() ); } } } Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/threadpool/ThreadPoolManager.java URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/threadpool/ThreadPoolManager.java?rev=1717801&r1=1717800&r2=1717801&view=diff ============================================================================== --- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/threadpool/ThreadPoolManager.java (original) +++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/threadpool/ThreadPoolManager.java Thu Dec 3 16:41:49 2015 @@ -20,14 +20,14 @@ package org.apache.commons.jcs.utils.thr */ import java.util.ArrayList; -import java.util.HashMap; import java.util.Properties; import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; -import org.apache.commons.jcs.utils.props.PropertyLoader; import org.apache.commons.jcs.utils.threadpool.PoolConfiguration.WhenBlockedPolicy; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -99,9 +99,6 @@ public class ThreadPoolManager /** The default config, created using property defaults if present, else those above. */ private static PoolConfiguration defaultConfig; - /** Setting this after initialization will have no effect. */ - private static String propsFileName = null; - /** the root property name */ private static final String PROP_NAME_ROOT = "thread_pool"; @@ -115,7 +112,10 @@ public class ThreadPoolManager private static volatile Properties props = null; /** Map of names to pools. */ - private static HashMap<String, ThreadPoolExecutor> pools = new HashMap<String, ThreadPoolExecutor>(); + private static ConcurrentHashMap<String, ThreadPoolExecutor> pools = new ConcurrentHashMap<String, ThreadPoolExecutor>(); + + /** Lock for pools initialization. */ + private static ReentrantLock poolLock = new ReentrantLock(); /** singleton instance */ private static ThreadPoolManager INSTANCE = null; @@ -236,30 +236,42 @@ public class ThreadPoolManager */ public ThreadPoolExecutor getPool( String name ) { - ThreadPoolExecutor pool = null; + ThreadPoolExecutor pool = pools.get( name ); - synchronized ( pools ) + if ( pool == null ) { - pool = pools.get( name ); - if ( pool == null ) - { - if ( log.isDebugEnabled() ) - { - log.debug( "Creating pool for name [" + name + "]" ); - } - PoolConfiguration config = this.loadConfig( PROP_NAME_ROOT + "." + name ); - pool = createPool( config ); + poolLock.lock(); - if ( pool != null ) - { - pools.put( name, pool ); - } + try + { + // double check + pool = pools.get( name ); - if ( log.isDebugEnabled() ) + if ( pool == null ) { - log.debug( "PoolName = " + getPoolNames() ); + if ( log.isDebugEnabled() ) + { + log.debug( "Creating pool for name [" + name + "]" ); + } + + PoolConfiguration config = loadConfig( PROP_NAME_ROOT + "." + name ); + pool = createPool( config ); + + if ( pool != null ) + { + pools.put( name, pool ); + } + + if ( log.isDebugEnabled() ) + { + log.debug( "PoolName = " + getPoolNames() ); + } } } + finally + { + poolLock.unlock(); + } } return pool; @@ -273,35 +285,11 @@ public class ThreadPoolManager public ArrayList<String> getPoolNames() { ArrayList<String> poolNames = new ArrayList<String>(); - synchronized ( pools ) - { - poolNames.addAll(pools.keySet()); - } + poolNames.addAll(pools.keySet()); return poolNames; } /** - * Setting this post initialization will have no effect. - * <p> - * @param propsFileName The propsFileName to set. - */ - public static void setPropsFileName( String propsFileName ) - { - ThreadPoolManager.propsFileName = propsFileName; - } - - /** - * Returns the name of the properties file that we used to initialize the pools. If the value - * was set post-initialization, then it may not be the file used. - * <p> - * @return Returns the propsFileName. - */ - public static String getPropsFileName() - { - return propsFileName; - } - - /** * This will be used if it is not null on initialization. Setting this post initialization will * have no effect. * <p> @@ -313,17 +301,9 @@ public class ThreadPoolManager } /** - * @return Returns the props. - */ - public static Properties getProps() - { - return props; - } - - /** * Initialize the ThreadPoolManager and create all the pools defined in the configuration. */ - protected void configure() + private static void configure() { if ( log.isDebugEnabled() ) { @@ -332,23 +312,6 @@ public class ThreadPoolManager if ( props == null ) { - try - { - props = PropertyLoader.loadProperties( propsFileName ); - - if ( log.isDebugEnabled() ) - { - log.debug( "File contained " + props.size() + " properties" ); - } - } - catch ( Exception e ) - { - log.error( "Problem loading properties. propsFileName [" + propsFileName + "]", e ); - } - } - - if ( props == null ) - { log.warn( "No configuration settings found. Using hardcoded default values for all pools." ); props = new Properties(); } @@ -368,7 +331,7 @@ public class ThreadPoolManager * @param root * @return PoolConfiguration */ - protected PoolConfiguration loadConfig( String root ) + private static PoolConfiguration loadConfig( String root ) { PoolConfiguration config = (PoolConfiguration) defaultConfig.clone(); Modified: commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/JCSConcurrentCacheAccessUnitTest.java URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/JCSConcurrentCacheAccessUnitTest.java?rev=1717801&r1=1717800&r2=1717801&view=diff ============================================================================== --- commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/JCSConcurrentCacheAccessUnitTest.java (original) +++ commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/JCSConcurrentCacheAccessUnitTest.java Thu Dec 3 16:41:49 2015 @@ -19,22 +19,24 @@ package org.apache.commons.jcs; * under the License. */ -import junit.framework.Assert; +import java.util.concurrent.atomic.AtomicInteger; + import junit.framework.TestCase; + import org.apache.commons.jcs.access.GroupCacheAccess; import org.apache.commons.jcs.access.exception.CacheException; -import java.util.concurrent.atomic.AtomicInteger; - /** * Test Case for JCS-73, modeled after the Groovy code by Alexander Kleymenov * * @author Thomas Vandahl * */ -public class JCSConcurrentCacheAccessUnitTest - extends TestCase +public class JCSConcurrentCacheAccessUnitTest extends TestCase { + private final static int THREADS = 10; + private final static int LOOPS = 10000; + /** * the cache instance */ @@ -78,7 +80,7 @@ public class JCSConcurrentCacheAccessUni { String name = getName(); - for (int idx = 0; idx < 10000; idx++) + for (int idx = 0; idx < LOOPS; idx++) { if (idx > 0) { @@ -116,7 +118,7 @@ public class JCSConcurrentCacheAccessUni } } - Assert.assertEquals("Values do not match", String.valueOf(idx-1), res); + assertEquals("Values do not match", String.valueOf(idx-1), res); } // put value in the cache @@ -145,15 +147,15 @@ public class JCSConcurrentCacheAccessUni public void testConcurrentAccess() throws Exception { - Worker[] worker = new Worker[10]; + Worker[] worker = new Worker[THREADS]; - for (int i = 0; i < 10; i++) + for (int i = 0; i < THREADS; i++) { worker[i] = new Worker(); worker[i].start(); } - for (int i = 0; i < 10; i++) + for (int i = 0; i < THREADS; i++) { worker[i].join(); } Modified: commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/access/TestCacheAccess.java URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/access/TestCacheAccess.java?rev=1717801&r1=1717800&r2=1717801&view=diff ============================================================================== --- commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/access/TestCacheAccess.java (original) +++ commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/access/TestCacheAccess.java Thu Dec 3 16:41:49 2015 @@ -19,6 +19,14 @@ package org.apache.commons.jcs.access; * under the License. */ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Iterator; +import java.util.Map; +import java.util.Random; +import java.util.StringTokenizer; + import org.apache.commons.jcs.JCS; import org.apache.commons.jcs.access.exception.CacheException; import org.apache.commons.jcs.engine.ElementAttributes; @@ -28,14 +36,6 @@ import org.apache.commons.jcs.engine.con import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.Iterator; -import java.util.Map; -import java.util.Random; -import java.util.StringTokenizer; - /** * Allows the user to run common cache commands from the command line for a test cache. This also * provide basic methods for use in unit tests. @@ -271,10 +271,7 @@ public class TestCacheAccess } else if ( message.startsWith( "random" ) ) { - if ( message.startsWith( "random" ) ) - { - processRandom( message ); - } + processRandom( message ); } } } Modified: commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/utils/threadpool/ThreadPoolManagerUnitTest.java URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/utils/threadpool/ThreadPoolManagerUnitTest.java?rev=1717801&r1=1717800&r2=1717801&view=diff ============================================================================== --- commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/utils/threadpool/ThreadPoolManagerUnitTest.java (original) +++ commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/utils/threadpool/ThreadPoolManagerUnitTest.java Thu Dec 3 16:41:49 2015 @@ -19,13 +19,14 @@ package org.apache.commons.jcs.utils.thr * under the License. */ -import junit.framework.TestCase; -import org.apache.commons.jcs.utils.props.PropertyLoader; -import org.apache.commons.jcs.utils.threadpool.PoolConfiguration.WhenBlockedPolicy; - import java.util.ArrayList; +import java.util.Properties; import java.util.concurrent.ThreadPoolExecutor; +import junit.framework.TestCase; + +import org.apache.commons.jcs.utils.props.PropertyLoader; + /** * Verify that the manager can create pools as intended by the default and * specified file names. @@ -41,7 +42,8 @@ public class ThreadPoolManagerUnitTest */ public void testDefaultConfig() { - ThreadPoolManager.setPropsFileName( "thread_pool.properties" ); + Properties props = PropertyLoader.loadProperties( "thread_pool.properties" ); + ThreadPoolManager.setProps( props ); ThreadPoolManager mgr = ThreadPoolManager.getInstance(); assertNotNull( mgr ); @@ -49,16 +51,14 @@ public class ThreadPoolManagerUnitTest assertNotNull( pool ); int poolSize = pool.getPoolSize(); - int expectedPoolSize = Integer.parseInt( PropertyLoader.loadProperties( "thread_pool.properties" ) - .getProperty( "thread_pool.test1.startUpSize" ) ); + int expectedPoolSize = Integer.parseInt( props.getProperty( "thread_pool.test1.startUpSize" ) ); assertEquals( poolSize, expectedPoolSize ); // int qs = ((BoundedBuffer)pool.getQueue()).size(); int max = pool.getMaximumPoolSize(); - int expected = Integer.parseInt( PropertyLoader.loadProperties( "thread_pool.properties" ) - .getProperty( "thread_pool.test1.maximumPoolSize" ) ); + int expected = Integer.parseInt( props.getProperty( "thread_pool.test1.maximumPoolSize" ) ); assertEquals(expected, max ); } @@ -67,7 +67,8 @@ public class ThreadPoolManagerUnitTest */ public void testDefaultConfigUndefinedPool() { - ThreadPoolManager.setPropsFileName( "thread_pool.properties" ); + Properties props = PropertyLoader.loadProperties( "thread_pool.properties" ); + ThreadPoolManager.setProps( props ); ThreadPoolManager mgr = ThreadPoolManager.getInstance(); assertNotNull( mgr ); @@ -76,30 +77,7 @@ public class ThreadPoolManagerUnitTest int max = pool.getMaximumPoolSize(); - int expected = Integer.parseInt( PropertyLoader.loadProperties( "thread_pool.properties" ) - .getProperty( "thread_pool.default.maximumPoolSize" ) ); - assertEquals( expected, max ); - } - - /** - * Makes ure we can get a non existent pool from the non exitent config - * file. - */ - public void testNonExistentConfigFile() - { - ThreadPoolManager.setPropsFileName( "somefilethatdoesntexist" ); - ThreadPoolManager mgr = ThreadPoolManager.getInstance(); - assertNotNull( mgr ); - - ThreadPoolExecutor pool = mgr.getPool( "doesntexist" ); - assertNotNull( "Should have gotten back a pool configured like the default", pool ); - - int max = pool.getMaximumPoolSize(); - - // it will load from the default file - int expected = Integer.parseInt( PropertyLoader.loadProperties( "cache.ccf" ) - .getProperty( "thread_pool.default.maximumPoolSize" ) ); - + int expected = Integer.parseInt( props.getProperty( "thread_pool.default.maximumPoolSize" ) ); assertEquals( expected, max ); } @@ -124,35 +102,6 @@ public class ThreadPoolManagerUnitTest } /** - * Verify that the wait policy gets set correctly. - * - * Switched off as the POLICY_WAIT is not supported by the javax.concurrent package - */ - public void OFFtestWaitPolicyConfig() - { - ThreadPoolManager.setPropsFileName( "thread_pool.properties" ); - ThreadPoolManager mgr = ThreadPoolManager.getInstance(); - // force config from new props file - mgr.configure(); - assertNotNull( mgr ); - - ThreadPoolExecutor pool = mgr.getPool( "waittest" ); - assertNotNull( "Should have gotten back a pool.", pool ); - - int max = pool.getMaximumPoolSize(); - - // it will load from the default file - int expected = Integer.parseInt( PropertyLoader.loadProperties( "thread_pool.properties" ) - .getProperty( "thread_pool.waittest.maximumPoolSize" ) ); - - assertEquals( "Max is wrong", expected, max ); - - PoolConfiguration config = mgr.loadConfig( "thread_pool.waittest" ); - - assertEquals( "Policy is wrong.", WhenBlockedPolicy.WAIT, config.getWhenBlockedPolicy() ); - } - - /** * Verify that if we specify not to use a buffer boundary that we get a * linked queue. * @@ -161,8 +110,6 @@ public class ThreadPoolManagerUnitTest // { // ThreadPoolManager.setPropsFileName( "thread_pool.properties" ); // ThreadPoolManager mgr = ThreadPoolManager.getInstance(); -// // force config from new props file -// mgr.configure(); // assertNotNull( mgr ); // // ThreadPoolExecutor pool = mgr.getPool( "nobound" ); @@ -180,8 +127,6 @@ public class ThreadPoolManagerUnitTest // // SETUP // ThreadPoolManager.setPropsFileName( "thread_pool.properties" ); // ThreadPoolManager mgr = ThreadPoolManager.getInstance(); -// // force config from new props file -// mgr.configure(); // assertNotNull( mgr ); // // // DO WORK Modified: commons/proper/jcs/trunk/src/changes/changes.xml URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/src/changes/changes.xml?rev=1717801&r1=1717800&r2=1717801&view=diff ============================================================================== --- commons/proper/jcs/trunk/src/changes/changes.xml (original) +++ commons/proper/jcs/trunk/src/changes/changes.xml Thu Dec 3 16:41:49 2015 @@ -20,6 +20,9 @@ </properties> <body> <release version="2.0" date="unreleased" description="JDK 1.6 based major release"> + <action dev="tv" type="update"> + Reduce synchronization + </action> <action issue="JCS-153" dev="tv" type="fix" due-to="Wiktor Niesiobedzki"> Fix file size limitation for Block Disk Cache and Indexed Disk Cache </action>