[prev in list] [next in list] [prev in thread] [next in thread] 

List:       turbine-jcs-dev
Subject:    svn commit: r786172 - in /jakarta/jcs/trunk/src:
From:       asmuts () apache ! org
Date:       2009-06-18 17:16:56
Message-ID: 20090618171656.AB52723888CE () eris ! apache ! org
[Download RAW message or body]

Author: asmuts
Date: Thu Jun 18 17:16:55 2009
New Revision: 786172

URL: http://svn.apache.org/viewvc?rev=786172&view=rev
Log:
Added a FileDiskCache based on the sketch provided in \
https://issues.apache.org/jira/browse/JCS-58

Added:
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/file/
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/file/FileDiskCache.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/file/FileDiskCacheAttributes.java
  jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/file/FileDiskCacheFactory.java
  jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/file/FileDiskCacheManager.java
  jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/file/
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/file/FileDiskCacheFactoryUnitTest.java
  jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/file/FileDiskCacheUnitTest.java
 Modified:
    jakarta/jcs/trunk/src/test-conf/log4j.properties

Added: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/file/FileDiskCache.java
                
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/file/FileDiskCache.java?rev=786172&view=auto
 ==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/file/FileDiskCache.java \
                (added)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/file/FileDiskCache.java \
Thu Jun 18 17:16:55 2009 @@ -0,0 +1,546 @@
+package org.apache.jcs.auxiliary.disk.file;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jcs.auxiliary.AuxiliaryCacheAttributes;
+import org.apache.jcs.auxiliary.disk.AbstractDiskCache;
+import org.apache.jcs.engine.behavior.ICacheElement;
+import org.apache.jcs.engine.behavior.IElementSerializer;
+import org.apache.jcs.engine.logging.behavior.ICacheEvent;
+import org.apache.jcs.engine.logging.behavior.ICacheEventLogger;
+import org.apache.jcs.utils.timing.SleepUtil;
+
+/**
+ * This disk cache writes each item to a separate file. This is for regions with \
very few items, + * perhaps big ones.
+ * <p>
+ * This is a fairly simple implementation. All the disk writing is handled right \
here. It's not + * clear that anything more complicated is needed.
+ */
+public class FileDiskCache
+    extends AbstractDiskCache
+{
+    /** Don't change */
+    private static final long serialVersionUID = 1L;
+
+    /** The logger. */
+    private static final Log log = LogFactory.getLog( FileDiskCache.class );
+
+    /** The name to prefix all log messages with. */
+    private final String logCacheName;
+
+    /** The config values. */
+    private FileDiskCacheAttributes diskFileCacheAttributes;
+
+    /** The directory where the files are stored */
+    private File directory;
+
+    /**
+     * Constructor for the DiskCache object.
+     * <p>
+     * @param cacheAttributes
+     */
+    public FileDiskCache( FileDiskCacheAttributes cacheAttributes )
+    {
+        this( cacheAttributes, null );
+    }
+
+    /**
+     * Constructor for the DiskCache object. Will be marked alive if the directory \
cannot be +     * created.
+     * <p>
+     * @param cattr
+     * @param elementSerializer used if supplied, the super's super will not set a \
null +     */
+    public FileDiskCache( FileDiskCacheAttributes cattr, IElementSerializer \
elementSerializer ) +    {
+        super( cattr );
+        setElementSerializer( elementSerializer );
+        this.diskFileCacheAttributes = cattr;
+        this.logCacheName = "Region [" + getCacheName() + "] ";
+        alive = initializeFileSystem( cattr );;
+    }
+
+    /**
+     * Tries to create the root directory if it does not already exist.
+     * <p>
+     * @param cattr
+     * @return does the directory exist.
+     */
+    private boolean initializeFileSystem( FileDiskCacheAttributes cattr )
+    {
+        // TODO, we might need to make this configurable
+        String rootDirName = cattr.getDiskPath() + "/" + cattr.getCacheName();
+        this.setDirectory( new File( rootDirName ) );
+        boolean createdDirectories = getDirectory().mkdirs();
+        if ( log.isInfoEnabled() )
+        {
+            log.info( logCacheName + "Cache file root directory: " + rootDirName );
+            log.info( logCacheName + "Created root directory: " + createdDirectories \
); +        }
+
+        // TODO consider throwing.
+        boolean exists = getDirectory().exists();
+        if ( !exists )
+        {
+            log.error( "Could not initialize File Disk Cache.  The root directory \
does not exist." ); +        }
+        return exists;
+    }
+
+    /**
+     * Creates the file for a key. Filenames and keys can be passed into this \
method. It must be +     * idempotent.
+     * <p>
+     * Protected for testing.
+     * <p>
+     * @param key
+     * @return the file for the key
+     */
+    protected File file( Serializable key )
+    {
+        StringBuffer fileNameBuffer = new StringBuffer();
+
+        // add key as filename in a file system safe way
+        String keys = key.toString();
+        int l = keys.length();
+        for ( int i = 0; i < l; i++ )
+        {
+            char c = keys.charAt( i );
+            if ( !Character.isLetterOrDigit( c ) )
+            {
+                c = '_';
+            }
+            fileNameBuffer.append( c );
+        }
+        String fileName = fileNameBuffer.toString();
+
+        if ( log.isDebugEnabled() )
+        {
+            log.debug( logCacheName + "Creating file for name: [" + fileName + "] \
based on key: [" + key + "]" ); +        }
+
+        return new File( getDirectory().getAbsolutePath(), fileName );
+    }
+
+    /**
+     * @param groupName
+     * @return Set
+     */
+    public Set getGroupKeys( String groupName )
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @return dir.list().length
+     */
+    public int getSize()
+    {
+        if ( getDirectory().exists() )
+        {
+            return getDirectory().list().length;
+        }
+        return 0;
+    }
+
+    /**
+     * @return AuxiliaryCacheAttributes
+     */
+    public AuxiliaryCacheAttributes getAuxiliaryCacheAttributes()
+    {
+        return diskFileCacheAttributes;
+    }
+
+    /**
+     * @return String the path to the directory
+     */
+    protected String getDiskLocation()
+    {
+        return getDirectory().getAbsolutePath();
+    }
+
+    /**
+     * Sets alive to false.
+     * <p>
+     * @throws IOException
+     */
+    protected synchronized void processDispose()
+        throws IOException
+    {
+        ICacheEvent cacheEvent = createICacheEvent( cacheName, "none", \
ICacheEventLogger.DISPOSE_EVENT ); +        try
+        {
+            if ( !alive )
+            {
+                log.error( logCacheName + "Not alive and dispose was called, \
directgory: " + getDirectory() ); +                return;
+            }
+
+            // Prevents any interaction with the cache while we're shutting down.
+            alive = false;
+
+            // TODO consider giving up the handle on the directory.
+            if ( log.isInfoEnabled() )
+            {
+                log.info( logCacheName + "Shutdown complete." );
+            }
+        }
+        finally
+        {
+            logICacheEvent( cacheEvent );
+        }
+    }
+
+    /**
+     * Looks for a file matching the key. If it exists, reads the file.
+     * <p>
+     * @param key
+     * @return ICacheElement
+     * @throws IOException
+     */
+    protected ICacheElement processGet( Serializable key )
+        throws IOException
+    {
+        File file = file( key );
+
+        if ( !file.exists() )
+        {
+            if ( log.isDebugEnabled() )
+            {
+                log.debug( "File does not exist.  Returning null from Get." + file \
); +            }
+            return null;
+        }
+
+        ICacheElement element = null;
+
+        FileInputStream fis = null;
+        try
+        {
+            fis = new FileInputStream( file );
+
+            long length = file.length();
+            // Create the byte array to hold the data
+            byte[] bytes = new byte[(int) length];
+
+            int offset = 0;
+            int numRead = 0;
+            while ( offset < bytes.length && ( numRead = fis.read( bytes, offset, \
bytes.length - offset ) ) >= 0 ) +            {
+                offset += numRead;
+            }
+
+            // Ensure all the bytes have been read in
+            if ( offset < bytes.length )
+            {
+                throw new IOException( "Could not completely read file " + \
file.getName() ); +            }
+
+            element = (ICacheElement) getElementSerializer().deSerialize( bytes );
+
+            // test that the retrieved object has equal key
+            if ( element != null && !key.equals( element.getKey() ) )
+            {
+                if ( log.isInfoEnabled() )
+                {
+                    log.info( logCacheName + "key: [" + key + "] point to cached \
object with key: [" + element.getKey() +                        + "]" );
+                }
+                element = null;
+            }
+        }
+        catch ( IOException e )
+        {
+            log.error( logCacheName + "Failure getting element, key: [" + key + "]", \
e ); +        }
+        catch ( ClassNotFoundException e )
+        {
+            log.error( logCacheName + "Failure getting element, key: [" + key + "]", \
e ); +        }
+        finally
+        {
+            silentClose( fis );
+        }
+
+        // If this is true and we have a max file size, the Least Recently Used file \
will be removed. +        if ( element != null && \
diskFileCacheAttributes.isTouchOnGet() ) +        {
+            touchWithRetry( file );
+        }
+        return element;
+    }
+
+    /**
+     * @param pattern
+     * @return Map
+     * @throws IOException
+     */
+    protected Map processGetMatching( String pattern )
+        throws IOException
+    {
+        // TODO get a list of file and return those with matching keys.
+        // the problem will be to handle the underscores.
+        return null;
+    }
+
+    /**
+     * Removes the file.
+     * <p>
+     * @param key
+     * @return true if the item was removed
+     * @throws IOException
+     */
+    protected boolean processRemove( Serializable key )
+        throws IOException
+    {
+        File file = file( key );
+        if ( log.isDebugEnabled() )
+        {
+            log.debug( logCacheName + "Removing file " + file );
+        }
+        return deleteWithRetry( file );
+    }
+
+    /**
+     * Remove all the files in the directory.
+     * <p>
+     * Assumes that this is the only region in the directory. We could add a region \
prefix to the +     * files and only delete those, but the region should create a \
directory. +     * <p>
+     * @throws IOException
+     */
+    protected void processRemoveAll()
+        throws IOException
+    {
+        String[] fileNames = getDirectory().list();
+        for ( int i = 0; i < fileNames.length; i++ )
+        {
+            processRemove( fileNames[i] );
+        }
+    }
+
+    /**
+     * We create a temp file with the new contents, remove the old if it exists, and \
then rename the +     * temp.
+     * <p>
+     * @param element
+     * @throws IOException
+     */
+    protected void processUpdate( ICacheElement element )
+        throws IOException
+    {
+        removeIfLimitIsSetAndReached();
+
+        File file = file( element.getKey() );
+
+        File tmp = null;
+        OutputStream os = null;
+        try
+        {
+            byte[] bytes = getElementSerializer().serialize( element );
+
+            tmp = File.createTempFile( "JCS_DiskFileCache", null, getDirectory() );
+
+            FileOutputStream fos = new FileOutputStream( tmp );
+            os = new BufferedOutputStream( fos );
+
+            if ( bytes != null )
+            {
+                if ( log.isDebugEnabled() )
+                {
+                    log.debug( logCacheName + "Wrote " + bytes.length + " bytes to \
file " + tmp ); +                }
+                os.write( bytes );
+                os.close();
+            }
+            deleteWithRetry( file );
+            tmp.renameTo( file );
+            if ( log.isDebugEnabled() )
+            {
+                log.debug( logCacheName + "Renamed to: " + file );
+            }
+        }
+        catch ( IOException e )
+        {
+            log.error( logCacheName + "Failure updating element, key: [" + \
element.getKey() + "]", e ); +        }
+        finally
+        {
+            silentClose( os );
+            if ( ( tmp != null ) && tmp.exists() )
+            {
+                deleteWithRetry( tmp );
+            }
+        }
+    }
+
+    /**
+     * If a limit has been set and we have reached it, remove the least recently \
modified file. +     * <p>
+     * We will probably need to touch the files. If we touch, the LRM file will be \
based on age +     * (i.e. FIFO). If we touch, it will be based on access time (i.e. \
LRU). +     */
+    private void removeIfLimitIsSetAndReached()
+    {
+        if ( diskFileCacheAttributes.getMaxNumberOfFiles() > 0 )
+        {
+            // TODO we might want to synchronize this block.
+            if ( getSize() >= diskFileCacheAttributes.getMaxNumberOfFiles() )
+            {
+                if ( log.isDebugEnabled() )
+                {
+                    log.debug( logCacheName + "Max reached, removing least recently \
modifed" ); +                }
+
+                long oldestLastModified = System.currentTimeMillis();
+                File theLeastRecentlyModified = null;
+                String[] fileNames = getDirectory().list();
+                for ( int i = 0; i < fileNames.length; i++ )
+                {
+                    File file = file( fileNames[i] );
+                    long lastModified = file.lastModified();
+                    if ( lastModified < oldestLastModified )
+                    {
+                        oldestLastModified = lastModified;
+                        theLeastRecentlyModified = file;
+                    }
+                }
+                if ( theLeastRecentlyModified != null )
+                {
+                    if ( log.isDebugEnabled() )
+                    {
+                        log.debug( logCacheName + "Least recently modifed: " + \
theLeastRecentlyModified ); +                    }
+                    deleteWithRetry( theLeastRecentlyModified );
+                }
+            }
+        }
+    }
+
+    /**
+     * Tries to delete a file. If it fails, it tries several more times, pausing a \
few ms. each +     * time.
+     * <p>
+     * @param file
+     * @return true if the file does not exist or if it was removed
+     */
+    private boolean deleteWithRetry( File file )
+    {
+        boolean success = file.delete();
+
+        if ( file.exists() )
+        {
+            int maxRetries = diskFileCacheAttributes.getMaxRetriesOnDelete();
+            for ( int i = 0; i < maxRetries && !success; i++ )
+            {
+                SleepUtil.sleepAtLeast( 5 );
+                success = file.delete();
+            }
+        }
+        else
+        {
+            success = true;
+        }
+        if ( log.isDebugEnabled() )
+        {
+            log.debug( logCacheName + "deleteWithRetry.  success= " + success + " \
file: " + file ); +        }
+        return success;
+    }
+    
+    /**
+     * Tries to set the last access time to now.
+     * <p>
+     * @param file to touch
+     * @return was it successful
+     */
+    private boolean touchWithRetry( File file )
+    {
+        boolean success = file.setLastModified( System.currentTimeMillis() );
+        if ( !success )
+        {
+            int maxRetries = diskFileCacheAttributes.getMaxRetriesOnTouch();
+            if ( file.exists() )
+            {
+                for ( int i = 0; i < maxRetries && !success; i++ )
+                {
+                    SleepUtil.sleepAtLeast( 5 );
+                    success = file.delete();
+                }
+            }
+        }
+        if ( log.isDebugEnabled() )
+        {
+            log.debug( logCacheName + "Last modified, success: " + success );
+        }
+        return success;
+    }
+
+    /**
+     * Closes a stream and swallows errors.
+     * <p>
+     * @param s the stream
+     */
+    private void silentClose( InputStream s )
+    {
+        if ( s != null )
+        {
+            try
+            {
+                s.close();
+            }
+            catch ( IOException e )
+            {
+                log.error( logCacheName + "Failure closing stream", e );
+            }
+        }
+    }
+
+    /**
+     * Closes a stream and swallows errors.
+     * <p>
+     * @param s the stream
+     */
+    private void silentClose( OutputStream s )
+    {
+        if ( s != null )
+        {
+            try
+            {
+                s.close();
+            }
+            catch ( IOException e )
+            {
+                log.error( logCacheName + "Failure closing stream", e );
+            }
+        }
+    }
+
+    /**
+     * @param directory the directory to set
+     */
+    protected void setDirectory( File directory )
+    {
+        this.directory = directory;
+    }
+
+    /**
+     * @return the directory
+     */
+    protected File getDirectory()
+    {
+        return directory;
+    }
+}

Added: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/file/FileDiskCacheAttributes.java
                
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/file/FileDiskCacheAttributes.java?rev=786172&view=auto
 ==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/file/FileDiskCacheAttributes.java \
                (added)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/file/FileDiskCacheAttributes.java \
Thu Jun 18 17:16:55 2009 @@ -0,0 +1,139 @@
+package org.apache.jcs.auxiliary.disk.file;
+
+import org.apache.jcs.auxiliary.AuxiliaryCacheAttributes;
+import org.apache.jcs.auxiliary.disk.AbstractDiskCacheAttributes;
+
+/**
+ * Configuration values for the file disk cache.
+ */
+public class FileDiskCacheAttributes
+    extends AbstractDiskCacheAttributes
+{
+    /** Don't change. */
+    private static final long serialVersionUID = -7371586172678836062L;
+
+    /** Default file count limit: -1 means no limit */
+    public static final int DEFAULT_MAX_NUMBER_OF_FILES = -1;
+
+    /** Max number of files */
+    private int maxNumberOfFiles = DEFAULT_MAX_NUMBER_OF_FILES;
+
+    /** Default limit on the number of times we will retry a delete. */
+    public static final int DEFAULT_MAX_RETRIES_ON_DELETE = 10;
+
+    /** Max number of retries on delete */
+    private int maxRetriesOnDelete = DEFAULT_MAX_RETRIES_ON_DELETE;
+
+    /** Default touch rule. */
+    public static final boolean DEFAULT_TOUCH_ON_GET = false;
+
+    /** Default limit on the number of times we will retry a delete. */
+    public static final int DEFAULT_MAX_RETRIES_ON_TOUCH = 10;
+
+    /** Max number of retries on touch  */
+    private int maxRetriesOnTouch = DEFAULT_MAX_RETRIES_ON_TOUCH;
+    
+    /**
+     * Should we touch on get. If so, we will reset the last modified time. If you \
have a max file +     * size set, this will make the removal strategy LRU. If this is \
false, then the oldest will be +     * removed.
+     */
+    private boolean touchOnGet = DEFAULT_TOUCH_ON_GET;
+
+    /**
+     * Returns a copy of the attributes.
+     * <p>
+     * @return AuxiliaryCacheAttributes
+     */
+    public AuxiliaryCacheAttributes copy()
+    {
+        try
+        {
+            return (AuxiliaryCacheAttributes) this.clone();
+        }
+        catch ( Exception e )
+        {
+            // swallow
+        }
+        return this;
+    }
+
+    /**
+     * @param maxNumberOfFiles the maxNumberOfFiles to set
+     */
+    public void setMaxNumberOfFiles( int maxNumberOfFiles )
+    {
+        this.maxNumberOfFiles = maxNumberOfFiles;
+    }
+
+    /**
+     * @return the maxNumberOfFiles
+     */
+    public int getMaxNumberOfFiles()
+    {
+        return maxNumberOfFiles;
+    }
+
+    /**
+     * @param maxRetriesOnDelete the maxRetriesOnDelete to set
+     */
+    public void setMaxRetriesOnDelete( int maxRetriesOnDelete )
+    {
+        this.maxRetriesOnDelete = maxRetriesOnDelete;
+    }
+
+    /**
+     * @return the maxRetriesOnDelete
+     */
+    public int getMaxRetriesOnDelete()
+    {
+        return maxRetriesOnDelete;
+    }
+
+    /**
+     * @param touchOnGet the touchOnGet to set
+     */
+    public void setTouchOnGet( boolean touchOnGet )
+    {
+        this.touchOnGet = touchOnGet;
+    }
+
+    /**
+     * @return the touchOnGet
+     */
+    public boolean isTouchOnGet()
+    {
+        return touchOnGet;
+    }
+
+    /**
+     * @param maxRetriesOnTouch the maxRetriesOnTouch to set
+     */
+    public void setMaxRetriesOnTouch( int maxRetriesOnTouch )
+    {
+        this.maxRetriesOnTouch = maxRetriesOnTouch;
+    }
+
+    /**
+     * @return the maxRetriesOnTouch
+     */
+    public int getMaxRetriesOnTouch()
+    {
+        return maxRetriesOnTouch;
+    }
+
+    /**
+     * Write out the values for debugging purposes.
+     * <p>
+     * @return String
+     */
+    public String toString()
+    {
+        StringBuffer str = new StringBuffer();
+        str.append( "DiskFileCacheAttributes " );
+        str.append( "\n diskPath = " + diskPath );
+        str.append( "\n maxNumberOfFiles   = " + getMaxNumberOfFiles() );
+        str.append( "\n maxRetriesOnDelete  = " + getMaxRetriesOnDelete() );
+        return str.toString();
+    }
+}

Added: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/file/FileDiskCacheFactory.java
                
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/file/FileDiskCacheFactory.java?rev=786172&view=auto
 ==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/file/FileDiskCacheFactory.java \
                (added)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/file/FileDiskCacheFactory.java \
Thu Jun 18 17:16:55 2009 @@ -0,0 +1,77 @@
+package org.apache.jcs.auxiliary.disk.file;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jcs.auxiliary.AuxiliaryCache;
+import org.apache.jcs.auxiliary.AuxiliaryCacheAttributes;
+import org.apache.jcs.auxiliary.AuxiliaryCacheFactory;
+import org.apache.jcs.engine.behavior.ICompositeCacheManager;
+import org.apache.jcs.engine.behavior.IElementSerializer;
+import org.apache.jcs.engine.logging.behavior.ICacheEventLogger;
+
+/** Create Disk File Caches */
+public class FileDiskCacheFactory
+    implements AuxiliaryCacheFactory
+{
+    /** The logger. */
+    private final static Log log = LogFactory.getLog( FileDiskCacheFactory.class );
+
+    /** The auxiliary name. */
+    private String name;
+
+    /** The manager used by this factory instance */
+    private FileDiskCacheManager diskFileCacheManager;
+    
+    /**
+     * Creates a manager if we don't have one, and then uses the manager to create \
the cache. The +     * same factory will be called multiple times by the composite \
cache to create a cache for each +     * region.
+     * <p>
+     * @param attr config
+     * @param cacheMgr the manager to use if needed
+     * @param cacheEventLogger the event logger
+     * @param elementSerializer the serializer
+     * @return AuxiliaryCache
+     */
+    public AuxiliaryCache createCache( AuxiliaryCacheAttributes attr, \
ICompositeCacheManager cacheMgr, +                                       \
ICacheEventLogger cacheEventLogger, IElementSerializer elementSerializer ) +    {
+        FileDiskCacheAttributes idfca = (FileDiskCacheAttributes) attr;
+        synchronized( this )
+        {
+            if ( diskFileCacheManager == null )
+            {
+                if ( log.isDebugEnabled() )
+                {
+                    log.debug( "Creating DiskFileCacheManager" );
+                }
+                diskFileCacheManager = new FileDiskCacheManager( idfca, \
cacheEventLogger, elementSerializer ); +            }
+        }
+        if ( log.isDebugEnabled() )
+        {
+            log.debug( "Creating DiskFileCache for attributes = " + idfca );
+        }
+        return diskFileCacheManager.getCache( idfca );
+    }
+
+    /**
+     * Gets the name attribute of the DiskCacheFactory object
+     * <p>
+     * @return The name value
+     */
+    public String getName()
+    {
+        return this.name;
+    }
+
+    /**
+     * Sets the name attribute of the DiskCacheFactory object
+     * <p>
+     * @param name The new name value
+     */
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+}

Added: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/file/FileDiskCacheManager.java
                
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/file/FileDiskCacheManager.java?rev=786172&view=auto
 ==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/file/FileDiskCacheManager.java \
                (added)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/file/FileDiskCacheManager.java \
Thu Jun 18 17:16:55 2009 @@ -0,0 +1,105 @@
+package org.apache.jcs.auxiliary.disk.file;
+
+import java.util.Hashtable;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jcs.auxiliary.AuxiliaryCache;
+import org.apache.jcs.auxiliary.disk.AbstractDiskCacheManager;
+import org.apache.jcs.engine.behavior.IElementSerializer;
+import org.apache.jcs.engine.logging.behavior.ICacheEventLogger;
+
+/**
+ * This is a non singleton. It creates caches on a per region basis.
+ */
+public class FileDiskCacheManager
+    extends AbstractDiskCacheManager
+{
+    /** Don't change */
+    private static final long serialVersionUID = -4153287154512264626L;
+
+    /** The logger */
+    private final static Log log = LogFactory.getLog( FileDiskCacheManager.class );
+
+    /** Each region has an entry here. */
+    private Hashtable caches = new Hashtable();
+
+    /** User configurable attributes */
+    private FileDiskCacheAttributes defaultCacheAttributes;
+
+    /**
+     * Constructor for the DiskFileCacheManager object
+     * <p>
+     * @param defaultCacheAttributes Default attributes for caches managed by the \
instance. +     * @param cacheEventLogger
+     * @param elementSerializer
+     */
+    protected FileDiskCacheManager( FileDiskCacheAttributes defaultCacheAttributes, \
ICacheEventLogger cacheEventLogger, +                                  \
IElementSerializer elementSerializer ) +    {
+        this.defaultCacheAttributes = defaultCacheAttributes;
+        setElementSerializer( elementSerializer );
+        setCacheEventLogger( cacheEventLogger );
+    }
+
+    /**
+     * Gets an DiskFileCache for the supplied name using the default attributes.
+     * <p>
+     * @param cacheName Name that will be used when creating attributes.
+     * @return A cache.
+     */
+    public AuxiliaryCache getCache( String cacheName )
+    {
+        FileDiskCacheAttributes cacheAttributes = (FileDiskCacheAttributes) \
defaultCacheAttributes.copy(); +
+        cacheAttributes.setCacheName( cacheName );
+
+        return getCache( cacheAttributes );
+    }
+
+    /**
+     * Get an DiskFileCache for the supplied attributes. Will provide an existing \
cache for the name +     * attribute if one has been created, or will create a new \
cache. +     * <p>
+     * @param cacheAttributes Attributes the cache should have.
+     * @return A cache, either from the existing set or newly created.
+     */
+    public AuxiliaryCache getCache( FileDiskCacheAttributes cacheAttributes )
+    {
+        AuxiliaryCache cache = null;
+
+        String cacheName = cacheAttributes.getCacheName();
+
+        log.debug( "Getting cache named: " + cacheName );
+
+        synchronized ( caches )
+        {
+            // Try to load the cache from the set that have already been
+            // created. This only looks at the name attribute.
+
+            cache = (AuxiliaryCache) caches.get( cacheName );
+
+            // If it was not found, create a new one using the supplied
+            // attributes
+
+            if ( cache == null )
+            {
+                cache = new FileDiskCache( cacheAttributes, getElementSerializer() \
); +                cache.setCacheEventLogger( getCacheEventLogger() );
+                caches.put( cacheName, cache );
+            }
+        }
+
+        return cache;
+    }
+
+    /**
+     * Gets the cacheType attribute of the DiskCacheManager object
+     * <p>
+     * @return The cacheType value
+     */
+    public int getCacheType()
+    {
+        return DISK_CACHE;
+    }
+}

Modified: jakarta/jcs/trunk/src/test-conf/log4j.properties
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test-conf/log4j.properties?rev=786172&r1=786171&r2=786172&view=diff
 ==============================================================================
--- jakarta/jcs/trunk/src/test-conf/log4j.properties (original)
+++ jakarta/jcs/trunk/src/test-conf/log4j.properties Thu Jun 18 17:16:55 2009
@@ -22,7 +22,8 @@
 log4j.category.org.apache.jcs.engine.CacheEventQueueFactory=INFO
 log4j.category.org.apache.jcs.auxiliary.disk.jdbc=INFO
 log4j.category.org.apache.jcs.auxiliary.disk=INFO
-log4j.category.org.apache.jcs.auxiliary.disk.block=DEBUG
+log4j.category.org.apache.jcs.auxiliary.disk.block=INFO
+log4j.category.org.apache.jcs.auxiliary.disk.file=INFO
 log4j.category.org.apache.jcs.auxiliary.remote=INFO
 log4j.category.org.apache.jcs.auxiliary.lateral=INFO
 log4j.category.org.apache.jcs.utils.struct=INFO

Added: jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/file/FileDiskCacheFactoryUnitTest.java
                
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/file/FileDiskCacheFactoryUnitTest.java?rev=786172&view=auto
 ==============================================================================
--- jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/file/FileDiskCacheFactoryUnitTest.java \
                (added)
+++ jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/file/FileDiskCacheFactoryUnitTest.java \
Thu Jun 18 17:16:55 2009 @@ -0,0 +1,39 @@
+package org.apache.jcs.auxiliary.disk.file;
+
+import junit.framework.TestCase;
+
+import org.apache.jcs.auxiliary.MockCacheEventLogger;
+import org.apache.jcs.engine.behavior.ICompositeCacheManager;
+import org.apache.jcs.engine.behavior.IElementSerializer;
+import org.apache.jcs.engine.control.MockCompositeCacheManager;
+import org.apache.jcs.engine.control.MockElementSerializer;
+import org.apache.jcs.engine.logging.behavior.ICacheEventLogger;
+
+/** Verify that the factory works */
+public class FileDiskCacheFactoryUnitTest
+    extends TestCase
+{
+    /** Verify that we can get a cache from the manager via the factory */
+    public void testCreateCache_Normal()
+    {
+        // SETUP
+        String cacheName = "testCreateCache_Normal";
+        FileDiskCacheAttributes cattr = new FileDiskCacheAttributes();
+        cattr.setCacheName( cacheName );
+        cattr.setDiskPath( "target/test-sandbox/FileDiskCacheFactoryUnitTest" );
+
+        ICompositeCacheManager cacheMgr = new MockCompositeCacheManager();
+        ICacheEventLogger cacheEventLogger = new MockCacheEventLogger();
+        IElementSerializer elementSerializer = new MockElementSerializer();
+
+        FileDiskCacheFactory factory = new FileDiskCacheFactory();
+
+        // DO WORK
+        FileDiskCache result = (FileDiskCache) factory.createCache( cattr, cacheMgr, \
cacheEventLogger, +                                                                   \
elementSerializer ); +
+        // VERIFY
+        assertNotNull( "Should have a disk cache", result );
+        assertEquals( "Should have a disk cache with a serializer", \
elementSerializer, result.getElementSerializer() ); +    }
+}

Added: jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/file/FileDiskCacheUnitTest.java
                
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/file/FileDiskCacheUnitTest.java?rev=786172&view=auto
 ==============================================================================
--- jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/file/FileDiskCacheUnitTest.java \
                (added)
+++ jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/file/FileDiskCacheUnitTest.java \
Thu Jun 18 17:16:55 2009 @@ -0,0 +1,522 @@
+package org.apache.jcs.auxiliary.disk.file;
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+import org.apache.jcs.engine.CacheConstants;
+import org.apache.jcs.engine.CacheElement;
+import org.apache.jcs.engine.behavior.ICacheElement;
+import org.apache.jcs.utils.timing.SleepUtil;
+
+/** Unit tests for the disk file cache. */
+public class FileDiskCacheUnitTest
+    extends TestCase
+{
+    /**
+     * Verify initialization.
+     * <p>
+     * @throws Exception
+     */
+    public void testInitialization_Normal()
+        throws Exception
+    {
+        // SETUP
+        String cacheName = "testInitialization_Normal";
+        FileDiskCacheAttributes cattr = new FileDiskCacheAttributes();
+        cattr.setCacheName( cacheName );
+        cattr.setDiskPath( "target/test-sandbox/DiskFileCacheUnitTest" );
+
+        // DO WORK
+        FileDiskCache diskCache = new FileDiskCache( cattr );
+        File directory = diskCache.getDirectory();
+
+        // VERIFY
+        assertNotNull( "Should have a directory", directory );
+        assertTrue( "Should have an existing directory", directory.exists() );
+        assertTrue( "Directory should include the cache name. " + \
directory.getAbsolutePath(), directory +            .getAbsolutePath().indexOf( \
cacheName ) != -1 ); +        assertTrue( "Directory should include the disk path. " \
+ directory.getAbsolutePath(), directory +            .getAbsolutePath().indexOf( \
"DiskFileCacheUnitTest" ) != -1 ); +        assertTrue( "Should be alive", \
diskCache.getStatus() == CacheConstants.STATUS_ALIVE ); +    }
+
+    /**
+     * Verify dispose.
+     * <p>
+     * @throws Exception
+     */
+    public void testDispose_Normal()
+        throws Exception
+    {
+        // SETUP
+        String cacheName = "testDispose_Normal";
+        FileDiskCacheAttributes cattr = new FileDiskCacheAttributes();
+        cattr.setCacheName( cacheName );
+        cattr.setDiskPath( "target/test-sandbox/DiskFileCacheUnitTest" );
+        FileDiskCache diskCache = new FileDiskCache( cattr );
+
+        // DO WORK
+        diskCache.dispose();
+
+        // VERIFY
+        assertTrue( "Should not be alive", diskCache.getStatus() == \
CacheConstants.STATUS_DISPOSED ); +    }
+
+    /**
+     * Verify initialization.
+     * <p>
+     * @throws Exception
+     */
+    public void testInitialization_JunkFileName()
+        throws Exception
+    {
+        // SETUP
+        String cacheName = "testInitialization_JunkFileName";
+        FileDiskCacheAttributes cattr = new FileDiskCacheAttributes();
+        cattr.setCacheName( cacheName );
+        cattr.setDiskPath( "target/test-sandbox/DiskFileCacheUnitTest%$&*#@" );
+
+        // DO WORK
+        FileDiskCache diskCache = new FileDiskCache( cattr );
+        File directory = diskCache.getDirectory();
+
+        // VERIFY
+        assertNotNull( "Should have a directory", directory );
+        assertFalse( "Should have an existing directory", directory.exists() );
+        assertTrue( "Should not be alive", diskCache.getStatus() == \
CacheConstants.STATUS_DISPOSED ); +    }
+
+    /**
+     * Verify getSize.
+     * <p>
+     * @throws Exception
+     */
+    public void testGetSize_Empty()
+        throws Exception
+    {
+        // SETUP
+        String cacheName = "testGetSize_Empty";
+        FileDiskCacheAttributes cattr = new FileDiskCacheAttributes();
+        cattr.setCacheName( cacheName );
+        cattr.setDiskPath( "target/test-sandbox/DiskFileCacheUnitTest" );
+        FileDiskCache diskCache = new FileDiskCache( cattr );
+
+        diskCache.removeAll();
+
+        // DO WORK
+        int result = diskCache.getSize();
+
+        // VERIFY
+        assertEquals( "Should be empty.", 0, result );
+    }
+
+    /**
+     * Verify getSize.
+     * <p>
+     * @throws Exception
+     */
+    public void testGetSize_OneItem()
+        throws Exception
+    {
+        // SETUP
+        String cacheName = "testGetSize_OneItem";
+        FileDiskCacheAttributes cattr = new FileDiskCacheAttributes();
+        cattr.setCacheName( cacheName );
+        cattr.setDiskPath( "target/test-sandbox/DiskFileCacheUnitTest" );
+        FileDiskCache diskCache = new FileDiskCache( cattr );
+
+        diskCache.removeAll();
+        diskCache.update( new CacheElement( cacheName, "key1", "Data" ) );
+        SleepUtil.sleepAtLeast( 100 );
+
+        // DO WORK
+        int result = diskCache.getSize();
+
+        // VERIFY
+        assertEquals( "Should not be empty.", 1, result );
+    }
+
+    /**
+     * Verify remove all.
+     * <p>
+     * @throws Exception
+     */
+    public void testRemoveAll_OneItem()
+        throws Exception
+    {
+        // SETUP
+        String cacheName = "testRemoveAll_OneItem";
+        FileDiskCacheAttributes cattr = new FileDiskCacheAttributes();
+        cattr.setCacheName( cacheName );
+        cattr.setDiskPath( "target/test-sandbox/DiskFileCacheUnitTest" );
+        FileDiskCache diskCache = new FileDiskCache( cattr );
+
+        diskCache.update( new CacheElement( cacheName, "key1", "Data" ) );
+        SleepUtil.sleepAtLeast( 100 );
+
+        // DO WORK
+        diskCache.removeAll();
+        SleepUtil.sleepAtLeast( 100 );
+        int result = diskCache.getSize();
+
+        // VERIFY
+        assertEquals( "Should be empty.", 0, result );
+    }
+
+    /**
+     * Verify get.
+     * <p>
+     * @throws Exception
+     */
+    public void testGet_Empty()
+        throws Exception
+    {
+        // SETUP
+        String cacheName = "testGet_Empty";
+        FileDiskCacheAttributes cattr = new FileDiskCacheAttributes();
+        cattr.setCacheName( cacheName );
+        cattr.setDiskPath( "target/test-sandbox/DiskFileCacheUnitTest" );
+        FileDiskCache diskCache = new FileDiskCache( cattr );
+
+        // DO WORK
+        ICacheElement result = diskCache.get( "key" );
+
+        // VERIFY
+        assertNull( "Should be null.", result );
+    }
+
+    /**
+     * Verify get.
+     * <p>
+     * @throws Exception
+     */
+    public void testGet_Exists()
+        throws Exception
+    {
+        // SETUP
+        String cacheName = "testGet_Empty";
+        FileDiskCacheAttributes cattr = new FileDiskCacheAttributes();
+        cattr.setCacheName( cacheName );
+        cattr.setDiskPath( "target/test-sandbox/DiskFileCacheUnitTest" );
+        FileDiskCache diskCache = new FileDiskCache( cattr );
+
+        diskCache.update( new CacheElement( cacheName, "key1", "Data" ) );
+        SleepUtil.sleepAtLeast( 100 );
+
+        // DO WORK
+        ICacheElement result = diskCache.get( "key1" );
+
+        // VERIFY
+        assertNotNull( "Should NOT be null.", result );
+    }
+
+    /**
+     * Verify RemoveIfLimitIsSetAndReached.
+     * <p>
+     * @throws Exception
+     */
+    public void testRemoveIfLimitIsSetAndReached_NotReached()
+        throws Exception
+    {
+        // SETUP
+        int maxNumberOfFiles = 10;
+        String cacheName = "testRemoveIfLimitIsSetAndReached_NotReached";
+        FileDiskCacheAttributes cattr = new FileDiskCacheAttributes();
+        cattr.setCacheName( cacheName );
+        cattr.setDiskPath( "target/test-sandbox/DiskFileCacheUnitTest" );
+        cattr.setMaxNumberOfFiles( maxNumberOfFiles );
+        FileDiskCache diskCache = new FileDiskCache( cattr );
+
+        for ( int i = 0; i < maxNumberOfFiles; i++ )
+        {
+            diskCache.update( new CacheElement( cacheName, "key" + i, "Data" ) );
+        }
+        SleepUtil.sleepAtLeast( 100 );
+
+        // DO WORK
+        ICacheElement result = diskCache.get( "key0" );
+
+        // VERIFY
+        assertNotNull( "Should NOT be null.", result );
+    }
+
+    /**
+     * Verify RemoveIfLimitIsSetAndReached.
+     * <p>
+     * @throws Exception
+     */
+    public void testRemoveIfLimitIsSetAndReached_Reached()
+        throws Exception
+    {
+        // SETUP
+        int maxNumberOfFiles = 10;
+        String cacheName = "testRemoveIfLimitIsSetAndReached_Reached";
+        FileDiskCacheAttributes cattr = new FileDiskCacheAttributes();
+        cattr.setCacheName( cacheName );
+        cattr.setDiskPath( "target/test-sandbox/DiskFileCacheUnitTest" );
+        cattr.setMaxNumberOfFiles( maxNumberOfFiles );
+        FileDiskCache diskCache = new FileDiskCache( cattr );
+
+        for ( int i = 0; i <= maxNumberOfFiles; i++ )
+        {
+            diskCache.update( new CacheElement( cacheName, "key" + i, "Data" ) );
+        }
+        SleepUtil.sleepAtLeast( 100 );
+
+        // DO WORK
+        ICacheElement result = diskCache.get( "key0" );
+
+        // VERIFY
+        assertNull( "Should be null.", result );
+    }
+
+    /**
+     * Verify RemoveIfLimitIsSetAndReached. Since touch on get is true, the LRU and \
not the oldest +     * shoudl be removed.
+     * <p>
+     * @throws Exception
+     */
+    public void testRemoveIfLimitIsSetAndReached_Reached_TouchTrue()
+        throws Exception
+    {
+        // SETUP
+        int maxNumberOfFiles = 10;
+        String cacheName = "testRemoveIfLimitIsSetAndReached_Reached_TouchTrue";
+        FileDiskCacheAttributes cattr = new FileDiskCacheAttributes();
+        cattr.setCacheName( cacheName );
+        cattr.setDiskPath( "target/test-sandbox/DiskFileCacheUnitTest" );
+        cattr.setMaxNumberOfFiles( maxNumberOfFiles );
+        cattr.setTouchOnGet( true );
+        FileDiskCache diskCache = new FileDiskCache( cattr );
+        diskCache.removeAll();
+
+        for ( int i = 0; i < maxNumberOfFiles; i++ )
+        {
+            diskCache.update( new CacheElement( cacheName, "key" + i, "Data" ) );
+        }
+        SleepUtil.sleepAtLeast( 100 );
+
+        for ( int i = maxNumberOfFiles - 1; i >= 0; i-- )
+        {
+            SleepUtil.sleepAtLeast( 5 );
+            diskCache.get( "key" + i );
+        }
+        SleepUtil.sleepAtLeast( 100 );
+        
+        // This will push it over.  number 9, the youngest, but LRU item should be \
removed +        diskCache.update( new CacheElement( cacheName, "key" + \
maxNumberOfFiles, "Data" ) ); +        SleepUtil.sleepAtLeast( 100 );
+
+        // DO WORK
+        ICacheElement result = diskCache.get( "key9" );
+
+        // VERIFY
+        assertNull( "Should be null.", result );
+    }
+
+    /**
+     * Verify RemoveIfLimitIsSetAndReached. Since touch on get is false, the the \
oldest +     * should be removed.
+     * <p>
+     * @throws Exception
+     */
+    public void testRemoveIfLimitIsSetAndReached_Reached_TouchFalse()
+        throws Exception
+    {
+        // SETUP
+        int maxNumberOfFiles = 10;
+        String cacheName = "testRemoveIfLimitIsSetAndReached_Reached_TouchTrue";
+        FileDiskCacheAttributes cattr = new FileDiskCacheAttributes();
+        cattr.setCacheName( cacheName );
+        cattr.setDiskPath( "target/test-sandbox/DiskFileCacheUnitTest" );
+        cattr.setMaxNumberOfFiles( maxNumberOfFiles );
+        cattr.setTouchOnGet( false );
+        FileDiskCache diskCache = new FileDiskCache( cattr );
+        diskCache.removeAll();
+
+        for ( int i = 0; i < maxNumberOfFiles; i++ )
+        {
+            diskCache.update( new CacheElement( cacheName, "key" + i, "Data" ) );
+        }
+        SleepUtil.sleepAtLeast( 100 );
+
+        for ( int i = maxNumberOfFiles - 1; i >= 0; i-- )
+        {
+            SleepUtil.sleepAtLeast( 5 );
+            diskCache.get( "key" + i );
+        }
+        SleepUtil.sleepAtLeast( 100 );
+        
+        // This will push it over.  number 0, the oldest should be removed
+        diskCache.update( new CacheElement( cacheName, "key" + maxNumberOfFiles, \
"Data" ) ); +        SleepUtil.sleepAtLeast( 100 );
+
+        // DO WORK
+        ICacheElement result = diskCache.get( "key0" );
+
+        // VERIFY
+        assertNull( "Should be null.", result );
+    }
+    /**
+     * Verify file.
+     * <p>
+     * @throws Exception
+     */
+    public void testFile_NoSPecialCharacters()
+        throws Exception
+    {
+        // SETUP
+        String cacheName = "testFile";
+        FileDiskCacheAttributes cattr = new FileDiskCacheAttributes();
+        cattr.setCacheName( cacheName );
+        cattr.setDiskPath( "target/test-sandbox/DiskFileCacheUnitTest" );
+        FileDiskCache diskCache = new FileDiskCache( cattr );
+
+        String key = "simplestring";
+
+        // DO WORK
+        File result = diskCache.file( key );
+
+        // VERIFY
+        assertEquals( "Wrong string.", key, result.getName() );
+    }
+
+    /**
+     * Verify file.
+     * <p>
+     * @throws Exception
+     */
+    public void testFile_Space()
+        throws Exception
+    {
+        // SETUP
+        String cacheName = "testFile";
+        FileDiskCacheAttributes cattr = new FileDiskCacheAttributes();
+        cattr.setCacheName( cacheName );
+        cattr.setDiskPath( "target/test-sandbox/DiskFileCacheUnitTest" );
+        FileDiskCache diskCache = new FileDiskCache( cattr );
+
+        String key = "simple string";
+
+        // DO WORK
+        File result = diskCache.file( key );
+
+        // VERIFY
+        assertEquals( "Wrong string.", "simple_string", result.getName() );
+    }
+
+    /**
+     * Verify file.
+     * <p>
+     * @throws Exception
+     */
+    public void testFile_SpecialCharacter()
+        throws Exception
+    {
+        // SETUP
+        String cacheName = "testFile";
+        FileDiskCacheAttributes cattr = new FileDiskCacheAttributes();
+        cattr.setCacheName( cacheName );
+        cattr.setDiskPath( "target/test-sandbox/DiskFileCacheUnitTest" );
+        FileDiskCache diskCache = new FileDiskCache( cattr );
+
+        String key = "simple%string";
+
+        // DO WORK
+        File result = diskCache.file( key );
+
+        // VERIFY
+        assertEquals( "Wrong string.", "simple_string", result.getName() );
+    }
+
+    /**
+     * Verify idempotence.
+     * <p>
+     * @throws Exception
+     */
+    public void testFile_WithFile()
+        throws Exception
+    {
+        // SETUP
+        String cacheName = "testFile";
+        FileDiskCacheAttributes cattr = new FileDiskCacheAttributes();
+        cattr.setCacheName( cacheName );
+        cattr.setDiskPath( "target/test-sandbox/DiskFileCacheUnitTest" );
+        FileDiskCache diskCache = new FileDiskCache( cattr );
+
+        String key = "simple%string";
+        File firstResult = diskCache.file( key );
+
+        // DO WORK
+        File result = diskCache.file( firstResult.getName() );
+
+        // VERIFY
+        assertEquals( "Wrong string.", "simple_string", result.getName() );
+    }
+
+    /**
+     * Verify remove.
+     * <p>
+     * @throws Exception
+     */
+    public void testRemove_OneItem()
+        throws Exception
+    {
+        // SETUP
+        String cacheName = "testRemove_OneItem";
+        FileDiskCacheAttributes cattr = new FileDiskCacheAttributes();
+        cattr.setCacheName( cacheName );
+        cattr.setDiskPath( "target/test-sandbox/DiskFileCacheUnitTest" );
+        FileDiskCache diskCache = new FileDiskCache( cattr );
+
+        diskCache.update( new CacheElement( cacheName, "key1", "Data" ) );
+        SleepUtil.sleepAtLeast( 100 );
+
+        // DO WORK
+        diskCache.remove( "key1" );
+        SleepUtil.sleepAtLeast( 100 );
+        int result = diskCache.getSize();
+
+        // VERIFY
+        assertEquals( "Should be empty.", 0, result );
+    }
+
+    /**
+     * Verify that the disk file cache can handle a big string.
+     * <p>
+     * @throws Exception
+     */
+    public void testPutGet_BigString()
+        throws Exception
+    {
+        // SETUP
+        String cacheName = "testPutGet_BigString";
+        FileDiskCacheAttributes cattr = new FileDiskCacheAttributes();
+        cattr.setCacheName( cacheName );
+        cattr.setDiskPath( "target/test-sandbox/DiskFileCacheUnitTest" );
+        FileDiskCache diskCache = new FileDiskCache( cattr );
+
+        String string = "This is my big string ABCDEFGH";
+        StringBuffer sb = new StringBuffer();
+        sb.append( string );
+        for ( int i = 0; i < 4; i++ )
+        {
+            sb.append( " " + i + sb.toString() ); // big string
+        }
+        string = sb.toString();
+
+        // DO WORK
+        diskCache.update( new CacheElement( cacheName, "x", string ) );
+        SleepUtil.sleepAtLeast( 300 );
+
+        // VERIFY
+        ICacheElement afterElement = diskCache.get( "x" );
+        assertNotNull( afterElement );
+        System.out.println( "afterElement = " + afterElement );
+        String after = (String) afterElement.getVal();
+
+        assertNotNull( after );
+        assertEquals( "wrong string after retrieval", string, after );
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: jcs-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: jcs-dev-help@jakarta.apache.org


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic