Author: asmuts
Date: Sun Aug 27 19:29:54 2006
New Revision: 437511

URL: http://svn.apache.org/viewvc?rev=437511&view=rev
Log:
Added configurable, periodic key persistence to the block disk cache.

Added rough disk file verification to block disk cache.


Modified:
    
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDisk.java
    
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskCache.java
    
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheAttributes.java
    
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskKeyStore.java
    jakarta/jcs/trunk/src/test-conf/TestBlockDiskCacheHuge.ccf
    
jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/HugeQuantityBlockDiskCacheLoadTest.java

Modified: 
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDisk.java
URL: 
http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDisk.java?rev=437511&r1=437510&r2=437511&view=diff
==============================================================================
--- 
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDisk.java 
(original)
+++ 
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDisk.java 
Sun Aug 27 19:29:54 2006
@@ -64,8 +64,13 @@
      */
     public BlockDisk( File file )
         throws FileNotFoundException
-    {
+    {        
         this( file, DEFAULT_BLOCK_SIZE_BYTES );
+        if ( log.isInfoEnabled() )
+        {
+            log.info( "Used default block size [" + DEFAULT_BLOCK_SIZE_BYTES + 
"]" );
+        }
+        
     }
 
     /**

Modified: 
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskCache.java
URL: 
http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskCache.java?rev=437511&r1=437510&r2=437511&view=diff
==============================================================================
--- 
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskCache.java
 (original)
+++ 
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskCache.java
 Sun Aug 27 19:29:54 2006
@@ -92,10 +92,9 @@
 
         try
         {
-            if ( cacheAttributes.getBlockSizeBytes() > 0 )
+            if ( this.blockDiskCacheAttributes.getBlockSizeBytes() > 0 )
             {
-                this.dataFile = new BlockDisk( new File( rootDirectory, 
fileName + ".data" ), cacheAttributes
-                    .getBlockSizeBytes() );
+                this.dataFile = new BlockDisk( new File( rootDirectory, 
fileName + ".data" ), this.blockDiskCacheAttributes.getBlockSizeBytes() );
             }
             else
             {
@@ -104,7 +103,9 @@
 
             keyStore = new BlockDiskKeyStore( this.blockDiskCacheAttributes, 
this );
 
-            if ( keyStore.size() == 0 )
+            boolean alright = verifyDisk();
+
+            if ( keyStore.size() == 0 || !alright )
             {
                 this.reset();
             }
@@ -113,7 +114,7 @@
             alive = true;
             if ( log.isInfoEnabled() )
             {
-                log.info( logCacheName + "Indexed Disk Cache is alive." );
+                log.info( logCacheName + "Block Disk Cache is alive." );
             }
         }
         catch ( Exception e )
@@ -126,6 +127,43 @@
     }
 
     /**
+     * We need to verify that the file on disk uses the same block size and 
that the file is the
+     * proper size.
+     * <p>
+     * @return true if it looks ok
+     */
+    protected boolean verifyDisk()
+    {
+        boolean alright = false;
+        // simply try to read a few. If it works, then the file is probably ok.
+        // TODO add more.
+        try
+        {
+            int maxToTest = 100;
+            int count = 0;
+            Set keySet = this.keyStore.entrySet();
+            Iterator it = keySet.iterator();
+            while ( it.hasNext() && count < maxToTest )
+            {
+                count++;
+                Map.Entry entry = (Map.Entry) it.next();
+                Object data = this.dataFile.read( (int[]) entry.getValue() );
+                if ( data == null )
+                {
+                    throw new Exception( "Couldn't find data for key [" + 
entry.getKey() + "]" );
+                }
+            }
+            alright = true;
+        }
+        catch ( Exception e )
+        {
+            log.warn( "Problem verifying disk.  Message [" +  e.getMessage() + 
"]" );
+            alright = false;
+        }
+        return alright;
+    }
+
+    /**
      * This requires a full iteration through the keys.
      * <p>
      * (non-Javadoc)
@@ -459,7 +497,6 @@
         storageLock.writeLock().acquire();
         try
         {
-
             // Prevents any interaction with the cache while we're shutting 
down.
             alive = false;
 
@@ -472,7 +509,7 @@
                     log.debug( logCacheName + "Closing files, base filename: " 
+ fileName );
                 }
                 dataFile.close();
-                dataFile = null;
+                // dataFile = null;
 
                 // TOD make a close
                 // keyFile.close();
@@ -527,8 +564,15 @@
             File dataFileTemp = new File( this.rootDirectory, fileName + 
".data" );
             dataFileTemp.delete();
 
-            dataFile = new BlockDisk( new File( this.rootDirectory, fileName + 
".data" ) );
-
+            if ( this.blockDiskCacheAttributes.getBlockSizeBytes() > 0 )
+            {
+                this.dataFile = new BlockDisk( new File( rootDirectory, 
fileName + ".data" ), this.blockDiskCacheAttributes.getBlockSizeBytes() );
+            }
+            else
+            {
+                this.dataFile = new BlockDisk( new File( rootDirectory, 
fileName + ".data" ) );
+            }
+            
             this.keyStore.reset();
         }
         catch ( Exception e )

Modified: 
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheAttributes.java
URL: 
http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheAttributes.java?rev=437511&r1=437510&r2=437511&view=diff
==============================================================================
--- 
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheAttributes.java
 (original)
+++ 
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheAttributes.java
 Sun Aug 27 19:29:54 2006
@@ -19,6 +19,12 @@
     /** -1 means no limit. */
     private int maxKeySize = DEFAULT_MAX_KEY_SIZE;
     
+    private static final long DEFAULT_KEY_PERSISTENCE_INTERVAL_SECONDS = 5 * 
60;
+    
+    /** The keys will be persisted at this interval.  -1 mean never. */
+    private long keyPersistenceIntervalSeconds = 
DEFAULT_KEY_PERSISTENCE_INTERVAL_SECONDS;
+    
+    
     /**
      * The size of the blocks. All blocks are the same size.
      * <p>
@@ -54,6 +60,22 @@
     }
 
     /**
+     * @param keyPersistenceIntervalSeconds The keyPersistenceIntervalSeconds 
to set.
+     */
+    public void setKeyPersistenceIntervalSeconds( long 
keyPersistenceIntervalSeconds )
+    {
+        this.keyPersistenceIntervalSeconds = keyPersistenceIntervalSeconds;
+    }
+
+    /**
+     * @return Returns the keyPersistenceIntervalSeconds.
+     */
+    public long getKeyPersistenceIntervalSeconds()
+    {
+        return keyPersistenceIntervalSeconds;
+    }
+
+    /**
      * Write out the values for debugging purposes.
      * <p>
      * @return String
@@ -66,6 +88,7 @@
         str.append( "\n MaxKeySize [" + this.getMaxKeySize() + "]" );
         str.append( "\n MaxPurgatorySize [" + this.getMaxPurgatorySize() + "]" 
);
         str.append( "\n BlockSizeBytes [" + this.getBlockSizeBytes() + "]" );
+        str.append( "\n KeyPersistenceIntervalSeconds [" + 
this.getKeyPersistenceIntervalSeconds() + "]" );
         return str.toString();
     }
 }

Modified: 
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskKeyStore.java
URL: 
http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskKeyStore.java?rev=437511&r1=437510&r2=437511&view=diff
==============================================================================
--- 
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskKeyStore.java
 (original)
+++ 
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskKeyStore.java
 Sun Aug 27 19:29:54 2006
@@ -28,6 +28,9 @@
 import org.apache.jcs.auxiliary.disk.LRUMapJCS;
 import org.apache.jcs.utils.timing.ElapsedTimer;
 
+import EDU.oswego.cs.dl.util.concurrent.ClockDaemon;
+import EDU.oswego.cs.dl.util.concurrent.ThreadFactory;
+
 /**
  * This is responsible for storing the keys.
  * <p>
@@ -35,7 +38,7 @@
  */
 public class BlockDiskKeyStore
 {
-    private static final Log log = LogFactory.getLog( BlockDiskCache.class );
+    private static final Log log = LogFactory.getLog( BlockDiskKeyStore.class 
);
 
     private BlockDiskCacheAttributes blockDiskCacheAttributes;
 
@@ -55,6 +58,11 @@
     private File rootDirectory;
 
     /**
+     * The background key persister, one for all regions.
+     */
+    private static ClockDaemon persistenceDaemon;
+
+    /**
      * Set the configuration options.
      * <p>
      * @param cacheAttributes
@@ -95,6 +103,26 @@
         {
             initKeyMap();
         }
+
+        // add this region to the persistence thread.
+        // TODO we might need to stagger this a bit.
+        if ( this.blockDiskCacheAttributes.getKeyPersistenceIntervalSeconds() 
> 0 )
+        {
+            if ( persistenceDaemon == null )
+            {
+                persistenceDaemon = new ClockDaemon();
+                persistenceDaemon.setThreadFactory( new MyThreadFactory() );
+            }
+            persistenceDaemon
+                .executePeriodically( 
this.blockDiskCacheAttributes.getKeyPersistenceIntervalSeconds() * 1000,
+                                      new Runnable()
+                                      {
+                                          public void run()
+                                          {
+                                              saveKeys();
+                                          }
+                                      }, false );
+        }
     }
 
     /**
@@ -369,6 +397,27 @@
                 log.debug( logCacheName + "Removing key: [" + key + "] from 
key store." );
                 log.debug( logCacheName + "Key store size: [" + this.size() + 
"]." );
             }
+        }
+    }
+
+    /**
+     * Allows us to set the daemon status on the clockdaemon
+     * @author aaronsm
+     */
+    class MyThreadFactory
+        implements ThreadFactory
+    {
+
+        /*
+         * (non-Javadoc)
+         * @see 
EDU.oswego.cs.dl.util.concurrent.ThreadFactory#newThread(java.lang.Runnable)
+         */
+        public Thread newThread( Runnable runner )
+        {
+            Thread t = new Thread( runner );
+            t.setDaemon( true );
+            t.setPriority( Thread.MIN_PRIORITY );
+            return t;
         }
     }
 }

Modified: jakarta/jcs/trunk/src/test-conf/TestBlockDiskCacheHuge.ccf
URL: 
http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test-conf/TestBlockDiskCacheHuge.ccf?rev=437511&r1=437510&r2=437511&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/test-conf/TestBlockDiskCacheHuge.ccf (original)
+++ jakarta/jcs/trunk/src/test-conf/TestBlockDiskCacheHuge.ccf Sun Aug 27 
19:29:54 2006
@@ -20,9 +20,9 @@
 # Block Disk Cache
 
jcs.auxiliary.blockDiskCache=org.apache.jcs.auxiliary.disk.block.BlockDiskCacheFactory
 
jcs.auxiliary.blockDiskCache.attributes=org.apache.jcs.auxiliary.disk.block.BlockDiskCacheAttributes
-jcs.auxiliary.blockDiskCache.attributes.DiskPath=target/test-sandbox/block-disk-cache-conc
+jcs.auxiliary.blockDiskCache.attributes.DiskPath=target/test-sandbox/block-disk-cache-huge
 jcs.auxiliary.blockDiskCache.attributes.MaxPurgatorySize=300000
-jcs.auxiliary.blockDiskCache.attributes.MaxKeySize=500000
+jcs.auxiliary.blockDiskCache.attributes.MaxKeySize=1000000
 jcs.auxiliary.blockDiskCache.attributes.blockSizeBytes=500
 jcs.auxiliary.blockDiskCache.attributes.EventQueueType=SINGLE
 
#jcs.auxiliary.blockDiskCache.attributes.EventQueuePoolName=disk_cache_event_queue

Modified: 
jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/HugeQuantityBlockDiskCacheLoadTest.java
URL: 
http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/HugeQuantityBlockDiskCacheLoadTest.java?rev=437511&r1=437510&r2=437511&view=diff
==============================================================================
--- 
jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/HugeQuantityBlockDiskCacheLoadTest.java
 (original)
+++ 
jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/HugeQuantityBlockDiskCacheLoadTest.java
 Sun Aug 27 19:29:54 2006
@@ -3,6 +3,8 @@
 import junit.framework.TestCase;
 
 import org.apache.jcs.JCS;
+import org.apache.jcs.utils.timing.ElapsedTimer;
+import org.apache.jcs.utils.timing.SleepUtil;
 
 /**
  * Put a few hundred thousand entries in the block disk cache.
@@ -38,15 +40,19 @@
         int items = 300000;
         String region = "testCache1";
 
-        JCS jcs = JCS.getInstance( region );
+        System.out.println( "--------------------------" );
+        long initialMemory = measureMemoryUse();
+        System.out.println( "Before getting JCS: " + initialMemory );
 
+        JCS jcs = JCS.getInstance( region );
+        jcs.clear();
+        
         try
         {
-
+            ElapsedTimer timer = new ElapsedTimer();            
             System.out.println( "Start: " + measureMemoryUse() );
 
             // Add items to cache
-
             for ( int i = 0; i <= items; i++ )
             {
                 jcs.put( i + ":key", region + " data " + i );
@@ -61,24 +67,40 @@
             System.out.println( jcs.getStats() );
             System.out.println( "--------------------------" );
             System.out.println( "After wait: " + measureMemoryUse() );
+            
+            for ( int i = 0; i < 10; i++ )
+            {
+                SleepUtil.sleepAtLeast( 3000 );
+                System.out.println( "--------------------------" );
+                System.out.println( "After sleep. " + 
timer.getElapsedTimeString() + " memory used = " + measureMemoryUse() );
+                System.out.println( jcs.getStats() );                
+            }
 
             // Test that all items are in cache
-
+            System.out.println( "--------------------------" );
+            System.out.println( "Retrieving all." );
             for ( int i = 0; i <= items; i++ )
             {
+                //System.out.print(  "\033[s" );
                 String value = (String) jcs.get( i + ":key" );
-
-                assertEquals( region + " data " + i, value );
+                if( i % 1000 == 0 )
+                {
+                    //System.out.print(  "\033[r" );
+                    System.out.println(  i + " ");
+                }
+                assertEquals( "Wrong value returned.", region + " data " + i, 
value );
             }
-
-            System.out.println( "After get: " + measureMemoryUse() );
+            long aftetGet = measureMemoryUse();
+            System.out.println( "After get: " + aftetGet + " diff = " + 
(aftetGet - initialMemory));
+        
         }
         finally
         {
             // dump the stats to the report
             System.out.println( jcs.getStats() );
             System.out.println( "--------------------------" );
-            System.out.println( "End: " + measureMemoryUse() );
+            long endMemory = measureMemoryUse();
+            System.out.println( "End: " + endMemory + " diff = " + (endMemory 
- initialMemory) );
         }
     }
 



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to