You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by tv...@apache.org on 2015/04/06 17:28:11 UTC
svn commit: r1671552 [1/2] - in /commons/proper/jcs/trunk:
commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/
commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/behavior/
commons-jcs-core/src/main/java/org/apache/co...
Author: tv
Date: Mon Apr 6 15:28:10 2015
New Revision: 1671552
URL: http://svn.apache.org/r1671552
Log:
JCS-147: Provide file size limitation for Block Disk Cache and Indexed Disk Cache
Added:
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/struct/AbstractLRUMap.java (with props)
commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheUnitTestCount.java (with props)
commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheUnitTestSize.java (with props)
commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexDiskCacheUnitTestCount.java (with props)
commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexDiskCacheUnitTestSize.java (with props)
commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/indexed/LRUMapSizeVsCount.java (with props)
Modified:
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/AbstractDiskCacheAttributes.java
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/behavior/IDiskCacheAttributes.java
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCache.java
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheAttributes.java
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskKeyStore.java
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCache.java
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCacheAttributes.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/test/java/org/apache/commons/jcs/auxiliary/disk/DiskTestObject.java
commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/LRUMapJCSUnitTest.java
commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheKeyStoreUnitTest.java
commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheUnitTest.java
commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexDiskCacheUnitTest.java
commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCacheSameRegionConcurrentUnitTest.java
commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/utils/struct/JCSvsCommonsLRUMapPerformanceTest.java
commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/utils/struct/LRUMapPerformanceTest.java
commons/proper/jcs/trunk/src/changes/changes.xml
commons/proper/jcs/trunk/xdocs/BlockDiskCache.xml
commons/proper/jcs/trunk/xdocs/IndexedDiskAuxCache.xml
Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/AbstractDiskCacheAttributes.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/AbstractDiskCacheAttributes.java?rev=1671552&r1=1671551&r2=1671552&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/AbstractDiskCacheAttributes.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/AbstractDiskCacheAttributes.java Mon Apr 6 15:28:10 2015
@@ -58,6 +58,10 @@ public abstract class AbstractDiskCacheA
*/
private int shutdownSpoolTimeLimit = DEFAULT_shutdownSpoolTimeLimit;
+ private DiskLimitType diskLimitType = DiskLimitType.COUNT;
+
+ private int chunkSize;
+
/**
* Sets the diskPath attribute of the DiskCacheAttributes object
* <p>
@@ -203,4 +207,27 @@ public abstract class AbstractDiskCacheA
str.append( "\n ShutdownSpoolTimeLimit = " + getShutdownSpoolTimeLimit() );
return str.toString();
}
+ @Override
+ public void setDiskLimitType(DiskLimitType diskLimitType) {
+ this.diskLimitType = diskLimitType;
+
+ }
+
+ @Override
+ public void setDiskLimitTypeName(String diskLimitTypeName) {
+ if (diskLimitTypeName != null) {
+ String name = diskLimitTypeName.trim();
+ if ("COUNT".equals(name)) {
+ diskLimitType = DiskLimitType.COUNT;
+ } else if ("SIZE".equals(name)) {
+ diskLimitType = DiskLimitType.SIZE;
+ }
+ }
+
+ }
+
+ @Override
+ public DiskLimitType getDiskLimitType() {
+ return diskLimitType;
+ }
}
Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/behavior/IDiskCacheAttributes.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/behavior/IDiskCacheAttributes.java?rev=1671552&r1=1671551&r2=1671552&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/behavior/IDiskCacheAttributes.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/behavior/IDiskCacheAttributes.java Mon Apr 6 15:28:10 2015
@@ -29,6 +29,12 @@ import java.io.File;
public interface IDiskCacheAttributes
extends AuxiliaryCacheAttributes
{
+ enum DiskLimitType {
+ /** limit elements by count (default) */
+ COUNT,
+ /** limit elements by their size */
+ SIZE
+ }
/**
* This is the default purgatory size limit. Purgatory is the area where
* items to be spooled are temporarily stored. It basically provides access
@@ -102,4 +108,24 @@ public interface IDiskCacheAttributes
* @param allowRemoveAll
*/
void setAllowRemoveAll( boolean allowRemoveAll );
+
+ /**
+ * set the type of the limit of the cache size
+ * @param diskLimitType COUNT - limit by count of the elements, SIZE, limit by sum of element's size
+ */
+ void setDiskLimitType(DiskLimitType diskLimitType);
+
+ /**
+ * Translates and stores String values of DiskLimitType
+ *
+ * Allowed values: "COUNT" and "SIZE"
+ * @param diskLimitTypeName
+ */
+ void setDiskLimitTypeName(String diskLimitTypeName);
+
+ /**
+ *
+ * @return active DiskLimitType
+ */
+ DiskLimitType getDiskLimitType();
}
Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCache.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCache.java?rev=1671552&r1=1671551&r2=1671552&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCache.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCache.java Mon Apr 6 15:28:10 2015
@@ -21,6 +21,7 @@ package org.apache.commons.jcs.auxiliary
import org.apache.commons.jcs.auxiliary.AuxiliaryCacheAttributes;
import org.apache.commons.jcs.auxiliary.disk.AbstractDiskCache;
+import org.apache.commons.jcs.auxiliary.disk.behavior.IDiskCacheAttributes.DiskLimitType;
import org.apache.commons.jcs.engine.CacheConstants;
import org.apache.commons.jcs.engine.behavior.ICacheElement;
import org.apache.commons.jcs.engine.behavior.IElementSerializer;
Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheAttributes.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheAttributes.java?rev=1671552&r1=1671551&r2=1671552&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheAttributes.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheAttributes.java Mon Apr 6 15:28:10 2015
@@ -112,6 +112,7 @@ public class BlockDiskCacheAttributes
str.append( "\n MaxPurgatorySize [" + this.getMaxPurgatorySize() + "]" );
str.append( "\n BlockSizeBytes [" + this.getBlockSizeBytes() + "]" );
str.append( "\n KeyPersistenceIntervalSeconds [" + this.getKeyPersistenceIntervalSeconds() + "]" );
+ str.append( "\n DiskLimitType [" + this.getDiskLimitType() + "]" );
return str.toString();
}
}
Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskKeyStore.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskKeyStore.java?rev=1671552&r1=1671551&r2=1671552&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskKeyStore.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskKeyStore.java Mon Apr 6 15:28:10 2015
@@ -20,7 +20,11 @@ package org.apache.commons.jcs.auxiliary
*/
import org.apache.commons.jcs.auxiliary.disk.LRUMapJCS;
+import org.apache.commons.jcs.auxiliary.disk.behavior.IDiskCacheAttributes.DiskLimitType;
+import org.apache.commons.jcs.auxiliary.disk.indexed.IndexedDiskElementDescriptor;
import org.apache.commons.jcs.io.ObjectInputStreamClassLoaderAware;
+import org.apache.commons.jcs.utils.struct.AbstractLRUMap;
+import org.apache.commons.jcs.utils.struct.LRUMap;
import org.apache.commons.jcs.utils.timing.ElapsedTimer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -37,6 +41,7 @@ import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* This is responsible for storing the keys.
@@ -69,6 +74,10 @@ public class BlockDiskKeyStore<K>
/** we need this so we can communicate free blocks to the data store when keys fall off the LRU */
protected final BlockDiskCache<K, ?> blockDiskCache;
+ private DiskLimitType diskLimitType = DiskLimitType.COUNT;
+
+ private int blockSize;
+
/**
* Set the configuration options.
* <p>
@@ -83,6 +92,8 @@ public class BlockDiskKeyStore<K>
this.fileName = this.blockDiskCacheAttributes.getCacheName();
this.maxKeySize = cacheAttributes.getMaxKeySize();
this.blockDiskCache = blockDiskCache;
+ this.diskLimitType = cacheAttributes.getDiskLimitType();
+ this.blockSize = cacheAttributes.getBlockSizeBytes();
File rootDirectory = cacheAttributes.getDiskPath();
@@ -190,7 +201,11 @@ public class BlockDiskKeyStore<K>
keyHash = null;
if ( maxKeySize >= 0 )
{
- keyHash = new LRUMap( maxKeySize );
+ if (this.diskLimitType.equals(DiskLimitType.SIZE)) {
+ keyHash = new LRUMapSizeLimited(maxKeySize);
+ } else {
+ keyHash = new LRUMapCountLimited( maxKeySize );
+ }
if ( log.isInfoEnabled() )
{
log.info( logCacheName + "Set maxKeySize to: '" + maxKeySize + "'" );
@@ -338,22 +353,27 @@ public class BlockDiskKeyStore<K>
return this.keyHash.remove( key );
}
+
/**
- * Class for recycling and lru. This implements the LRU overflow callback, so we can mark the
+ * Class for recycling and lru. This implements the LRU size overflow callback, so we can mark the
* blocks as free.
*/
- public class LRUMap
- extends LRUMapJCS<K, int[]>
+
+ public class LRUMapSizeLimited
+ extends AbstractLRUMap<K, int[]>
+
{
/**
* <code>tag</code> tells us which map we are working on.
*/
- public String tag = "orig";
-
+ public String tag = "orig-lru-size";
+ // size of the content in kB
+ private AtomicInteger contentSize = new AtomicInteger();
+ private int maxSize = -1;
/**
* Default
*/
- public LRUMap()
+ public LRUMapSizeLimited()
{
super();
}
@@ -361,11 +381,76 @@ public class BlockDiskKeyStore<K>
/**
* @param maxKeySize
*/
- public LRUMap( int maxKeySize )
+ public LRUMapSizeLimited( int maxKeySize )
{
- super( maxKeySize );
+ super();
+ this.maxSize = maxKeySize;
}
+ @Override
+ public int[] put(K key, int[] value) {
+ try {
+ return super.put(key, value);
+ } finally {
+ // keep the content size in kB, so 2^31 kB is reasonable value
+ contentSize.addAndGet((int) Math.ceil(value.length * blockSize / 1024.0));
+ }
+ }
+
+ @Override
+ public int[] remove(Object key ) {
+ int[] value = null;
+
+ try {
+ value = super.remove(key);
+ return value;
+ } finally {
+ if (value != null) {
+ // keep the content size in kB, so 2^31 kB is reasonable value
+ contentSize.addAndGet((int) ((Math.ceil(value.length * blockSize / 1024.0)) * -1));
+ }
+ }
+ }
+
+ /**
+ * This is called when the may key size is reached. The least recently used item will be
+ * passed here. We will store the position and size of the spot on disk in the recycle bin.
+ * <p>
+ * @param key
+ * @param value
+ */
+ protected void processRemovedLRU( K key, int[] value )
+ {
+ blockDiskCache.freeBlocks( value );
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( logCacheName + "Removing key: [" + key + "] from key store." );
+ log.debug( logCacheName + "Key store size: [" + super.size() + "]." );
+ }
+ }
+ @Override
+ protected boolean shouldRemove() {
+ return maxSize > 0 && contentSize.intValue() > maxSize && this.size() > 1;
+ }
+ }
+ /**
+ * Class for recycling and lru. This implements the LRU overflow callback, so we can mark the
+ * blocks as free.
+ */
+ public class LRUMapCountLimited
+ extends LRUMap<K, int[]>
+ // implements Serializable
+ {
+ /**
+ * <code>tag</code> tells us which map we are working on.
+ */
+ public String tag = "orig-lru-count";
+
+ public LRUMapCountLimited(int maxKeySize) {
+ super(maxKeySize);
+ }
+
+
/**
* This is called when the may key size is reached. The least recently used item will be
* passed here. We will store the position and size of the spot on disk in the recycle bin.
Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCache.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCache.java?rev=1671552&r1=1671551&r2=1671552&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCache.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCache.java Mon Apr 6 15:28:10 2015
@@ -21,7 +21,7 @@ package org.apache.commons.jcs.auxiliary
import org.apache.commons.jcs.auxiliary.AuxiliaryCacheAttributes;
import org.apache.commons.jcs.auxiliary.disk.AbstractDiskCache;
-import org.apache.commons.jcs.auxiliary.disk.LRUMapJCS;
+import org.apache.commons.jcs.auxiliary.disk.behavior.IDiskCacheAttributes.DiskLimitType;
import org.apache.commons.jcs.engine.CacheConstants;
import org.apache.commons.jcs.engine.behavior.ICacheElement;
import org.apache.commons.jcs.engine.behavior.IElementSerializer;
@@ -33,6 +33,8 @@ 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.struct.AbstractLRUMap;
+import org.apache.commons.jcs.utils.struct.LRUMap;
import org.apache.commons.jcs.utils.struct.SortedPreferentialArray;
import org.apache.commons.jcs.utils.timing.ElapsedTimer;
import org.apache.commons.logging.Log;
@@ -131,6 +133,9 @@ public class IndexedDiskCache<K, V>
/** the number of bytes free on disk. */
private long bytesFree = 0;
+ /** mode we are working on (size or count limited **/
+ private DiskLimitType diskLimitType = DiskLimitType.COUNT;
+
/** simple stat */
private AtomicInteger hitCount = new AtomicInteger(0);
@@ -166,6 +171,7 @@ public class IndexedDiskCache<K, V>
this.isRealTimeOptimizationEnabled = cattr.getOptimizeAtRemoveCount() > 0;
this.isShutdownOptimizationEnabled = cattr.isOptimizeOnShutdown();
this.logCacheName = "Region [" + getCacheName() + "] ";
+ this.diskLimitType = cattr.getDiskLimitType();
// Make a clean file name
this.fileName = getCacheName().replaceAll("[^a-zA-Z0-9-_\\.]", "_");
@@ -1017,7 +1023,12 @@ public class IndexedDiskCache<K, V>
keyHash = null;
if ( maxKeySize >= 0 )
{
- keyHash = new LRUMap( maxKeySize );
+ if (this.diskLimitType.equals(DiskLimitType.COUNT)) {
+ keyHash = new LRUMapCountLimited( maxKeySize );
+ } else {
+ keyHash = new LRUMapSizeLimited(maxKeySize);
+ }
+
if ( log.isInfoEnabled() )
{
log.info( logCacheName + "Set maxKeySize to: '" + maxKeySize + "'" );
@@ -1566,6 +1577,7 @@ public class IndexedDiskCache<K, V>
{
log.error( e );
}
+ elems.add(new StatElement<Integer>( "Max Key Size", this.maxKeySize));
elems.add(new StatElement<Integer>( "Hit Count", Integer.valueOf(this.hitCount.get()) ) );
elems.add(new StatElement<Long>( "Bytes Free", Long.valueOf(this.bytesFree) ) );
elems.add(new StatElement<Integer>( "Optimize Operation Count", Integer.valueOf(this.removeCount) ) );
@@ -1642,21 +1654,22 @@ public class IndexedDiskCache<K, V>
/**
* Class for recycling and lru. This implements the LRU overflow callback, so we can add items
- * to the recycle bin.
+ * to the recycle bin. This class counts the size element to decide, when to throw away an element
*/
- public class LRUMap
- extends LRUMapJCS<K, IndexedDiskElementDescriptor>
- // implements Serializable
+ public class LRUMapSizeLimited
+ extends AbstractLRUMap<K, IndexedDiskElementDescriptor>
{
/**
* <code>tag</code> tells us which map we are working on.
*/
public String tag = "orig";
-
+ // size of the content in kB
+ private AtomicInteger contentSize = new AtomicInteger();
+ private int maxSize = -1;
/**
* Default
*/
- public LRUMap()
+ public LRUMapSizeLimited()
{
super();
}
@@ -1664,11 +1677,79 @@ public class IndexedDiskCache<K, V>
/**
* @param maxKeySize
*/
- public LRUMap( int maxKeySize )
+ public LRUMapSizeLimited( int maxKeySize )
+ {
+ super();
+ this.maxSize = maxKeySize;
+ }
+
+ @Override
+ public IndexedDiskElementDescriptor put(K key, IndexedDiskElementDescriptor value) {
+ try {
+ return super.put(key, value);
+ } finally {
+ // keep the content size in kB, so 2^31 kB is reasonable value
+ contentSize.addAndGet((int) Math.ceil((value.len + IndexedDisk.HEADER_SIZE_BYTES) / 1024.0));
+ }
+ }
+
+ @Override
+ public IndexedDiskElementDescriptor remove(Object key ) {
+ IndexedDiskElementDescriptor value = null;
+
+ try {
+ value = super.remove(key);
+ return value;
+ } finally {
+ if (value != null) {
+ // keep the content size in kB, so 2^31 kB is reasonable value
+ contentSize.addAndGet((int) ((Math.ceil((value.len + IndexedDisk.HEADER_SIZE_BYTES) / 1024.0)) * -1));
+ }
+ }
+ }
+
+ /**
+ * This is called when the may key size is reached. The least recently used item will be
+ * passed here. We will store the position and size of the spot on disk in the recycle bin.
+ * <p>
+ * @param key
+ * @param value
+ */
+ @Override
+ protected void processRemovedLRU(K key, IndexedDiskElementDescriptor value )
{
- super( maxKeySize );
+ if (value != null) {
+ // keep the content size in kB, so 2^31 kB is reasonable value
+ contentSize.addAndGet((int) ((Math.ceil(value.len / 1024.0)) * -1));
+ }
+ addToRecycleBin( value );
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( logCacheName + "Removing key: [" + key + "] from key store." );
+ log.debug( logCacheName + "Key store size: [" + this.size() + "]." );
+ }
+
+ doOptimizeRealTime();
}
+ @Override
+ protected boolean shouldRemove() {
+ return maxSize > 0 && contentSize.intValue() > maxSize && this.size() > 0;
+ }
+ }
+
+ /**
+ * Class for recycling and lru. This implements the LRU overflow callback, so we can add items
+ * to the recycle bin. This class counts the elements to decide, when to throw away an element
+ */
+
+ public class LRUMapCountLimited
+ extends LRUMap<K, IndexedDiskElementDescriptor>
+ // implements Serializable
+ {
+ public LRUMapCountLimited(int maxKeySize) {
+ super(maxKeySize);
+ }
/**
* This is called when the may key size is reached. The least recently used item will be
* passed here. We will store the position and size of the spot on disk in the recycle bin.
Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCacheAttributes.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCacheAttributes.java?rev=1671552&r1=1671551&r2=1671552&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCacheAttributes.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCacheAttributes.java Mon Apr 6 15:28:10 2015
@@ -60,6 +60,8 @@ public class IndexedDiskCacheAttributes
/** Should we clear the disk on startup. If true the congtents of disk are cleared. */
private boolean clearDiskOnStartup = DEFAULT_CLEAR_DISK_ON_STARTUP;
+ private DiskLimitType diskLimitType = DiskLimitType.COUNT;
+
/**
* Constructor for the DiskCacheAttributes object
*/
Added: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/struct/AbstractLRUMap.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/struct/AbstractLRUMap.java?rev=1671552&view=auto
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/struct/AbstractLRUMap.java (added)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/struct/AbstractLRUMap.java Mon Apr 6 15:28:10 2015
@@ -0,0 +1,671 @@
+package org.apache.commons.jcs.utils.struct;
+
+/*
+ * 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.
+ */
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+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;
+
+import org.apache.commons.jcs.engine.control.group.GroupAttrName;
+import org.apache.commons.jcs.engine.stats.StatElement;
+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.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * This is a simple LRUMap. It implements most of the map methods. It is not recommended that you
+ * use any but put, get, remove, and clear.
+ * <p>
+ * Children can implement the processRemovedLRU method if they want to handle the removal of the
+ * lest recently used item.
+ * <p>
+ * This class was abstracted out of the LRU Memory cache. Put, remove, and get should be thread
+ * safe. It uses a hashtable and our own double linked list.
+ * <p>
+ * Locking is done on the instance.
+ * <p>
+ * @author aaron smuts
+ */
+public abstract class AbstractLRUMap<K, V>
+ implements Map<K, V>
+{
+ /** The logger */
+ private static final Log log = LogFactory.getLog( AbstractLRUMap.class );
+
+ /** double linked list for lru */
+ private final DoubleLinkedList<LRUElementDescriptor<K, V>> list;
+
+ /** Map where items are stored by key. */
+ private Map<K, LRUElementDescriptor<K, V>> map;
+
+ /** stats */
+ int hitCnt = 0;
+
+ /** stats */
+ int missCnt = 0;
+
+ /** stats */
+ int putCnt = 0;
+
+ /** 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.
+ */
+ public AbstractLRUMap()
+ {
+ list = new DoubleLinkedList<LRUElementDescriptor<K, V>>();
+
+ // normal hshtable is faster for
+ // sequential keys.
+ map = new ConcurrentHashMap<K, LRUElementDescriptor<K, V>>();
+ // map = new ConcurrentHashMap();
+ }
+
+
+ /**
+ * This simply returned the number of elements in the map.
+ * <p>
+ * @see java.util.Map#size()
+ */
+ @Override
+ public int size()
+ {
+ return map.size();
+ }
+
+ /**
+ * This removes all the items. It clears the map and the double linked list.
+ * <p>
+ * @see java.util.Map#clear()
+ */
+ @Override
+ public void clear()
+ {
+ lock.lock();
+ try
+ {
+ map.clear();
+ list.removeAll();
+ }
+ finally
+ {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Returns true if the map is empty.
+ * <p>
+ * @see java.util.Map#isEmpty()
+ */
+ @Override
+ public boolean isEmpty()
+ {
+ return map.size() == 0;
+ }
+
+ /**
+ * Returns true if the map contains an element for the supplied key.
+ * <p>
+ * @see java.util.Map#containsKey(java.lang.Object)
+ */
+ @Override
+ public boolean containsKey( Object key )
+ {
+ return map.containsKey( key );
+ }
+
+ /**
+ * This is an expensive operation that determines if the object supplied is mapped to any key.
+ * <p>
+ * @see java.util.Map#containsValue(java.lang.Object)
+ */
+ @Override
+ public boolean containsValue( Object value )
+ {
+ return map.containsValue( value );
+ }
+
+ /**
+ * @return map.values();
+ */
+ @Override
+ public Collection<V> values()
+ {
+ List<V> valueList = new ArrayList<V>(map.size());
+
+ for (LRUElementDescriptor<K, V> value : map.values())
+ {
+ valueList.add(value.getPayload());
+ }
+
+ return valueList;
+ }
+
+ /**
+ * @param source
+ */
+ @Override
+ public void putAll( Map<? extends K, ? extends V> source )
+ {
+ if ( source != null )
+ {
+ for (Map.Entry<? extends K, ? extends V> entry : source.entrySet())
+ {
+ this.put( entry.getKey(), entry.getValue() );
+ }
+ }
+ }
+
+ /**
+ * @param key
+ * @return Object
+ */
+ @Override
+ public V get( Object key )
+ {
+ V retVal = null;
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "getting item for key " + key );
+ }
+
+ LRUElementDescriptor<K, V> me = map.get( key );
+
+ if ( me != null )
+ {
+ hitCnt++;
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "LRUMap hit for " + key );
+ }
+
+ retVal = me.getPayload();
+
+ list.makeFirst( me );
+ }
+ else
+ {
+ missCnt++;
+ log.debug( "LRUMap miss for " + key );
+ }
+
+ // verifyCache();
+ return retVal;
+ }
+
+ /**
+ * This gets an element out of the map without adjusting it's posisiton in the LRU. In other
+ * words, this does not count as being used. If the element is the last item in the list, it
+ * will still be the last itme in the list.
+ * <p>
+ * @param key
+ * @return Object
+ */
+ public V getQuiet( Object key )
+ {
+ V ce = null;
+
+ LRUElementDescriptor<K, V> me = map.get( key );
+ if ( me != null )
+ {
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "LRUMap quiet hit for " + key );
+ }
+
+ ce = me.getPayload();
+ }
+ else if ( log.isDebugEnabled() )
+ {
+ log.debug( "LRUMap quiet miss for " + key );
+ }
+
+ return ce;
+ }
+
+ /**
+ * @param key
+ * @return Object removed
+ */
+ @Override
+ public V remove( Object key )
+ {
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "removing item for key: " + key );
+ }
+
+ // remove single item.
+ lock.lock();
+ try
+ {
+ LRUElementDescriptor<K, V> me = map.remove(key);
+
+ if (me != null)
+ {
+ list.remove(me);
+ return me.getPayload();
+ }
+ }
+ finally
+ {
+ lock.unlock();
+ }
+
+ return null;
+ }
+
+ /**
+ * @param key
+ * @param value
+ * @return Object
+ */
+ @Override
+ public V put(K key, V value)
+ {
+ putCnt++;
+
+ LRUElementDescriptor<K, V> old = null;
+ lock.lock();
+ try
+ {
+ // TODO address double synchronization of addFirst, use write lock
+ addFirst( key, value );
+ // this must be synchronized
+ LRUElementDescriptor<K, V> first = list.getFirst();
+ old = map.put(first.getKey(), first);
+
+ // If the node was the same as an existing node, remove it.
+ if ( old != null && first.getKey().equals(old.getKey()))
+ {
+ list.remove( old );
+ }
+ }
+ finally
+ {
+ lock.unlock();
+ }
+
+ // If the element limit is reached, we need to spool
+
+ if (shouldRemove())
+ {
+ final boolean debugEnabled = log.isDebugEnabled();
+ if (debugEnabled)
+ {
+ log.debug( "In memory limit reached, removing least recently used." );
+ }
+
+ // 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.
+
+ while ( shouldRemove() )
+ {
+ lock.lock();
+ try
+ {
+ 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
+ {
+ verifyCache();
+ throw new Error("update: last is null!");
+ }
+ }
+ finally
+ {
+ lock.unlock();
+ }
+ }
+
+ if ( log.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());
+ }
+ }
+
+ if ( old != null )
+ {
+ return old.getPayload();
+ }
+ return null;
+ }
+
+ protected abstract boolean shouldRemove();
+
+
+ /**
+ * Adds a new node to the start of the link list.
+ * <p>
+ * @param key
+ * @param val The feature to be added to the First
+ */
+ private void addFirst(K key, V val)
+ {
+ lock.lock();
+ try
+ {
+ LRUElementDescriptor<K, V> me = new LRUElementDescriptor<K, V>(key, val);
+ list.addFirst( me );
+ }
+ finally
+ {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Returns the size of the list.
+ * <p>
+ * @return int
+ */
+ private int dumpCacheSize()
+ {
+ return list.size();
+ }
+
+ /**
+ * Dump the cache entries from first to list for debugging.
+ */
+ @SuppressWarnings("unchecked") // No generics for public fields
+ public void dumpCacheEntries()
+ {
+ log.debug( "dumpingCacheEntries" );
+ for ( LRUElementDescriptor<K, V> me = list.getFirst(); me != null; me = (LRUElementDescriptor<K, V>) me.next )
+ {
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "dumpCacheEntries> key=" + me.getKey() + ", val=" + me.getPayload() );
+ }
+ }
+ }
+
+ /**
+ * Dump the cache map for debugging.
+ */
+ public void dumpMap()
+ {
+ log.debug( "dumpingMap" );
+ for (Map.Entry<K, LRUElementDescriptor<K, V>> e : map.entrySet())
+ {
+ LRUElementDescriptor<K, V> me = e.getValue();
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "dumpMap> key=" + e.getKey() + ", val=" + me.getPayload() );
+ }
+ }
+ }
+
+ /**
+ * 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()
+ {
+ if ( !log.isDebugEnabled() )
+ {
+ return;
+ }
+
+ boolean found = false;
+ log.debug( "verifycache: mapContains " + map.size() + " elements, linked list contains " + dumpCacheSize()
+ + " elements" );
+ log.debug( "verifycache: checking linked list by key " );
+ for (LRUElementDescriptor<K, V> li = list.getFirst(); li != null; li = (LRUElementDescriptor<K, V>) li.next )
+ {
+ K key = li.getKey();
+ if ( !map.containsKey( key ) )
+ {
+ log.error( "verifycache: map does not contain key : " + li.getKey() );
+ log.error( "li.hashcode=" + li.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() );
+ }
+ dumpMap();
+ }
+ else if ( map.get( li.getKey() ) == null )
+ {
+ log.error( "verifycache: linked list retrieval returned null for key: " + li.getKey() );
+ }
+ }
+
+ log.debug( "verifycache: checking linked list by value " );
+ for (LRUElementDescriptor<K, V> li3 = list.getFirst(); li3 != null; li3 = (LRUElementDescriptor<K, V>) li3.next )
+ {
+ if ( map.containsValue( li3 ) == false )
+ {
+ log.error( "verifycache: map does not contain value : " + li3 );
+ dumpMap();
+ }
+ }
+
+ log.debug( "verifycache: checking via keysets!" );
+ for (Iterator<K> itr2 = map.keySet().iterator(); itr2.hasNext(); )
+ {
+ found = false;
+ Serializable val = null;
+ try
+ {
+ val = (Serializable) itr2.next();
+ }
+ catch ( NoSuchElementException nse )
+ {
+ log.error( "verifycache: no such element exception" );
+ continue;
+ }
+
+ for (LRUElementDescriptor<K, V> li2 = list.getFirst(); li2 != null; li2 = (LRUElementDescriptor<K, V>) li2.next )
+ {
+ if ( val.equals( li2.getKey() ) )
+ {
+ found = true;
+ break;
+ }
+ }
+ if ( !found )
+ {
+ log.error( "verifycache: key not found in list : " + val );
+ dumpCacheEntries();
+ if ( map.containsKey( val ) )
+ {
+ log.error( "verifycache: map contains key" );
+ }
+ else
+ {
+ log.error( "verifycache: map does NOT contain key, what the HECK!" );
+ }
+ }
+ }
+ }
+
+ /**
+ * Logs an error is an element that should be in the cache is not.
+ * <p>
+ * @param key
+ */
+ @SuppressWarnings("unchecked") // No generics for public fields
+ protected void verifyCache( Object key )
+ {
+ if ( !log.isDebugEnabled() )
+ {
+ return;
+ }
+
+ boolean found = false;
+
+ // go through the linked list looking for the key
+ for (LRUElementDescriptor<K, V> li = list.getFirst(); li != null; li = (LRUElementDescriptor<K, V>) li.next )
+ {
+ if ( li.getKey() == key )
+ {
+ found = true;
+ log.debug( "verifycache(key) key match: " + key );
+ break;
+ }
+ }
+ if ( !found )
+ {
+ log.error( "verifycache(key), couldn't find key! : " + key );
+ }
+ }
+
+ /**
+ * This is called when an item is removed from the LRU. We just log some information.
+ * <p>
+ * Children can implement this method for special behavior.
+ * @param key
+ * @param value
+ */
+ protected void processRemovedLRU(K key, V value )
+ {
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "Removing key: [" + key + "] from LRUMap store, value = [" + value + "]" );
+ log.debug( "LRUMap store size: '" + this.size() + "'." );
+ }
+ }
+
+ /**
+ * The chunk size is the number of items to remove when the max is reached. By default it is 1.
+ * <p>
+ * @param chunkSize The chunkSize to set.
+ */
+ public void setChunkSize( int chunkSize )
+ {
+ this.chunkSize = chunkSize;
+ }
+
+ /**
+ * @return Returns the chunkSize.
+ */
+ public int getChunkSize()
+ {
+ return chunkSize;
+ }
+
+ /**
+ * @return IStats
+ */
+ public IStats getStatistics()
+ {
+ IStats stats = new Stats();
+ stats.setTypeName( "LRUMap" );
+
+ 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) ) );
+
+ stats.setStatElements( elems );
+
+ return stats;
+ }
+
+ /**
+ * This returns a set of entries. Our LRUMapEntry is used since the value stored in the
+ * underlying map is a node in the double linked list. We wouldn't want to return this to the
+ * client, so we construct a new entry with the payload of the node.
+ * <p>
+ * TODO we should return out own set wrapper, so we can avoid the extra object creation if it
+ * isn't necessary.
+ * <p>
+ * @see java.util.Map#entrySet()
+ */
+ @Override
+ public Set<Map.Entry<K, V>> 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>>();
+
+ 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
+ {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * @return map.keySet();
+ */
+ @Override
+ public Set<K> keySet()
+ {
+ // TODO fix this, it needs to return the keys inside the wrappers.
+ return map.keySet();
+ }
+
+}
Propchange: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/struct/AbstractLRUMap.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
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=1671552&r1=1671551&r2=1671552&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 Mon Apr 6 15:28:10 2015
@@ -19,680 +19,42 @@ package org.apache.commons.jcs.utils.str
* under the License.
*/
-import org.apache.commons.jcs.engine.control.group.GroupAttrName;
-import org.apache.commons.jcs.engine.stats.StatElement;
-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.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-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;
+import java.util.concurrent.atomic.AtomicInteger;
/**
- * This is a simple LRUMap. It implements most of the map methods. It is not recommended that you
- * use any but put, get, remove, and clear.
- * <p>
- * Children can implement the processRemovedLRU method if they want to handle the removal of the
- * lest recently used item.
- * <p>
- * This class was abstracted out of the LRU Memory cache. Put, remove, and get should be thread
- * safe. It uses a hashtable and our own double linked list.
- * <p>
- * Locking is done on the instance.
- * <p>
- * @author aaron smuts
+ *
+ * @author Wiktor NiesiobÄdzki
+ *
+ * Simple LRUMap implementation that keeps the number of the objects below or equal maxObjects
+ *
+ * @param <K>
+ * @param <V>
*/
-public class LRUMap<K, V>
- implements Map<K, V>
-{
- /** The logger */
- private static final Log log = LogFactory.getLog( LRUMap.class );
-
- /** double linked list for lru */
- private final DoubleLinkedList<LRUElementDescriptor<K, V>> list;
-
- /** Map where items are stored by key. */
- private Map<K, LRUElementDescriptor<K, V>> map;
-
- /** stats */
- int hitCnt = 0;
-
- /** stats */
- int missCnt = 0;
-
- /** stats */
- int putCnt = 0;
+public class LRUMap<K, V> extends AbstractLRUMap<K, V> {
/** if the max is less than 0, there is no limit! */
int maxObjects = -1;
+ AtomicInteger counter = new AtomicInteger(0);
- /** 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.
- */
- public LRUMap()
- {
- list = new DoubleLinkedList<LRUElementDescriptor<K, V>>();
-
- // normal hshtable is faster for
- // sequential keys.
- map = new ConcurrentHashMap<K, LRUElementDescriptor<K, V>>();
- // map = new ConcurrentHashMap();
+ public LRUMap() {
+ super();
}
/**
- * This sets the size limit.
- * <p>
- * @param maxObjects
+ *
+ * @param maxObjects maximum number to keep in the map
*/
- public LRUMap( int maxObjects )
- {
- this();
+ public LRUMap(int maxObjects) {
+ super();
this.maxObjects = maxObjects;
}
- /**
- * This simply returned the number of elements in the map.
- * <p>
- * @see java.util.Map#size()
- */
- @Override
- public int size()
- {
- return map.size();
- }
-
- /**
- * This removes all the items. It clears the map and the double linked list.
- * <p>
- * @see java.util.Map#clear()
- */
- @Override
- public void clear()
- {
- lock.lock();
- try
- {
- map.clear();
- list.removeAll();
- }
- finally
- {
- lock.unlock();
- }
- }
-
- /**
- * Returns true if the map is empty.
- * <p>
- * @see java.util.Map#isEmpty()
- */
- @Override
- public boolean isEmpty()
- {
- return map.size() == 0;
- }
-
- /**
- * Returns true if the map contains an element for the supplied key.
- * <p>
- * @see java.util.Map#containsKey(java.lang.Object)
- */
- @Override
- public boolean containsKey( Object key )
- {
- return map.containsKey( key );
- }
-
- /**
- * This is an expensive operation that determines if the object supplied is mapped to any key.
- * <p>
- * @see java.util.Map#containsValue(java.lang.Object)
- */
- @Override
- public boolean containsValue( Object value )
- {
- return map.containsValue( value );
- }
-
- /**
- * @return map.values();
- */
- @Override
- public Collection<V> values()
- {
- List<V> valueList = new ArrayList<V>(map.size());
-
- for (LRUElementDescriptor<K, V> value : map.values())
- {
- valueList.add(value.getPayload());
- }
-
- return valueList;
- }
-
- /**
- * @param source
- */
- @Override
- public void putAll( Map<? extends K, ? extends V> source )
- {
- if ( source != null )
- {
- for (Map.Entry<? extends K, ? extends V> entry : source.entrySet())
- {
- this.put( entry.getKey(), entry.getValue() );
- }
- }
- }
-
- /**
- * @param key
- * @return Object
- */
- @Override
- public V get( Object key )
- {
- V retVal = null;
-
- if ( log.isDebugEnabled() )
- {
- log.debug( "getting item for key " + key );
- }
-
- LRUElementDescriptor<K, V> me = map.get( key );
-
- if ( me != null )
- {
- hitCnt++;
- if ( log.isDebugEnabled() )
- {
- log.debug( "LRUMap hit for " + key );
- }
-
- retVal = me.getPayload();
-
- list.makeFirst( me );
- }
- else
- {
- missCnt++;
- log.debug( "LRUMap miss for " + key );
- }
-
- // verifyCache();
- return retVal;
- }
-
- /**
- * This gets an element out of the map without adjusting it's posisiton in the LRU. In other
- * words, this does not count as being used. If the element is the last item in the list, it
- * will still be the last itme in the list.
- * <p>
- * @param key
- * @return Object
- */
- public V getQuiet( Object key )
- {
- V ce = null;
-
- LRUElementDescriptor<K, V> me = map.get( key );
- if ( me != null )
- {
- if ( log.isDebugEnabled() )
- {
- log.debug( "LRUMap quiet hit for " + key );
- }
-
- ce = me.getPayload();
- }
- else if ( log.isDebugEnabled() )
- {
- log.debug( "LRUMap quiet miss for " + key );
- }
-
- return ce;
- }
-
- /**
- * @param key
- * @return Object removed
- */
- @Override
- public V remove( Object key )
- {
- if ( log.isDebugEnabled() )
- {
- log.debug( "removing item for key: " + key );
- }
-
- // remove single item.
- lock.lock();
- try
- {
- LRUElementDescriptor<K, V> me = map.remove(key);
-
- if (me != null)
- {
- list.remove(me);
- return me.getPayload();
- }
- }
- finally
- {
- lock.unlock();
- }
-
- return null;
- }
-
- /**
- * @param key
- * @param value
- * @return Object
- */
- @Override
- public V put(K key, V value)
- {
- putCnt++;
-
- LRUElementDescriptor<K, V> old = null;
- lock.lock();
- try
- {
- // TODO address double synchronization of addFirst, use write lock
- addFirst( key, value );
- // this must be synchronized
- LRUElementDescriptor<K, V> first = list.getFirst();
- old = map.put(first.getKey(), first);
-
- // If the node was the same as an existing node, remove it.
- if ( old != null && first.getKey().equals(old.getKey()))
- {
- 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 )
- {
- final boolean debugEnabled = log.isDebugEnabled();
- if (debugEnabled)
- {
- log.debug( "In memory limit reached, removing least recently used." );
- }
-
- // Write the last 'chunkSize' items to disk.
- int chunkSizeCorrected = Math.min( size, getChunkSize() );
-
- if (debugEnabled)
- {
- log.debug( "About to remove the least recently used. map size: " + size + ", max objects: "
- + this.maxObjects + ", 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
- {
- 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
- {
- verifyCache();
- throw new Error("update: last is null!");
- }
- }
- finally
- {
- lock.unlock();
- }
- }
-
- if ( log.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());
- }
- }
-
- if ( old != null )
- {
- return old.getPayload();
- }
- return null;
- }
-
- /**
- * Adds a new node to the start of the link list.
- * <p>
- * @param key
- * @param val The feature to be added to the First
- */
- private void addFirst(K key, V val)
- {
- lock.lock();
- try
- {
- LRUElementDescriptor<K, V> me = new LRUElementDescriptor<K, V>(key, val);
- list.addFirst( me );
- }
- finally
- {
- lock.unlock();
- }
- }
-
- /**
- * Returns the size of the list.
- * <p>
- * @return int
- */
- private int dumpCacheSize()
- {
- return list.size();
- }
-
- /**
- * Dump the cache entries from first to list for debugging.
- */
- @SuppressWarnings("unchecked") // No generics for public fields
- public void dumpCacheEntries()
- {
- log.debug( "dumpingCacheEntries" );
- for ( LRUElementDescriptor<K, V> me = list.getFirst(); me != null; me = (LRUElementDescriptor<K, V>) me.next )
- {
- if ( log.isDebugEnabled() )
- {
- log.debug( "dumpCacheEntries> key=" + me.getKey() + ", val=" + me.getPayload() );
- }
- }
- }
-
- /**
- * Dump the cache map for debugging.
- */
- public void dumpMap()
- {
- log.debug( "dumpingMap" );
- for (Map.Entry<K, LRUElementDescriptor<K, V>> e : map.entrySet())
- {
- LRUElementDescriptor<K, V> me = e.getValue();
- if ( log.isDebugEnabled() )
- {
- log.debug( "dumpMap> key=" + e.getKey() + ", val=" + me.getPayload() );
- }
- }
- }
-
- /**
- * 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()
- {
- if ( !log.isDebugEnabled() )
- {
- return;
- }
-
- boolean found = false;
- log.debug( "verifycache: mapContains " + map.size() + " elements, linked list contains " + dumpCacheSize()
- + " elements" );
- log.debug( "verifycache: checking linked list by key " );
- for (LRUElementDescriptor<K, V> li = list.getFirst(); li != null; li = (LRUElementDescriptor<K, V>) li.next )
- {
- K key = li.getKey();
- if ( !map.containsKey( key ) )
- {
- log.error( "verifycache: map does not contain key : " + li.getKey() );
- log.error( "li.hashcode=" + li.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() );
- }
- dumpMap();
- }
- else if ( map.get( li.getKey() ) == null )
- {
- log.error( "verifycache: linked list retrieval returned null for key: " + li.getKey() );
- }
- }
-
- log.debug( "verifycache: checking linked list by value " );
- for (LRUElementDescriptor<K, V> li3 = list.getFirst(); li3 != null; li3 = (LRUElementDescriptor<K, V>) li3.next )
- {
- if ( map.containsValue( li3 ) == false )
- {
- log.error( "verifycache: map does not contain value : " + li3 );
- dumpMap();
- }
- }
-
- log.debug( "verifycache: checking via keysets!" );
- for (Iterator<K> itr2 = map.keySet().iterator(); itr2.hasNext(); )
- {
- found = false;
- Serializable val = null;
- try
- {
- val = (Serializable) itr2.next();
- }
- catch ( NoSuchElementException nse )
- {
- log.error( "verifycache: no such element exception" );
- continue;
- }
-
- for (LRUElementDescriptor<K, V> li2 = list.getFirst(); li2 != null; li2 = (LRUElementDescriptor<K, V>) li2.next )
- {
- if ( val.equals( li2.getKey() ) )
- {
- found = true;
- break;
- }
- }
- if ( !found )
- {
- log.error( "verifycache: key not found in list : " + val );
- dumpCacheEntries();
- if ( map.containsKey( val ) )
- {
- log.error( "verifycache: map contains key" );
- }
- else
- {
- log.error( "verifycache: map does NOT contain key, what the HECK!" );
- }
- }
- }
- }
-
- /**
- * Logs an error is an element that should be in the cache is not.
- * <p>
- * @param key
- */
- @SuppressWarnings("unchecked") // No generics for public fields
- protected void verifyCache( Object key )
- {
- if ( !log.isDebugEnabled() )
- {
- return;
- }
-
- boolean found = false;
-
- // go through the linked list looking for the key
- for (LRUElementDescriptor<K, V> li = list.getFirst(); li != null; li = (LRUElementDescriptor<K, V>) li.next )
- {
- if ( li.getKey() == key )
- {
- found = true;
- log.debug( "verifycache(key) key match: " + key );
- break;
- }
- }
- if ( !found )
- {
- log.error( "verifycache(key), couldn't find key! : " + key );
- }
- }
-
- /**
- * This is called when an item is removed from the LRU. We just log some information.
- * <p>
- * Children can implement this method for special behavior.
- * @param key
- * @param value
- */
- protected void processRemovedLRU(K key, V value )
- {
- if ( log.isDebugEnabled() )
- {
- log.debug( "Removing key: [" + key + "] from LRUMap store, value = [" + value + "]" );
- log.debug( "LRUMap store size: '" + this.size() + "'." );
- }
- }
-
- /**
- * The chunk size is the number of items to remove when the max is reached. By default it is 1.
- * <p>
- * @param chunkSize The chunkSize to set.
- */
- public void setChunkSize( int chunkSize )
- {
- this.chunkSize = chunkSize;
- }
-
- /**
- * @return Returns the chunkSize.
- */
- public int getChunkSize()
- {
- return chunkSize;
- }
-
- /**
- * @return IStats
- */
- public IStats getStatistics()
- {
- IStats stats = new Stats();
- stats.setTypeName( "LRUMap" );
-
- 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) ) );
-
- stats.setStatElements( elems );
-
- return stats;
- }
-
- /**
- * This returns a set of entries. Our LRUMapEntry is used since the value stored in the
- * underlying map is a node in the double linked list. We wouldn't want to return this to the
- * client, so we construct a new entry with the payload of the node.
- * <p>
- * TODO we should return out own set wrapper, so we can avoid the extra object creation if it
- * isn't necessary.
- * <p>
- * @see java.util.Map#entrySet()
- */
@Override
- public Set<Map.Entry<K, V>> 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>>();
-
- 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
- {
- lock.unlock();
- }
+ public boolean shouldRemove() {
+ return maxObjects > 0 && this.size() > maxObjects;
}
- /**
- * @return map.keySet();
- */
- @Override
- public Set<K> keySet()
- {
- // TODO fix this, it needs to return the keys inside the wrappers.
- return map.keySet();
- }
-
- /**
- * @return the max objects size.
- */
- public int getMaxObjects()
- {
- return maxObjects;
- }
+ public Object getMaxCounter() {
+ return maxObjects;
+ }
}
Modified: commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/DiskTestObject.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/DiskTestObject.java?rev=1671552&r1=1671551&r2=1671552&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/DiskTestObject.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/DiskTestObject.java Mon Apr 6 15:28:10 2015
@@ -20,6 +20,7 @@ package org.apache.commons.jcs.auxiliary
*/
import java.io.Serializable;
+import java.util.Arrays;
/**
* Resembles a cached image.
@@ -49,4 +50,15 @@ public class DiskTestObject
this.id = id;
this.imageBytes = imageBytes;
}
+
+ public boolean equals(Object other) {
+ if (other instanceof DiskTestObject) {
+ DiskTestObject o = (DiskTestObject)other;
+ if (id != null)
+ return id.equals(o.id) && Arrays.equals(imageBytes, o.imageBytes);
+ else if (id ==null && o.id == null)
+ return Arrays.equals(imageBytes, o.imageBytes);
+ }
+ return false;
+ }
}
Modified: commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/LRUMapJCSUnitTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/LRUMapJCSUnitTest.java?rev=1671552&r1=1671551&r2=1671552&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/LRUMapJCSUnitTest.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/LRUMapJCSUnitTest.java Mon Apr 6 15:28:10 2015
@@ -20,7 +20,9 @@ package org.apache.commons.jcs.auxiliary
*/
import junit.framework.TestCase;
+
import org.apache.commons.jcs.TestLogConfigurationUtil;
+import org.apache.commons.jcs.auxiliary.disk.LRUMapJCS;
import java.io.StringWriter;
@@ -37,7 +39,7 @@ public class LRUMapJCSUnitTest
LRUMapJCS<String, String> map = new LRUMapJCS<String, String>();
// VERIFY
- assertEquals( "Should be unlimted", -1, map.getMaxObjects() );
+ assertEquals( "Should be unlimted", -1, map.getMaxCounter() );
}
/** Verify that we default to unlimited */
@@ -50,7 +52,7 @@ public class LRUMapJCSUnitTest
LRUMapJCS<String, String> map = new LRUMapJCS<String, String>( expected );
// VERIFY
- assertEquals( "Should be expected", expected, map.getMaxObjects() );
+ assertEquals( "Should be expected", expected, map.getMaxCounter() );
}
/** Verify that the log message. */
Modified: commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheKeyStoreUnitTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheKeyStoreUnitTest.java?rev=1671552&r1=1671551&r2=1671552&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheKeyStoreUnitTest.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheKeyStoreUnitTest.java Mon Apr 6 15:28:10 2015
@@ -19,6 +19,8 @@ package org.apache.commons.jcs.auxiliary
* under the License.
*/
+import org.apache.commons.jcs.auxiliary.disk.behavior.IDiskCacheAttributes.DiskLimitType;
+
import junit.framework.TestCase;
/**
@@ -41,16 +43,31 @@ public class BlockDiskCacheKeyStoreUnitT
throws Exception
{
// SETUP
- String regionName = "testPutKeys";
- int maxKeys = 1000;
- int bytesPerBlock = 2000;
+ BlockDiskCacheAttributes attributes = new BlockDiskCacheAttributes();
+ attributes.setCacheName( "testPutKeys" );
+ attributes.setDiskPath( rootDirName );
+ attributes.setMaxKeySize( 1000 );
+ attributes.setBlockSizeBytes( 2000 );
+ innerTestPutKeys(attributes);
+ }
+
+ public void testPutKeysSize()
+ throws Exception
+ {
+ // SETUP
BlockDiskCacheAttributes attributes = new BlockDiskCacheAttributes();
- attributes.setCacheName( regionName );
+ attributes.setCacheName( "testPutKeys" );
attributes.setDiskPath( rootDirName );
- attributes.setMaxKeySize( maxKeys );
- attributes.setBlockSizeBytes( bytesPerBlock );
+ attributes.setMaxKeySize( 100000 );
+ attributes.setBlockSizeBytes( 1024 );
+ attributes.setDiskLimitType(DiskLimitType.SIZE);
+ innerTestPutKeys(attributes);
+ }
+
+
+ private void innerTestPutKeys(BlockDiskCacheAttributes attributes) {
BlockDiskCache<String, String> blockDiskCache = new BlockDiskCache<String, String>( attributes );
BlockDiskKeyStore<String> keyStore = new BlockDiskKeyStore<String>( attributes, blockDiskCache );
@@ -82,16 +99,31 @@ public class BlockDiskCacheKeyStoreUnitT
throws Exception
{
// SETUP
- String regionName = "testSaveLoadKeys";
- int maxKeys = 10000;
- int bytesPerBlock = 2000;
+ BlockDiskCacheAttributes attributes = new BlockDiskCacheAttributes();
+ attributes.setCacheName( "testSaveLoadKeys" );
+ attributes.setDiskPath( rootDirName );
+ attributes.setMaxKeySize( 10000 );
+ attributes.setBlockSizeBytes( 2000 );
+ testSaveLoadKeysInner(attributes);
+ }
+
+ public void testSaveLoadKeysSize()
+ throws Exception
+ {
+ // SETUP
BlockDiskCacheAttributes attributes = new BlockDiskCacheAttributes();
- attributes.setCacheName( regionName );
+ attributes.setCacheName( "testSaveLoadKeys" );
attributes.setDiskPath( rootDirName );
- attributes.setMaxKeySize( maxKeys );
- attributes.setBlockSizeBytes( bytesPerBlock );
+ attributes.setMaxKeySize( 10000 );
+ attributes.setBlockSizeBytes( 2000 );
+
+ testSaveLoadKeysInner(attributes);
+ }
+
+
+ private void testSaveLoadKeysInner(BlockDiskCacheAttributes attributes) {
BlockDiskKeyStore<String> keyStore = new BlockDiskKeyStore<String>( attributes, null );
// DO WORK
@@ -126,4 +158,21 @@ public class BlockDiskCacheKeyStoreUnitT
assertEquals( "Wrong array returned.", i, result.length );
}
}
+
+ public void testObjectLargerThanMaxSize() {
+ BlockDiskCacheAttributes attributes = new BlockDiskCacheAttributes();
+ attributes.setCacheName( "testObjectLargerThanMaxSize" );
+ attributes.setDiskPath( rootDirName );
+ attributes.setMaxKeySize( 1000 );
+ attributes.setBlockSizeBytes( 2000 );
+ attributes.setDiskLimitType(DiskLimitType.SIZE);
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ BlockDiskKeyStore<String> keyStore = new BlockDiskKeyStore<String>( attributes, new BlockDiskCache(attributes));
+
+ keyStore.put("1", new int[1000]);
+ keyStore.put("2", new int[1000]);
+ assertNull(keyStore.get("1"));
+ assertNotNull(keyStore.get("2"));
+ }
}
Modified: commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheUnitTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheUnitTest.java?rev=1671552&r1=1671551&r2=1671552&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheUnitTest.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheUnitTest.java Mon Apr 6 15:28:10 2015
@@ -29,7 +29,7 @@ import java.io.Serializable;
import java.util.Map;
/** Unit tests for the Block Disk Cache */
-public class BlockDiskCacheUnitTest
+public abstract class BlockDiskCacheUnitTest
extends TestCase
{
/**
@@ -37,6 +37,9 @@ public class BlockDiskCacheUnitTest
* <p>
* @throws Exception
*/
+
+ public abstract BlockDiskCacheAttributes getCacheAttributes();
+
public void testPutGetMatching_SmallWait()
throws Exception
{
@@ -44,7 +47,7 @@ public class BlockDiskCacheUnitTest
int items = 200;
String cacheName = "testPutGetMatching_SmallWait";
- BlockDiskCacheAttributes cattr = new BlockDiskCacheAttributes();
+ BlockDiskCacheAttributes cattr = getCacheAttributes();
cattr.setCacheName( cacheName );
cattr.setMaxKeySize( 100 );
cattr.setDiskPath( "target/test-sandbox/BlockDiskCacheUnitTest" );
@@ -77,7 +80,7 @@ public class BlockDiskCacheUnitTest
int items = 200;
String cacheName = "testPutGetMatching_NoWait";
- BlockDiskCacheAttributes cattr = new BlockDiskCacheAttributes();
+ BlockDiskCacheAttributes cattr = getCacheAttributes();
cattr.setCacheName( cacheName );
cattr.setMaxKeySize( 100 );
cattr.setDiskPath( "target/test-sandbox/BlockDiskCacheUnitTest" );
@@ -165,7 +168,7 @@ public class BlockDiskCacheUnitTest
String cacheName = "testPutGet_BigString";
- BlockDiskCacheAttributes cattr = new BlockDiskCacheAttributes();
+ BlockDiskCacheAttributes cattr = getCacheAttributes();
cattr.setCacheName( cacheName );
cattr.setMaxKeySize( 100 );
cattr.setBlockSizeBytes( 200 );
@@ -208,7 +211,7 @@ public class BlockDiskCacheUnitTest
String cacheName = "testUTF8String";
- BlockDiskCacheAttributes cattr = new BlockDiskCacheAttributes();
+ BlockDiskCacheAttributes cattr = getCacheAttributes();
cattr.setCacheName( cacheName );
cattr.setMaxKeySize( 100 );
cattr.setBlockSizeBytes( 200 );
@@ -252,7 +255,7 @@ public class BlockDiskCacheUnitTest
String cacheName = "testUTF8ByteArray";
- BlockDiskCacheAttributes cattr = new BlockDiskCacheAttributes();
+ BlockDiskCacheAttributes cattr = getCacheAttributes();
cattr.setCacheName( cacheName );
cattr.setMaxKeySize( 100 );
cattr.setBlockSizeBytes( 200 );
@@ -301,7 +304,7 @@ public class BlockDiskCacheUnitTest
String cacheName = "testUTF8StringAndBytes";
- BlockDiskCacheAttributes cattr = new BlockDiskCacheAttributes();
+ BlockDiskCacheAttributes cattr = getCacheAttributes();
cattr.setCacheName( cacheName );
cattr.setMaxKeySize( 100 );
cattr.setBlockSizeBytes( 500 );
Added: commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheUnitTestCount.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheUnitTestCount.java?rev=1671552&view=auto
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheUnitTestCount.java (added)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheUnitTestCount.java Mon Apr 6 15:28:10 2015
@@ -0,0 +1,14 @@
+package org.apache.commons.jcs.auxiliary.disk.block;
+
+import org.apache.commons.jcs.auxiliary.disk.behavior.IDiskCacheAttributes.DiskLimitType;
+
+public class BlockDiskCacheUnitTestCount extends BlockDiskCacheUnitTest {
+
+ @Override
+ public BlockDiskCacheAttributes getCacheAttributes() {
+ BlockDiskCacheAttributes ret = new BlockDiskCacheAttributes();
+ ret.setDiskLimitType(DiskLimitType.COUNT);
+ return ret;
+ }
+
+}
Propchange: commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheUnitTestCount.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheUnitTestSize.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheUnitTestSize.java?rev=1671552&view=auto
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheUnitTestSize.java (added)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheUnitTestSize.java Mon Apr 6 15:28:10 2015
@@ -0,0 +1,14 @@
+package org.apache.commons.jcs.auxiliary.disk.block;
+
+import org.apache.commons.jcs.auxiliary.disk.behavior.IDiskCacheAttributes.DiskLimitType;
+
+public class BlockDiskCacheUnitTestSize extends BlockDiskCacheUnitTest {
+
+ @Override
+ public BlockDiskCacheAttributes getCacheAttributes() {
+ BlockDiskCacheAttributes ret = new BlockDiskCacheAttributes();
+ ret.setDiskLimitType(DiskLimitType.SIZE);
+ return ret;
+ }
+
+}
Propchange: commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheUnitTestSize.java
------------------------------------------------------------------------------
svn:mime-type = text/plain