Author: asmuts
Date: Mon Mar 19 06:18:22 2007
New Revision: 519940
URL: http://svn.apache.org/viewvc?view=rev&rev=519940
Log:
FIXED JCS-15
The indexed disk cache was not removing items when called with a partial key or a group. The problem was that it was trying to remove from an iterator on a copy of the keys.
I fixed the problem and added a couple unit tests.
I also cleaned up the block disk cache and change the lock.
Modified:
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/AbstractDiskCache.java
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/AbstractDiskCacheAttributes.java
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/LRUMapJCS.java
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/PurgatoryElement.java
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/behavior/IDiskCacheAttributes.java
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/BlockDiskCacheFactory.java
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheManager.java
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskElementDescriptor.java
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskKeyStore.java
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/indexed/IndexedDiskCache.java
jakarta/jcs/trunk/src/java/org/apache/jcs/utils/struct/LRUMap.java
jakarta/jcs/trunk/src/test-conf/log4j.properties
jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheConcurrentUnitTest.java
jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheKeyStoreUnitTest.java
jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheRandomConcurrentTestUtil.java
jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheSameRegionConcurrentUnitTest.java
jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/indexed/IndexDiskCacheUnitTest.java
jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/indexed/IndexedDiskCacheOptimizationUnitTest.java
jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCacheShrinkUnitTest.java
jakarta/jcs/trunk/xdocs/changes.xml
Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/AbstractDiskCache.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/AbstractDiskCache.java?view=diff&rev=519940&r1=519939&r2=519940
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/AbstractDiskCache.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/AbstractDiskCache.java Mon Mar 19 06:18:22 2007
@@ -1,14 +1,12 @@
package org.apache.jcs.auxiliary.disk;
/*
- * Copyright 2001-2004 The Apache Software Foundation. Licensed 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.
+ * Copyright 2001-2004 The Apache Software Foundation. Licensed 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.IOException;
@@ -39,53 +37,50 @@
import EDU.oswego.cs.dl.util.concurrent.WriterPreferenceReadWriteLock;
/**
- * Abstract class providing a base implementation of a disk cache, which can be
- * easily extended to implement a disk cache for a specific perstistence
- * mechanism.
+ * Abstract class providing a base implementation of a disk cache, which can be easily extended to
+ * implement a disk cache for a specific perstistence mechanism.
* <p>
- * When implementing the abstract methods note that while this base class
- * handles most things, it does not acquire or release any locks.
- * Implementations should do so as neccesary. This is mainly done to minimize
- * the time speant in critical sections.
+ * When implementing the abstract methods note that while this base class handles most things, it
+ * does not acquire or release any locks. Implementations should do so as neccesary. This is mainly
+ * done to minimize the time speant in critical sections.
* <p>
- * Error handling in this class needs to be addressed. Currently if an exception
- * is thrown by the persistence mechanism, this class destroys the event queue.
- * Should it also destory purgatory? Should it dispose itself?
+ * Error handling in this class needs to be addressed. Currently if an exception is thrown by the
+ * persistence mechanism, this class destroys the event queue. Should it also destory purgatory?
+ * Should it dispose itself?
*/
public abstract class AbstractDiskCache
implements AuxiliaryCache, Serializable
{
+ /** The logger */
private static final Log log = LogFactory.getLog( AbstractDiskCache.class );
/** Generic disk cache attributes */
private IDiskCacheAttributes dcattr = null;
/**
- * Map where elements are stored between being added to this cache and
- * actually spooled to disk. This allows puts to the disk cache to return
- * quickly, and the more expensive operation of serializing the elements to
- * persistent storage queued for later.
+ * Map where elements are stored between being added to this cache and actually spooled to disk.
+ * This allows puts to the disk cache to return quickly, and the more expensive operation of
+ * serializing the elements to persistent storage queued for later.
* <p>
- * If the elements are pulled into the memory cache while the are still in
- * purgatory, writing to disk can be cancelled.
+ * If the elements are pulled into the memory cache while the are still in purgatory, writing to
+ * disk can be cancelled.
*/
protected Map purgatory = new HashMap();
/**
- * The CacheEventQueue where changes will be queued for asynchronous
- * updating of the persistent storage.
+ * The CacheEventQueue where changes will be queued for asynchronous updating of the persistent
+ * storage.
*/
protected ICacheEventQueue cacheEventQueue;
/**
- * Indicates whether the cache is 'alive', defined as having been
- * initialized, but not yet disposed.
+ * Indicates whether the cache is 'alive', defined as having been initialized, but not yet
+ * disposed.
*/
protected boolean alive = false;
/**
- * Every cache will have a name, subclasses must set this when they are
- * initialized.
+ * Every cache will have a name, subclasses must set this when they are initialized.
*/
protected String cacheName;
@@ -94,8 +89,10 @@
*/
protected int purgHits = 0;
- // we lock here, so that we cannot get an update after a remove all.
- // an individual removal locks the item.
+ /**
+ * We lock here, so that we cannot get an update after a remove all. an individual removal locks
+ * the item.
+ */
private WriterPreferenceReadWriteLock removeAllLock = new WriterPreferenceReadWriteLock();
// ----------------------------------------------------------- constructors
@@ -122,13 +119,12 @@
}
/**
- * Purgatory size of -1 means to use a HashMap with no size limit. Anything
- * greater will use an LRU map of some sort.
+ * Purgatory size of -1 means to use a HashMap with no size limit. Anything greater will use an
+ * LRU map of some sort.
* <p>
- * @TODO Currently setting this to 0 will cause nothing to be put to disk,
- * since it will assume that if an item is not in purgatory, then it
- * must have been plucked. We should make 0 work, a way to not use
- * purgatory.
+ * @TODO Currently setting this to 0 will cause nothing to be put to disk, since it will assume
+ * that if an item is not in purgatory, then it must have been plucked. We should make 0
+ * work, a way to not use purgatory.
*/
private void initPurgatory()
{
@@ -177,13 +173,11 @@
// ------------------------------------------------------- interface ICache
/**
- * Adds the provided element to the cache. Element will be added to
- * purgatory, and then queued for later writing to the serialized storage
- * mechanism.
- * <p>
- * An update results in a put event being created. The put event will call
- * the handlePut method defined here. The handlePut method calls the
- * implemented doPut on the child.
+ * Adds the provided element to the cache. Element will be added to purgatory, and then queued
+ * for later writing to the serialized storage mechanism.
+ * <p>
+ * An update results in a put event being created. The put event will call the handlePut method
+ * defined here. The handlePut method calls the implemented doPut on the child.
* <p>
* @param cacheElement
* @throws IOException
@@ -225,8 +219,8 @@
}
/**
- * Check to see if the item is in purgatory. If so, return it. If not, check
- * to see if we have it on disk.
+ * Check to see if the item is in purgatory. If so, return it. If not, check to see if we have
+ * it on disk.
* <p>
* @param key
* @return ICacheElement or null
@@ -297,6 +291,12 @@
return null;
}
+ /**
+ * The keys in a group.
+ * <p>
+ * (non-Javadoc)
+ * @see org.apache.jcs.auxiliary.AuxiliaryCache#getGroupKeys(java.lang.String)
+ */
public abstract Set getGroupKeys( String groupName );
/**
@@ -370,11 +370,10 @@
* <p>
* Disposal proceeds in several steps.
* <ol>
- * <li> Prior to this call the Composite cache dumped the memory into the
- * disk cache. If it is large then we need to wait for the event queue to
- * finish.
- * <li> Wait until the event queue is empty of until the configured
- * ShutdownSpoolTimeLimit is reached.
+ * <li> Prior to this call the Composite cache dumped the memory into the disk cache. If it is
+ * large then we need to wait for the event queue to finish.
+ * <li> Wait until the event queue is empty of until the configured ShutdownSpoolTimeLimit is
+ * reached.
* <li> Call doDispose on the concrete impl.
* </ol>
*/
@@ -428,6 +427,7 @@
}
/**
+ * @return the region name.
* @see ICache#getCacheName
*/
public String getCacheName()
@@ -445,8 +445,9 @@
return getStatistics().toString();
}
- /*
- * (non-Javadoc)
+ /**
+ * Returns semi-structured data.
+ * <p>
* @see org.apache.jcs.auxiliary.AuxiliaryCache#getStatistics()
*/
public IStats getStatistics()
@@ -483,6 +484,7 @@
}
/**
+ * @return the status -- alive or disposed from CacheConstants
* @see ICache#getStatus
*/
public int getStatus()
@@ -491,17 +493,17 @@
}
/**
- * Size cannot be determined without knowledge of the cache implementation,
- * so subclasses will need to implement this method.
+ * Size cannot be determined without knowledge of the cache implementation, so subclasses will
+ * need to implement this method.
* <p>
+ * @return the number of items.
* @see ICache#getSize
*/
public abstract int getSize();
/**
* @see org.apache.jcs.engine.behavior.ICacheType#getCacheType
- * @return Always returns DISK_CACHE since subclasses should all be of that
- * type.
+ * @return Always returns DISK_CACHE since subclasses should all be of that type.
*/
public int getCacheType()
{
@@ -509,15 +511,18 @@
}
/**
- * Cache that implements the CacheListener interface, and calls appropriate
- * methods in its parent class.
+ * Cache that implements the CacheListener interface, and calls appropriate methods in its
+ * parent class.
*/
private class MyCacheListener
implements ICacheListener
{
+ /** Id of the listener */
private long listenerId = 0;
/**
+ * @return cacheElement.getElementAttributes();
+ * @throws IOException
* @see ICacheListener#getListenerId
*/
public long getListenerId()
@@ -540,10 +545,9 @@
/**
* @param element
* @throws IOException
- * @see ICacheListener#handlePut NOTE: This checks if the element is a
- * puratory element and behaves differently depending. However
- * since we have control over how elements are added to the cache
- * event queue, that may not be needed ( they are always
+ * @see ICacheListener#handlePut NOTE: This checks if the element is a puratory element and
+ * behaves differently depending. However since we have control over how elements are
+ * added to the cache event queue, that may not be needed ( they are always
* PurgatoryElements ).
*/
public void handlePut( ICacheElement element )
@@ -616,10 +620,9 @@
else
{
/*
- * The cache is not alive, hence the element should be removed
- * from purgatory. All elements should be removed eventually.
- * Perhaps, the alive check should have been done before it went
- * in the queue. This block handles the case where the disk
+ * The cache is not alive, hence the element should be removed from purgatory. All
+ * elements should be removed eventually. Perhaps, the alive check should have been
+ * done before it went in the queue. This block handles the case where the disk
* cache fails during normal opertations.
*/
synchronized ( purgatory )
@@ -680,8 +683,7 @@
/**
* Get a value from the persistent store.
- * @param key
- * Key to locate value for.
+ * @param key Key to locate value for.
* @return An object matching key, or null.
*/
protected abstract ICacheElement doGet( Serializable key );
@@ -694,8 +696,7 @@
/**
* Remove an object from the persistent store if found.
- * @param key
- * Key of object to remove.
+ * @param key Key of object to remove.
* @return whether or no the item was present when removed
*/
protected abstract boolean doRemove( Serializable key );
@@ -706,8 +707,8 @@
protected abstract void doRemoveAll();
/**
- * Dispose of the persistent store. Note that disposal of purgatory and
- * setting alive to false does NOT need to be done by this method.
+ * Dispose of the persistent store. Note that disposal of purgatory and setting alive to false
+ * does NOT need to be done by this method.
*/
protected abstract void doDispose();
Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/AbstractDiskCacheAttributes.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/AbstractDiskCacheAttributes.java?view=diff&rev=519940&r1=519939&r2=519940
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/AbstractDiskCacheAttributes.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/AbstractDiskCacheAttributes.java Mon Mar 19 06:18:22 2007
@@ -24,16 +24,16 @@
extends AbstractAuxiliaryCacheAttributes
implements IDiskCacheAttributes
{
-
/** path to disk */
protected String diskPath;
- // if this is false, we will not execute remove all
+ /** if this is false, we will not execute remove all */
private boolean allowRemoveAll = true;
/** default to 5000 */
protected int maxPurgatorySize = MAX_PURGATORY_SIZE_DEFUALT;
+ /** Default amount of time to allow for keypersistence on shutdown */
private static final int DEFAULT_shutdownSpoolTimeLimit = 60;
/**
@@ -144,5 +144,4 @@
str.append( "\n allowRemoveAll = " + allowRemoveAll );
return str.toString();
}
-
}
Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/LRUMapJCS.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/LRUMapJCS.java?view=diff&rev=519940&r1=519939&r2=519940
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/LRUMapJCS.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/LRUMapJCS.java Mon Mar 19 06:18:22 2007
@@ -5,14 +5,16 @@
import org.apache.jcs.utils.struct.LRUMap;
/**
- * Extension of LRUMap for logging of removals. Can switch this back to a
- * HashMap easily.
+ * Extension of LRUMap for logging of removals. Can switch this back to a HashMap easily. This
+ * provides some abstraction. It also makes it easy to log overflow.
*/
public class LRUMapJCS
extends LRUMap
{
+ /** Don't change */
private static final long serialVersionUID = 776964015449842672L;
+ /** The logger */
private static final Log log = LogFactory.getLog( LRUMapJCS.class );
/**
@@ -24,11 +26,11 @@
}
/**
- * This creates a list bounded by the max key size argument. The Boundary is
- * enforces by an LRU eviction policy.
+ * This creates a list bounded by the max key size argument. The Boundary is enforces by an LRU
+ * eviction policy.
* <p>
- * This is used in the Disk cache to store keys and purgatory elements if a
- * boundary is requested.
+ * This is used in the Disk cache to store keys and purgatory elements if a boundary is
+ * requested.
* <p>
* The LRU memory cache uses its own LRU implementation.
* <p>
@@ -40,8 +42,7 @@
}
/**
- * This is called when an item is removed from the LRU. We just log some
- * information.
+ * This is called when an item is removed from the LRU. We just log some information.
* <p>
* @param key
* @param value
Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/PurgatoryElement.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/PurgatoryElement.java?view=diff&rev=519940&r1=519939&r2=519940
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/PurgatoryElement.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/PurgatoryElement.java Mon Mar 19 06:18:22 2007
@@ -1,14 +1,12 @@
package org.apache.jcs.auxiliary.disk;
/*
- * Copyright 2001-2004 The Apache Software Foundation. Licensed 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.
+ * Copyright 2001-2004 The Apache Software Foundation. Licensed 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;
@@ -17,30 +15,27 @@
import org.apache.jcs.engine.behavior.IElementAttributes;
/**
- * Wrapper for cache elements in purgatory. Elements are stored in purgatory
- * when they are spooled to the auxilliary cache, but have not yet been written
- * to disk.
+ * Wrapper for cache elements in purgatory.
+ * <p>
+ * Elements are stored in purgatory when they are spooled to the auxilliary cache, but have not yet
+ * been written to disk.
*/
public class PurgatoryElement
implements ICacheElement, Serializable
{
+ /** Don't change */
private static final long serialVersionUID = -8152034342684135628L;
- /**
- * Is the element ready to be spooled?
- */
+ /** Is the element ready to be spooled? */
protected boolean spoolable = false;
- /**
- * Wrapped cache Element
- */
+ /** Wrapped cache Element */
protected ICacheElement cacheElement;
/**
* Constructor for the PurgatoryElement object
* <p>
- * @param cacheElement
- * CacheElement to wrap.
+ * @param cacheElement CacheElement to wrap.
*/
public PurgatoryElement( ICacheElement cacheElement )
{
@@ -60,8 +55,7 @@
/**
* Sets the spoolable property.
* <p>
- * @param spoolable
- * The new spoolable value
+ * @param spoolable The new spoolable value
*/
public void setSpoolable( boolean spoolable )
{
@@ -81,6 +75,7 @@
// ------------------------------------------------ interface ICacheElement
/**
+ * @return cacheElement.getCacheName();
* @see ICacheElement#getCacheName
*/
public String getCacheName()
@@ -89,6 +84,7 @@
}
/**
+ * @return cacheElement.getKey();
* @see ICacheElement#getKey
*/
public Serializable getKey()
@@ -97,6 +93,7 @@
}
/**
+ * @return cacheElement.getVal();
* @see ICacheElement#getVal
*/
public Serializable getVal()
@@ -105,6 +102,7 @@
}
/**
+ * @return cacheElement.getElementAttributes();
* @see ICacheElement#getElementAttributes
*/
public IElementAttributes getElementAttributes()
Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/behavior/IDiskCacheAttributes.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/behavior/IDiskCacheAttributes.java?view=diff&rev=519940&r1=519939&r2=519940
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/behavior/IDiskCacheAttributes.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/behavior/IDiskCacheAttributes.java Mon Mar 19 06:18:22 2007
@@ -19,7 +19,6 @@
public interface IDiskCacheAttributes
extends AuxiliaryCacheAttributes
{
-
/**
* This is the default purgatory size limit. Purgatory is the area where
* items to be spooled are temporarily stored. It basically provides access
@@ -81,7 +80,7 @@
/**
* If this is true then remove all is not prohibited.
* <p>
- * @return
+ * @return boolean
*/
public boolean isAllowRemoveAll();
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?view=diff&rev=519940&r1=519939&r2=519940
==============================================================================
--- 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 Mon Mar 19 06:18:22 2007
@@ -28,14 +28,16 @@
*/
public class BlockDisk
{
+ /** The logger */
private static final Log log = LogFactory.getLog( BlockDisk.class );
/** The size of the header that indicates the amount of data stored in an occupied block. */
public static final byte HEADER_SIZE_BYTES = 4;
- // defaults to 4kb
+ /** defaults to 4kb */
private static final int DEFAULT_BLOCK_SIZE_BYTES = 4 * 1024;
+ /** Size of the blocks */
private int blockSizeBytes = DEFAULT_BLOCK_SIZE_BYTES;
/**
@@ -44,16 +46,22 @@
*/
private int numberOfBlocks = 0;
+ /** Empty blocks that can be reused. */
private SingleLinkedList emptyBlocks = new SingleLinkedList();
+ /** Handles serializing the objects */
private static final StandardSerializer SERIALIZER = new StandardSerializer();
+ /** Location of the spot on disk */
private final String filepath;
+ /** The file handle. */
private RandomAccessFile raf;
+ /** How many bytes have we put to disk */
private long putBytes = 0;
+ /** How many items have we put to disk */
private long putCount = 0;
/**
@@ -342,7 +350,7 @@
* Calcuates the file offset for a particular block.
* <p>
* @param block
- * @return
+ * @return the offset for this block
*/
protected int calculateByteOffsetForBlock( int block )
{
@@ -353,7 +361,7 @@
* The number of blocks needed.
* <p>
* @param data
- * @return
+ * @return the number of blocks needed to store the byte array
*/
protected int calculateTheNumberOfBlocksNeeded( byte[] data )
{
@@ -379,7 +387,7 @@
/**
* Returns the raf length.
* <p>
- * @return
+ * @return the size of the file.
* @exception IOException
*/
protected long length()
@@ -438,6 +446,10 @@
*/
protected long getAveragePutSizeBytes()
{
+ if ( this.putCount == 0 )
+ {
+ return 0;
+ }
return this.putBytes / this.putCount;
}
@@ -451,6 +463,8 @@
/**
* For debugging only.
+ * <p>
+ * @return String with details.
*/
public String toString()
{
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?view=diff&rev=519940&r1=519939&r2=519940
==============================================================================
--- 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 Mon Mar 19 06:18:22 2007
@@ -33,36 +33,47 @@
import org.apache.jcs.engine.stats.behavior.IStatElement;
import org.apache.jcs.engine.stats.behavior.IStats;
-import EDU.oswego.cs.dl.util.concurrent.ReentrantWriterPreferenceReadWriteLock;
+import EDU.oswego.cs.dl.util.concurrent.WriterPreferenceReadWriteLock;
/**
+ * There is one BlockDiskCache per region. It manages the key and data store.
+ * <p>
* @author Aaron Smuts
*/
public class BlockDiskCache
extends AbstractDiskCache
{
+ /** Don't change */
private static final long serialVersionUID = 1L;
+ /** The logger. */
private static final Log log = LogFactory.getLog( BlockDiskCache.class );
+ /** The name to prefix all log messages with. */
private final String logCacheName;
+ /** The name of the file to store data. */
private String fileName;
+ /** The data access object */
private BlockDisk dataFile;
+ /** Attributes governing the behavior of the block disk cache. */
private BlockDiskCacheAttributes blockDiskCacheAttributes;
+ /** The root directory for keys and data. */
private File rootDirectory;
/** Store, loads, and persists the keys */
private BlockDiskKeyStore keyStore;
- // public Object lock = new Object();
/**
- * Use this lock to synchronize reads and writes to the underlying storage mechansism.
+ * Use this lock to synchronize reads and writes to the underlying storage mechansism. We don't
+ * need a reentrant lock, since we only lock one level.
*/
- protected ReentrantWriterPreferenceReadWriteLock storageLock = new ReentrantWriterPreferenceReadWriteLock();
+ // private ReentrantWriterPreferenceReadWriteLock storageLock = new
+ // ReentrantWriterPreferenceReadWriteLock();
+ private WriterPreferenceReadWriteLock storageLock = new WriterPreferenceReadWriteLock();
/**
* Constructs the BlockDisk after setting up the root directory.
@@ -95,7 +106,8 @@
{
if ( this.blockDiskCacheAttributes.getBlockSizeBytes() > 0 )
{
- this.dataFile = new BlockDisk( new File( rootDirectory, fileName + ".data" ), this.blockDiskCacheAttributes.getBlockSizeBytes() );
+ this.dataFile = new BlockDisk( new File( rootDirectory, fileName + ".data" ),
+ this.blockDiskCacheAttributes.getBlockSizeBytes() );
}
else
{
@@ -158,7 +170,7 @@
}
catch ( Exception e )
{
- log.warn( "Problem verifying disk. Message [" + e.getMessage() + "]" );
+ log.warn( "Problem verifying disk. Message [" + e.getMessage() + "]" );
alright = false;
}
return alright;
@@ -532,7 +544,9 @@
}
}
- /*
+ /**
+ * Returns the attributes.
+ * <p>
* (non-Javadoc)
* @see org.apache.jcs.auxiliary.AuxiliaryCache#getAuxiliaryCacheAttributes()
*/
@@ -567,13 +581,14 @@
if ( this.blockDiskCacheAttributes.getBlockSizeBytes() > 0 )
{
- this.dataFile = new BlockDisk( new File( rootDirectory, fileName + ".data" ), this.blockDiskCacheAttributes.getBlockSizeBytes() );
+ 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 )
@@ -603,6 +618,7 @@
class ShutdownHook
extends Thread
{
+ /** Disposes of the cache. This will result force the keys to be persisted. */
public void run()
{
if ( alive )
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?view=diff&rev=519940&r1=519939&r2=519940
==============================================================================
--- 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 Mon Mar 19 06:18:22 2007
@@ -10,21 +10,24 @@
public class BlockDiskCacheAttributes
extends AbstractDiskCacheAttributes
{
+ /** Don't change */
private static final long serialVersionUID = 6568840097657265989L;
+ /** The size per block in bytes. */
private int blockSizeBytes;
+ /** Maximum number of keys to be kept in memory */
private static final int DEFAULT_MAX_KEY_SIZE = 5000;
/** -1 means no limit. */
private int maxKeySize = DEFAULT_MAX_KEY_SIZE;
+ /** How often should we persist the keys. */
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>
Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheFactory.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheFactory.java?view=diff&rev=519940&r1=519939&r2=519940
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheFactory.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheFactory.java Mon Mar 19 06:18:22 2007
@@ -22,8 +22,10 @@
public class BlockDiskCacheFactory
implements AuxiliaryCacheFactory
{
+ /** The logger */
private final static Log log = LogFactory.getLog( BlockDiskCacheFactory.class );
+ /** The auxiliary name */
private String name;
/**
Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheManager.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheManager.java?view=diff&rev=519940&r1=519939&r2=519940
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheManager.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheManager.java Mon Mar 19 06:18:22 2007
@@ -27,16 +27,22 @@
public class BlockDiskCacheManager
implements AuxiliaryCacheManager
{
+ /** Don't change */
private static final long serialVersionUID = -4153287154512274626L;
+ /** The logger */
private final static Log log = LogFactory.getLog( BlockDiskCacheManager.class );
+ /** ? */
private static int clients;
+ /** The singleton instance */
private static BlockDiskCacheManager instance;
+ /** block disks for a region. */
private Hashtable caches = new Hashtable();
+ /** Attributes. */
private BlockDiskCacheAttributes defaultCacheAttributes;
/**
Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskElementDescriptor.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskElementDescriptor.java?view=diff&rev=519940&r1=519939&r2=519940
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskElementDescriptor.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/block/BlockDiskElementDescriptor.java Mon Mar 19 06:18:22 2007
@@ -25,10 +25,13 @@
public class BlockDiskElementDescriptor
implements Serializable, Externalizable
{
+ /** Don't change */
private static final long serialVersionUID = -1400659301208101411L;
+ /** The key */
private Serializable key;
+ /** The array of block numbers */
private int[] blocks;
/**
@@ -67,6 +70,8 @@
/**
* For debugging.
+ * <p>
+ * @return Info on the descriptor.
*/
public String 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?view=diff&rev=519940&r1=519939&r2=519940
==============================================================================
--- 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 Mon Mar 19 06:18:22 2007
@@ -38,23 +38,31 @@
*/
public class BlockDiskKeyStore
{
+ /** The logger */
private static final Log log = LogFactory.getLog( BlockDiskKeyStore.class );
+ /** Attributes governing the behavior of the block disk cache. */
private BlockDiskCacheAttributes blockDiskCacheAttributes;
+ /** The key to block map */
private Map keyHash;
+ /** The file where we persist the keys */
private File keyFile;
+ /** The name to prefix log messages with. */
private final String logCacheName;
+ /** Name of the file where we persist the keys */
private String fileName;
+ /** The maximum number of keys to store in memory */
private int maxKeySize;
- // we need this so we can communicate free blocks to the data store when keys fall off the LRU
+ /** we need this so we can communicate free blocks to the data store when keys fall off the LRU */
private BlockDiskCache blockDiskCache;
+ /** The root directory in which the keyFile lives */
private File rootDirectory;
/**
@@ -362,6 +370,7 @@
public class LRUMap
extends LRUMapJCS
{
+ /** Don't change */
private static final long serialVersionUID = 4955079991472142198L;
/**
@@ -388,6 +397,9 @@
/**
* This is called when the may key size is reaced. 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( Object key, Object value )
{
@@ -408,7 +420,9 @@
implements ThreadFactory
{
- /*
+ /**
+ * Ensures that we create daemon threads.
+ * <p>
* (non-Javadoc)
* @see EDU.oswego.cs.dl.util.concurrent.ThreadFactory#newThread(java.lang.Runnable)
*/
Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/indexed/IndexedDiskCache.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/indexed/IndexedDiskCache.java?view=diff&rev=519940&r1=519939&r2=519940
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/indexed/IndexedDiskCache.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/indexed/IndexedDiskCache.java Mon Mar 19 06:18:22 2007
@@ -50,8 +50,10 @@
public class IndexedDiskCache
extends AbstractDiskCache
{
+ /** Don't change */
private static final long serialVersionUID = -265035607729729629L;
+ /** The logger */
private static final Log log = LogFactory.getLog( IndexedDiskCache.class );
private final String logCacheName;
@@ -74,22 +76,22 @@
boolean isShutdownOptimizationEnabled = true;
- // are we currenlty optimizing the files
+ /** are we currenlty optimizing the files */
boolean isOptimizing = false;
private int timesOptimized = 0;
private volatile Thread currentOptimizationThread;
- // used for counting the number of requests
+ /** used for counting the number of requests */
private int removeCount = 0;
private boolean queueInput = false;
- // list where puts made during optimization are made
+ /** list where puts made during optimization are made */
private LinkedList queuedPutList = new LinkedList();
- // RECYLCE BIN -- array of empty spots
+ /** RECYLCE BIN -- array of empty spots */
private SortedPreferentialArray recycle;
private IndexedDiskCacheAttributes cattr;
@@ -98,11 +100,11 @@
private int startupSize = 0;
- // the number of bytes free on disk.
+ /** the number of bytes free on disk. */
private long bytesFree = 0;
private int hitCount = 0;
-
+
/**
* Use this lock to synchronize reads and writes to the underlying storage mechansism.
*/
@@ -522,13 +524,13 @@
storageLock.readLock().acquire();
try
{
- object = readElement( key );
+ object = readElement( key );
}
finally
{
storageLock.readLock().release();
}
-
+
if ( object != null )
{
incrementHitCount();
@@ -626,7 +628,7 @@
* Returns true if the removal was succesful; or false if there is nothing to remove. Current
* implementation always result in a disk orphan.
* <p>
- * @return
+ * @return true if at least one item was removed.
* @param key
*/
public boolean doRemove( Serializable key )
@@ -636,6 +638,11 @@
log.error( logCacheName + "No longer alive so returning false for key = " + key );
return false;
}
+
+ if ( key == null )
+ {
+ return false;
+ }
boolean reset = false;
boolean removed = false;
@@ -645,56 +652,15 @@
if ( key instanceof String && key.toString().endsWith( CacheConstants.NAME_COMPONENT_DELIMITER ) )
{
- // remove all keys of the same name group.
-
- Iterator iter = keyHash.entrySet().iterator();
-
- while ( iter.hasNext() )
- {
- Map.Entry entry = (Map.Entry) iter.next();
-
- Object k = entry.getKey();
-
- if ( k instanceof String && k.toString().startsWith( key.toString() ) )
- {
- IndexedDiskElementDescriptor ded = (IndexedDiskElementDescriptor) keyHash.get( key );
- addToRecycleBin( ded );
- iter.remove();
- removed = true;
- // TODO this needs to update the rmove count separately
- }
- }
+ removed = performPartialKeyRemoval( (String) key );
}
else if ( key instanceof GroupId )
{
- // remove all keys of the same name hierarchy.
- Iterator iter = keyHash.entrySet().iterator();
- while ( iter.hasNext() )
- {
- Map.Entry entry = (Map.Entry) iter.next();
- Object k = entry.getKey();
-
- if ( k instanceof GroupAttrName && ( (GroupAttrName) k ).groupId.equals( key ) )
- {
- IndexedDiskElementDescriptor ded = (IndexedDiskElementDescriptor) keyHash.get( key );
- addToRecycleBin( ded );
- iter.remove();
- removed = true;
- }
- }
+ removed = performGroupRemoval( (GroupId) key );
}
else
{
- // remove single item.
- IndexedDiskElementDescriptor ded = (IndexedDiskElementDescriptor) keyHash.remove( key );
- removed = ( ded != null );
- addToRecycleBin( ded );
-
- if ( log.isDebugEnabled() )
- {
- log.debug( logCacheName + "Disk removal: Removed from key hash, key [" + key + "] removed = "
- + removed );
- }
+ removed = performSingleKeyRemoval( key );
}
}
catch ( Exception e )
@@ -723,6 +689,113 @@
}
/**
+ * Iterates over the keyset. Builds a list of matches. Removes all the keys in the list . Does
+ * not remove via the iterator, since the map impl may not support it.
+ * <p>
+ * This operates under a lock obtained in doRemove().
+ * <p>
+ * @param key
+ * @return true if there was a match
+ */
+ private boolean performPartialKeyRemoval( String key )
+ {
+ boolean removed = false;
+
+ // remove all keys of the same name hierarchy.
+ List itemsToRemove = new LinkedList();
+
+ Iterator iter = keyHash.entrySet().iterator();
+ while ( iter.hasNext() )
+ {
+ Map.Entry entry = (Map.Entry) iter.next();
+ Object k = entry.getKey();
+ if ( k instanceof String && k.toString().startsWith( key.toString() ) )
+ {
+ itemsToRemove.add( k );
+ }
+ }
+
+ // remove matches.
+ Iterator itToRemove = itemsToRemove.iterator();
+ while ( itToRemove.hasNext() )
+ {
+ String fullKey = (String) itToRemove.next();
+ IndexedDiskElementDescriptor ded = (IndexedDiskElementDescriptor) keyHash.get( fullKey );
+ addToRecycleBin( ded );
+ performSingleKeyRemoval( fullKey );
+ removed = true;
+ // TODO this needs to update the remove count separately
+ }
+
+ return removed;
+ }
+
+ /**
+ * Remove all elements from the group. This does not use the iterator to remove. It builds a
+ * list of group elemetns and then removes them one by one.
+ * <p>
+ * This operates under a lock obtained in doRemove().
+ * <p>
+ * @param key
+ * @return true if an element was removed
+ */
+ private boolean performGroupRemoval( GroupId key )
+ {
+ boolean removed = false;
+
+ // remove all keys of the same name group.
+ List itemsToRemove = new LinkedList();
+
+ // remove all keys of the same name hierarchy.
+ Iterator iter = keyHash.entrySet().iterator();
+ while ( iter.hasNext() )
+ {
+ Map.Entry entry = (Map.Entry) iter.next();
+ Object k = entry.getKey();
+
+ if ( k instanceof GroupAttrName && ( (GroupAttrName) k ).groupId.equals( key ) )
+ {
+ itemsToRemove.add( k );
+ }
+ }
+
+ // remove matches.
+ Iterator itToRemove = itemsToRemove.iterator();
+ while ( itToRemove.hasNext() )
+ {
+ GroupAttrName keyToRemove = (GroupAttrName) itToRemove.next();
+ IndexedDiskElementDescriptor ded = (IndexedDiskElementDescriptor) keyHash.get( keyToRemove );
+ addToRecycleBin( ded );
+ performSingleKeyRemoval( keyToRemove );
+ removed = true;
+ }
+ return removed;
+ }
+
+ /**
+ * Removes an individual key from the cache.
+ * <p>
+ * This operates under a lock obtained in doRemove().
+ * <p>
+ * @param key
+ * @return true if an item was removed.
+ */
+ private boolean performSingleKeyRemoval( Serializable key )
+ {
+ boolean removed;
+ // remove single item.
+ IndexedDiskElementDescriptor ded = (IndexedDiskElementDescriptor) keyHash.remove( key );
+ removed = ( ded != null );
+ addToRecycleBin( ded );
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( logCacheName + "Disk removal: Removed from key hash, key [" + key + "] removed = " + removed );
+ }
+ return removed;
+ }
+
+ /**
* Remove all the items from the disk cache by reseting everything.
*/
public void doRemoveAll()
@@ -1215,8 +1288,8 @@
/**
* To subtract you can pass in false for add..
* <p>
- * @param ded
- * @param add
+ * @param ded
+ * @param add
*/
private synchronized void adjustBytesFree( IndexedDiskElementDescriptor ded, boolean add )
{
@@ -1305,16 +1378,15 @@
{
return this.cattr;
}
-
+
/**
* Increments the hit count in a thread safe manner.
- *
*/
private synchronized void incrementHitCount()
{
hitCount++;
}
-
+
/**
* Gets basic stats for the disk cache.
* <p>
@@ -1442,6 +1514,11 @@
private static final class PositionComparator
implements Comparator
{
+ /**
+ * Compares two descriptors based on position.
+ * <p>
+ * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+ */
public int compare( Object o1, Object o2 )
{
IndexedDiskElementDescriptor ded1 = (IndexedDiskElementDescriptor) o1;
@@ -1469,6 +1546,7 @@
public class LRUMap
extends LRUMapJCS
{
+ /** Don't change */
private static final long serialVersionUID = 4955079991472142198L;
/**
@@ -1495,6 +1573,9 @@
/**
* This is called when the may key size is reaced. 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( Object key, Object value )
{
@@ -1516,6 +1597,11 @@
class ShutdownHook
extends Thread
{
+ /**
+ * This will persist the keys on shutdown.
+ * <p>
+ * @see java.lang.Thread#run()
+ */
public void run()
{
if ( alive )
Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/utils/struct/LRUMap.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/utils/struct/LRUMap.java?view=diff&rev=519940&r1=519939&r2=519940
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/utils/struct/LRUMap.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/utils/struct/LRUMap.java Mon Mar 19 06:18:22 2007
@@ -160,44 +160,6 @@
}
}
- /**
- * 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()
- */
- public synchronized Set entrySet()
- {
- // todo, we should return a defensive copy
- Set entries = map.entrySet();
-
- Set unWrapped = new HashSet();
-
- Iterator it = entries.iterator();
- while ( it.hasNext() )
- {
- Entry pre = (Entry) it.next();
- Entry post = new LRUMapEntry( pre.getKey(), ( (LRUElementDescriptor) pre.getValue() ).getPayload() );
- unWrapped.add( post );
- }
-
- return unWrapped;
- }
-
- /*
- * (non-Javadoc)
- * @see java.util.Map#keySet()
- */
- public Set keySet()
- {
- // TODO fix this, it needs to return the keys inside the wrappers.
- return map.keySet();
- }
-
/*
* (non-Javadoc)
* @see java.util.Map#get(java.lang.Object)
@@ -641,5 +603,43 @@
stats.setStatElements( ses );
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()
+ */
+ public synchronized Set entrySet()
+ {
+ // todo, we should return a defensive copy
+ Set entries = map.entrySet();
+
+ Set unWrapped = new HashSet();
+
+ Iterator it = entries.iterator();
+ while ( it.hasNext() )
+ {
+ Entry pre = (Entry) it.next();
+ Entry post = new LRUMapEntry( pre.getKey(), ( (LRUElementDescriptor) pre.getValue() ).getPayload() );
+ unWrapped.add( post );
+ }
+
+ return unWrapped;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.util.Map#keySet()
+ */
+ public Set keySet()
+ {
+ // TODO fix this, it needs to return the keys inside the wrappers.
+ return map.keySet();
}
}
Modified: jakarta/jcs/trunk/src/test-conf/log4j.properties
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test-conf/log4j.properties?view=diff&rev=519940&r1=519939&r2=519940
==============================================================================
--- jakarta/jcs/trunk/src/test-conf/log4j.properties (original)
+++ jakarta/jcs/trunk/src/test-conf/log4j.properties Mon Mar 19 06:18:22 2007
@@ -1,4 +1,4 @@
-log4j.rootCategory=INFO, stdout, logfile
+log4j.rootCategory=INFO, logfile
log4j.category.org.apache.jcs=INFO
log4j.category.org.apache.jcs.config=INFO
@@ -6,6 +6,7 @@
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=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
@@ -18,6 +19,7 @@
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=target/jcs.log
log4j.appender.logfile.MaxFileSize=5MB
+log4j.appender.logfile.Append=false
# Keep three backup files
log4j.appender.logfile.MaxBackupIndex=3
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
Modified: jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheConcurrentUnitTest.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheConcurrentUnitTest.java?view=diff&rev=519940&r1=519939&r2=519940
==============================================================================
--- jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheConcurrentUnitTest.java (original)
+++ jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheConcurrentUnitTest.java Mon Mar 19 06:18:22 2007
@@ -39,8 +39,9 @@
* Constructor for the TestDiskCache object.
*
* @param testName
+ * @throws Exception
*/
- public BlockDiskCacheConcurrentUnitTest( String testName )
+ public BlockDiskCacheConcurrentUnitTest( String testName ) throws Exception
{
super( testName );
}
@@ -60,11 +61,17 @@
* A unit test suite for JUnit
*
* @return The test suite
+ * @throws Exception
*/
- public static Test suite()
+ public static Test suite() throws Exception
{
ActiveTestSuite suite = new ActiveTestSuite();
+ JCS.setConfigFilename( "/TestBlockDiskCache.ccf" );
+ JCS.getInstance( "indexedRegion1" ).clear();
+ JCS.getInstance( "indexedRegion2" ).clear();
+ JCS.getInstance( "indexedRegion3" ).clear();
+
suite.addTest( new BlockDiskCacheConcurrentUnitTest( "testBlockDiskCache1" )
{
public void runTest()
Modified: jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheKeyStoreUnitTest.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheKeyStoreUnitTest.java?view=diff&rev=519940&r1=519939&r2=519940
==============================================================================
--- jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheKeyStoreUnitTest.java (original)
+++ jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheKeyStoreUnitTest.java Mon Mar 19 06:18:22 2007
@@ -9,8 +9,6 @@
* the License for the specific language governing permissions and limitations under the License.
*/
-import java.util.Random;
-
import junit.framework.TestCase;
/**
@@ -21,6 +19,7 @@
public class BlockDiskCacheKeyStoreUnitTest
extends TestCase
{
+ /** Directory name */
private String rootDirName = "target/test-sandbox/block";
/**
@@ -89,11 +88,12 @@
// DO WORK
int numElements = 1000;
- Random random = new Random( 89 );
+ //Random random = new Random( 89 );
for ( int i = 0; i < numElements; i++ )
{
- int blocks = random.nextInt( 10 );
+ int blocks = i;//random.nextInt( 10 );
keyStore.put( String.valueOf( i ), new int[blocks] );
+ keyStore.put( String.valueOf( i ), new int[i] );
}
System.out.println( "testSaveLoadKeys " + keyStore );
@@ -112,5 +112,10 @@
// VERIFY
assertEquals( "Wrong number of keys after loading", numElements, keyStore.size() );
+ for ( int i = 0; i < numElements; i++ )
+ {
+ int[] result = keyStore.get( String.valueOf( i ) );
+ assertEquals( "Wrong array returned.", i, result.length );
+ }
}
}
Modified: jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheRandomConcurrentTestUtil.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheRandomConcurrentTestUtil.java?view=diff&rev=519940&r1=519939&r2=519940
==============================================================================
--- jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheRandomConcurrentTestUtil.java (original)
+++ jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheRandomConcurrentTestUtil.java Mon Mar 19 06:18:22 2007
@@ -11,7 +11,6 @@
public class BlockDiskCacheRandomConcurrentTestUtil
extends TestCase
{
-
/**
* Constructor for the TestDiskCache object.
*
@@ -26,7 +25,7 @@
* Randomly adds items to cache, gets them, and removes them. The range
* count is more than the size of the memory cache, so items should spool to
* disk.
- *
+ * <p>
* @param region
* Name of the region to access
* @param range
@@ -52,7 +51,6 @@
jcs.put( key, data );
String value = (String) jcs.get( key );
assertEquals( data, value );
-
}
/**
@@ -62,5 +60,4 @@
{
JCS.setConfigFilename( "/TestBlockDiskCacheCon.ccf" );
}
-
}
Modified: jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheSameRegionConcurrentUnitTest.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheSameRegionConcurrentUnitTest.java?view=diff&rev=519940&r1=519939&r2=519940
==============================================================================
--- jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheSameRegionConcurrentUnitTest.java (original)
+++ jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheSameRegionConcurrentUnitTest.java Mon Mar 19 06:18:22 2007
@@ -97,11 +97,14 @@
}
/**
- * Test setup
+ * Test setup. Sets the config name and clears the region.
+ * <p>
+ * @throws Exception
*/
- public void setUp()
+ public void setUp() throws Exception
{
JCS.setConfigFilename( "/TestBlockDiskCacheCon.ccf" );
+ JCS.getInstance( "blockRegion4" ).clear();
}
/**
@@ -121,7 +124,7 @@
for ( int i = start; i <= end; i++ )
{
- jcs.put( i + ":key", region + " data " + i );
+ jcs.put( i + ":key", region + " data " + i + "-" + region );
}
// Test that all items are in cache
@@ -131,7 +134,7 @@
String key = i + ":key";
String value = (String) jcs.get( key );
- assertEquals( "Wrong value for key [" + key + "]", region + " data " + i, value );
+ assertEquals( "Wrong value for key [" + key + "]", region + " data " + i + "-" + region, value );
}
}
}
Modified: jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/indexed/IndexDiskCacheUnitTest.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/indexed/IndexDiskCacheUnitTest.java?view=diff&rev=519940&r1=519939&r2=519940
==============================================================================
--- jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/indexed/IndexDiskCacheUnitTest.java (original)
+++ jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/indexed/IndexDiskCacheUnitTest.java Mon Mar 19 06:18:22 2007
@@ -8,6 +8,8 @@
import org.apache.jcs.engine.ElementAttributes;
import org.apache.jcs.engine.behavior.ICacheElement;
import org.apache.jcs.engine.behavior.IElementAttributes;
+import org.apache.jcs.engine.control.group.GroupAttrName;
+import org.apache.jcs.engine.control.group.GroupId;
/**
* Tests for common functionality.
@@ -343,20 +345,22 @@
// verify that the recyle bin has the correct amount.
assertEquals( "The recycle bin should have the number removed.", numberToRemove, disk.getRecyleBinSize() );
-
- // add half as many as we removed. These should all use spots in the recycle bin.
+
+ // add half as many as we removed. These should all use spots in the recycle bin.
int numberToAdd = numberToRemove / 2;
for ( int i = 0; i < numberToAdd; i++ )
{
disk.doUpdate( elements[i] );
}
-
+
// verify that we used the correct number of spots
- assertEquals( "The recycle bin should have the number removed." + disk.getStats(), numberToAdd, disk.getRecyleCount() );
+ assertEquals( "The recycle bin should have the number removed." + disk.getStats(), numberToAdd, disk
+ .getRecyleCount() );
}
-
+
/**
- * Verify that the data size is as expected after a remove and after a put that should use the spots.
+ * Verify that the data size is as expected after a remove and after a put that should use the
+ * spots.
* <p>
* @throws IOException
* @throws InterruptedException
@@ -390,23 +394,131 @@
{
disk.doRemove( elements[i].getKey() );
}
-
+
long expectedSize = DiskTestObjectUtil.totalSize( elements, numberToRemove );
long resultSize = disk.getBytesFree();
System.out.println( "testBytesFreeSize stats " + disk.getStats() );
assertEquals( "Wrong bytes free size" + disk.getStats(), expectedSize, resultSize );
-
- // add half as many as we removed. These should all use spots in the recycle bin.
+
+ // add half as many as we removed. These should all use spots in the recycle bin.
int numberToAdd = numberToRemove / 2;
for ( int i = 0; i < numberToAdd; i++ )
{
disk.doUpdate( elements[i] );
- }
-
+ }
+
long expectedSize2 = DiskTestObjectUtil.totalSize( elements, numberToAdd );
long resultSize2 = disk.getBytesFree();
- assertEquals( "Wrong bytes free size" + disk.getStats(), expectedSize2, resultSize2 );
- }
+ assertEquals( "Wrong bytes free size" + disk.getStats(), expectedSize2, resultSize2 );
+ }
+
+ /**
+ * Add some items to the disk cache and then remove them one by one.
+ */
+ public void testRemove_PartialKey()
+ {
+ IndexedDiskCacheAttributes cattr = new IndexedDiskCacheAttributes();
+ cattr.setCacheName( "testRemove_PartialKey" );
+ cattr.setMaxKeySize( 100 );
+ cattr.setDiskPath( "target/test-sandbox/IndexDiskCacheUnitTest" );
+ IndexedDiskCache disk = new IndexedDiskCache( cattr );
+
+ disk.doRemoveAll();
+
+ int cnt = 25;
+ for ( int i = 0; i < cnt; i++ )
+ {
+ IElementAttributes eAttr = new ElementAttributes();
+ eAttr.setIsSpool( true );
+ ICacheElement element = new CacheElement( "testRemove_PartialKey", i + ":key", "data:" + i );
+ element.setElementAttributes( eAttr );
+ disk.doUpdate( element );
+ }
+
+ // verif each
+ for ( int i = 0; i < cnt; i++ )
+ {
+ ICacheElement element = disk.doGet( i + ":key" );
+ assertNotNull( "Shoulds have recevied an element.", element );
+ }
+
+ // remove each
+ for ( int i = 0; i < cnt; i++ )
+ {
+ disk.remove( i + ":" );
+ ICacheElement element = disk.doGet( i + ":key" );
+ assertNull( "Should not have recevied an element.", element );
+ }
+ }
+
+ /**
+ * Verify that group members are removed if we call remove with a group.
+ */
+ public void testRemove_Group()
+ {
+ // SETUP
+ IndexedDiskCacheAttributes cattr = new IndexedDiskCacheAttributes();
+ cattr.setCacheName( "testRemove_Group" );
+ cattr.setMaxKeySize( 100 );
+ cattr.setDiskPath( "target/test-sandbox/IndexDiskCacheUnitTest" );
+ IndexedDiskCache disk = new IndexedDiskCache( cattr );
+
+ disk.doRemoveAll();
+
+ String cacheName = "testRemove_Group_Region";
+ String groupName = "testRemove_Group";
+
+ int cnt = 25;
+ for ( int i = 0; i < cnt; i++ )
+ {
+ GroupAttrName groupAttrName = getGroupAttrName( cacheName, groupName, i + ":key" );
+
+ CacheElement element = new CacheElement( cacheName, groupAttrName, "data:" + i );
+
+ IElementAttributes eAttr = new ElementAttributes();
+ eAttr.setIsSpool( true );
+ element.setElementAttributes( eAttr );
+
+ disk.doUpdate( element );
+ }
+
+ // verify each
+ for ( int i = 0; i < cnt; i++ )
+ {
+ GroupAttrName groupAttrName = getGroupAttrName( cacheName, groupName, i + ":key" );
+ ICacheElement element = disk.doGet( groupAttrName );
+ assertNotNull( "Should have recevied an element.", element );
+ }
+
+ // DO WORK
+ // remove the group
+ GroupId gid = new GroupId( cacheName, groupName );
+ disk.remove( gid );
+
+ for ( int i = 0; i < cnt; i++ )
+ {
+ GroupAttrName groupAttrName = getGroupAttrName( cacheName, groupName, i + ":key" );
+ ICacheElement element = disk.doGet( groupAttrName );
+
+ // VERIFY
+ assertNull( "Should not have recevied an element.", element );
+ }
+
+ }
+
+ /**
+ * Internal method used for group functionality.
+ * <p>
+ * @param cacheName
+ * @param group
+ * @param name
+ * @return GroupAttrName
+ */
+ private GroupAttrName getGroupAttrName( String cacheName, String group, Object name )
+ {
+ GroupId gid = new GroupId( cacheName, group );
+ return new GroupAttrName( gid, name );
+ }
}
Modified: jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/indexed/IndexedDiskCacheOptimizationUnitTest.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/indexed/IndexedDiskCacheOptimizationUnitTest.java?view=diff&rev=519940&r1=519939&r2=519940
==============================================================================
--- jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/indexed/IndexedDiskCacheOptimizationUnitTest.java (original)
+++ jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/indexed/IndexedDiskCacheOptimizationUnitTest.java Mon Mar 19 06:18:22 2007
@@ -6,12 +6,13 @@
import org.apache.jcs.utils.timing.SleepUtil;
/**
+ * Tests for the optimization routine.
+ * <p>
* @author Aaron Smuts
*/
public class IndexedDiskCacheOptimizationUnitTest
extends TestCase
{
-
/**
* Set the optimize at remove count to 10. Add 20. Check the file size. Remove 10. Check the
* times optimized. Check the file size.
@@ -20,6 +21,7 @@
public void testBasicOptimization()
throws Exception
{
+ // SETUP
int removeCount = 50;
IndexedDiskCacheAttributes cattr = new IndexedDiskCacheAttributes();
@@ -46,23 +48,27 @@
System.out.println( "file sizeBeforeRemove " + sizeBeforeRemove );
System.out.println( "totalSize inserted " + DiskTestObjectUtil.totalSize( elements, numberToInsert ) );
+ // DO WORK
for ( int i = 0; i < removeCount; i++ )
{
disk.doRemove( new Integer( i ) );
}
- Thread.sleep( 500 );
- Thread.yield();
- Thread.sleep( 500 );
- SleepUtil.sleepAtLeast( 750 );
+ SleepUtil.sleepAtLeast( 1000 );
+ // VERIFY
long sizeAfterRemove = disk.getDataFileSize();
System.out.println( "file sizeAfterRemove " + sizeAfterRemove );
long expectedSizeAfterRemove = DiskTestObjectUtil.totalSize( elements, removeCount, elements.length );
System.out.println( "totalSize expected after remove " + expectedSizeAfterRemove );
+ // test is prone to failure for timing reasons.
+ if ( expectedSizeAfterRemove != sizeAfterRemove )
+ {
+ SleepUtil.sleepAtLeast( 2000 );
+ }
+
assertTrue( "The post optimization size should be smaller.", sizeAfterRemove < sizeBeforeRemove );
-
assertEquals( "The file size is not as expected size.", expectedSizeAfterRemove, sizeAfterRemove );
}
}
Modified: jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCacheShrinkUnitTest.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCacheShrinkUnitTest.java?view=diff&rev=519940&r1=519939&r2=519940
==============================================================================
--- jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCacheShrinkUnitTest.java (original)
+++ jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCacheShrinkUnitTest.java Mon Mar 19 06:18:22 2007
@@ -10,6 +10,7 @@
import org.apache.jcs.JCS;
import org.apache.jcs.access.exception.CacheException;
+import org.apache.jcs.utils.timing.SleepUtil;
/**
* Runs basic tests for the JDBC disk cache.
@@ -77,7 +78,7 @@
System.out.println( jcsExpire.getStats() );
// the shrinker is supposed to run every second
- Thread.sleep( 3000 );
+ SleepUtil.sleepAtLeast( 3000 );
System.out.println( jcsExpire.getStats() );
@@ -113,7 +114,7 @@
System.out.println( jcs.getStats() );
- Thread.sleep( 1000 );
+ SleepUtil.sleepAtLeast( 1000 );
System.out.println( jcs.getStats() );
@@ -166,7 +167,7 @@
System.out.println( jcs.getStats() );
- Thread.sleep( 1000 );
+ SleepUtil.sleepAtLeast( 1000 );
System.out.println( jcs.getStats() );
Modified: jakarta/jcs/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/xdocs/changes.xml?view=diff&rev=519940&r1=519939&r2=519940
==============================================================================
--- jakarta/jcs/trunk/xdocs/changes.xml (original)
+++ jakarta/jcs/trunk/xdocs/changes.xml Mon Mar 19 06:18:22 2007
@@ -6,10 +6,18 @@
<body>
<release version="1.2.7.9.3" date="in CVS">
+ <action dev="asmuts" type="fix" issue="JCS-15"
+ due-to="Kevin Preece">
+ Fixed partial key and group id removal bug in indexed disk cache.
+ </action>
<action dev="asmuts" type="fix" issue="JCS-20"
due-to="Alistair Forbes">
Fixed partial key removal SQL syntax problem with the
JDBC disk cache.
+ </action>
+ <action dev="asmuts" type="fix" issue="JCS-21"
+ due-to="Michael Stevens">
+ Fixed a few minor missing locks.
</action>
</release>
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.