You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jcs-dev@jakarta.apache.org by as...@apache.org on 2008/04/11 20:43:31 UTC

svn commit: r647264 [1/6] - in /jakarta/jcs/trunk: ./ src/java/org/apache/jcs/access/ src/java/org/apache/jcs/access/behavior/ src/java/org/apache/jcs/auxiliary/ src/java/org/apache/jcs/auxiliary/disk/ src/java/org/apache/jcs/auxiliary/lateral/ src/jav...

Author: asmuts
Date: Fri Apr 11 11:43:26 2008
New Revision: 647264

URL: http://svn.apache.org/viewvc?rev=647264&view=rev
Log:
Committing a patch by Chris Fairbanks.  It allows clients to retrieve multple items from the cache with a single call.

Added:
    jakarta/jcs/trunk/ant_eclipse_jar_install.xml
Modified:
    jakarta/jcs/trunk/pom.xml
    jakarta/jcs/trunk/project.xml
    jakarta/jcs/trunk/src/java/org/apache/jcs/access/CacheAccess.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/access/behavior/ICacheAccess.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/AuxiliaryCache.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/AbstractDiskCache.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/LateralCache.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/LateralCacheNoWait.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/LateralCacheNoWaitFacade.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/behavior/ILateralCacheService.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPSender.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPService.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/RemoteCache.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/RemoteCacheNoWait.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/RemoteCacheNoWaitFacade.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/ZombieRemoteCacheService.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/behavior/IRemoteCacheService.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServer.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/engine/ZombieCacheService.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/engine/behavior/ICache.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/engine/behavior/ICacheService.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/engine/control/CompositeCache.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/engine/memory/AbstractMemoryCache.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/engine/memory/behavior/IMemoryCache.java
    jakarta/jcs/trunk/src/test-conf/TestTCPLateralIssueRemoveCache.ccf
    jakarta/jcs/trunk/src/test-conf/TestTCPLateralRemoveFilter.ccf
    jakarta/jcs/trunk/src/test/org/apache/jcs/access/CacheAccessUnitTest.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/access/TestCacheAccess.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/AuxiliaryCacheMockImpl.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/block/BlockDiskCacheConcurrentUnitTest.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/IndexedDiskCacheConcurrentNoDeadLockUnitTest.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/indexed/IndexedDiskCacheConcurrentUnitTest.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/indexed/IndexedDiskCacheNoMemoryUnitTest.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/indexed/IndexedDiskCacheSameRegionConcurrentUnitTest.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCacheUnitTest.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/jdbc/hsql/HSQLDiskCacheConcurrentUnitTest.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/jdbc/hsql/HSQLDiskCacheUnitTest.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/jdbc/mysql/MySQLDiskCacheHsqlBackedUnitTest.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPFilterRemoveHashCodeUnitTest.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPIssueRemoveOnPutUnitTest.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/remote/RemoteCacheClientMockImpl.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/remote/RemoteCacheNoWaitUnitTest.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/remote/RemoteCacheServiceMockImpl.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/remote/server/BasicRemoteCacheClientServerUnitTest.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/engine/control/CompositeCacheDiskUsageUnitTest.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/engine/memory/MemoryCacheMockImpl.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/engine/memory/lru/LRUMemoryCacheConcurrentUnitTest.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/engine/memory/mru/MRUMemoryCacheUnitTest.java

Added: jakarta/jcs/trunk/ant_eclipse_jar_install.xml
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/ant_eclipse_jar_install.xml?rev=647264&view=auto
==============================================================================
--- jakarta/jcs/trunk/ant_eclipse_jar_install.xml (added)
+++ jakarta/jcs/trunk/ant_eclipse_jar_install.xml Fri Apr 11 11:43:26 2008
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<project name="ant_eclipse" basedir="." default="default">
+
+  <!-- bring in the environmental properties -->
+  <property environment="env"/>
+  <property name="maven.home" value="${env.MAVEN_HOME}"/>
+
+  <!-- make sure we have maven -->
+  <target name="check-env" description="Check if environment variables are set">
+    <echo>maven.home = ${maven.home}</echo>
+    <fail unless="env.MAVEN_HOME" message="You MUST set MAVEN_HOME first"/>
+  </target>
+
+  <target name="default" depends="check-env">
+  
+       <condition property="maven.script" value="maven.bat">
+         <and>
+            <os family="windows" />
+            <equals arg1="${maven.script}" arg2="$${maven.script}" />
+          <not>
+            <isset property="cygwin.home" />
+          </not>
+        </and>
+        </condition>
+        
+       <condition property="maven.script" value="maven">
+          <equals arg1="${maven.script}" arg2="$${maven.script}" />
+       </condition>  
+  
+    <!-- call maven jar:install -Dtest=Unit -->
+    <exec executable="${maven.script}" failonerror="true">
+      <arg value="jar:install"/>
+      <arg value="-Dtest=Unit"/>
+    </exec>
+    
+  </target>
+
+</project>

Modified: jakarta/jcs/trunk/pom.xml
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/pom.xml?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/pom.xml (original)
+++ jakarta/jcs/trunk/pom.xml Fri Apr 11 11:43:26 2008
@@ -36,7 +36,7 @@
   <groupId>org.apache.jcs</groupId>
   <artifactId>jcs</artifactId>
   <packaging>pom</packaging>
-  <version>1.3</version>
+  <version>1.3.1.0-RC</version>
   <name>Jakarta JCS</name>
   <url>http://jakarta.apache.org/jcs/</url>
   <inceptionYear>2002</inceptionYear>

Modified: jakarta/jcs/trunk/project.xml
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/project.xml?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/project.xml (original)
+++ jakarta/jcs/trunk/project.xml Fri Apr 11 11:43:26 2008
@@ -23,7 +23,7 @@
 	<pomVersion>3</pomVersion>
 	<name>JCS</name>
 	<id>jcs</id>
-	<currentVersion>1.3</currentVersion>
+	<currentVersion>1.3.1.0-RC</currentVersion>
 	<organization>
 		<name>Apache Software Foundation</name>
 		<url>http://jakarta.apache.org/</url>

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/access/CacheAccess.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/access/CacheAccess.java?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/access/CacheAccess.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/access/CacheAccess.java Fri Apr 11 11:43:26 2008
@@ -21,6 +21,8 @@
 
 import java.io.IOException;
 import java.io.Serializable;
+import java.util.Map;
+import java.util.Set;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -202,7 +204,7 @@
      * This method is most useful if you want to determine things such as the how long the element
      * has been in the cache.
      * <p>
-     * The last access time in teh ElementAttributes should be current.
+     * The last access time in the ElementAttributes should be current.
      * <p>
      * @param name Key the object is stored as
      * @return The ICacheElement if the object is found or null
@@ -213,6 +215,28 @@
     }
 
     /**
+     * Get multiple elements from the cache based on a set of cache keys.
+     * <p>
+     * This method returns the ICacheElement wrapper which provides access to element info and other
+     * attributes.
+     * <p>
+     * This returns a reference to the wrapper. Any modifications will be reflected in the cache. No
+     * defensive copy is made.
+     * <p>
+     * This method is most useful if you want to determine things such as the how long the element
+     * has been in the cache.
+     * <p>
+     * The last access time in the ElementAttributes should be current.
+     * <p>
+     * @param names set of Object cache keys
+     * @return a map of Object key to ICacheElement element, or empty map if none of the keys are present
+     */
+    public Map getCacheElements( Set names )
+    {
+        return this.cacheControl.getMultiple( names );
+    }
+
+    /**
      * Place a new object in the cache, associated with key name. If there is currently an object
      * associated with name in the region an ObjectExistsException is thrown. Names are scoped to a
      * region so they must be unique within the region they are placed.
@@ -377,7 +401,7 @@
      * TODO is should be renamed "setDefaultElementAttributes"
      * <p>
      * @deprecated As of release 1.3
-     * @see setDefaultElementAttributes
+     * @see #setDefaultElementAttributes(IElementAttributes)
      * @param attr New attributes for this region.
      * @exception CacheException
      * @exception InvalidHandleException
@@ -417,6 +441,7 @@
         throws CacheException, InvalidHandleException
     {
         ICacheElement element = this.cacheControl.get( (Serializable) name );
+
         if ( element == null )
         {
             throw new InvalidHandleException( "Object for name [" + name + "] is not in the cache" );
@@ -426,8 +451,8 @@
         // i.e. don't do this:
         // element.setElementAttributes( attr );
         // Another reason to call put is to force the changes to be distributed.
-        put( element.getKey(), element.getVal(), attr );
 
+        put( element.getKey(), element.getVal(), attr );
     }
 
     /**
@@ -437,7 +462,7 @@
      * This was confusing, so I created a new method with a clear name.
      * <p>
      * @deprecated As of release 1.3
-     * @see getDefaultElementAttributes
+     * @see #getDefaultElementAttributes
      * @return Attributes for this region
      * @exception CacheException
      */

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/access/behavior/ICacheAccess.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/access/behavior/ICacheAccess.java?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/access/behavior/ICacheAccess.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/access/behavior/ICacheAccess.java Fri Apr 11 11:43:26 2008
@@ -19,7 +19,11 @@
  * under the License.
  */
 
+import java.util.Map;
+import java.util.Set;
+
 import org.apache.jcs.access.exception.CacheException;
+import org.apache.jcs.engine.behavior.ICacheElement;
 import org.apache.jcs.engine.behavior.ICompositeCacheAttributes;
 import org.apache.jcs.engine.behavior.IElementAttributes;
 
@@ -68,11 +72,47 @@
         throws CacheException;
 
     /**
+     * This method returns the ICacheElement wrapper which provides access to element info and other
+     * attributes.
+     * <p>
+     * This returns a reference to the wrapper. Any modifications will be reflected in the cache. No
+     * defensive copy is made.
+     * <p>
+     * This method is most useful if you want to determine things such as the how long the element
+     * has been in the cache.
+     * <p>
+     * The last access time in the ElementAttributes should be current.
+     * <p>
+     * @param name Key the object is stored as
+     * @return The ICacheElement if the object is found or null
+     */
+    ICacheElement getCacheElement( Object name );
+
+    /**
+     * Get multiple elements from the cache based on a set of cache keys.
+     * <p>
+     * This method returns the ICacheElement wrapper which provides access to element info and other
+     * attributes.
+     * <p>
+     * This returns a reference to the wrapper. Any modifications will be reflected in the cache. No
+     * defensive copy is made.
+     * <p>
+     * This method is most useful if you want to determine things such as the how long the element
+     * has been in the cache.
+     * <p>
+     * The last access time in the ElementAttributes should be current.
+     * <p>
+     * @param names set of Object cache keys
+     * @return a map of Object key to ICacheElement element, or empty map if none of the keys are present
+     */
+    Map getCacheElements( Set names );
+
+    /**
      * Removes an item or all items. Should be called remove.
      * <p>
      * @throws CacheException
      * @deprecated
-     * @see #remove
+     * @see #remove()
      */
     void destroy()
         throws CacheException;
@@ -90,7 +130,7 @@
      * @param name
      * @throws CacheException
      * @deprecated
-     * @see #remove
+     * @see #remove(Object)
      */
     void destroy( Object name )
         throws CacheException;
@@ -114,20 +154,20 @@
      * Only object loaded after the reset will use the new defaults. If no name
      * argument is provided, the reset is applied to the region.
      * <p>
-     * @param attr
+     * @param attributes
      * @throws CacheException
      */
-    void resetElementAttributes( IElementAttributes attr )
+    void resetElementAttributes( IElementAttributes attributes )
         throws CacheException;
 
     /**
      * Reset the attributes on the object matching this key name.
      * <p>
      * @param name
-     * @param attr
+     * @param attributes
      * @throws CacheException
      */
-    void resetElementAttributes( Object name, IElementAttributes attr )
+    void resetElementAttributes( Object name, IElementAttributes attributes )
         throws CacheException;
 
     /**

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/AuxiliaryCache.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/AuxiliaryCache.java?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/AuxiliaryCache.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/AuxiliaryCache.java Fri Apr 11 11:43:26 2008
@@ -20,11 +20,9 @@
  */
 
 import java.io.IOException;
-import java.io.Serializable;
 import java.util.Set;
 
 import org.apache.jcs.engine.behavior.ICache;
-import org.apache.jcs.engine.behavior.ICacheElement;
 import org.apache.jcs.engine.stats.behavior.IStats;
 
 /**
@@ -38,83 +36,24 @@
     extends ICache
 {
     /**
-     * Puts an item to the cache.
-     * @param ce
-     * @throws IOException
-     */
-    public void update( ICacheElement ce )
-        throws IOException;
-
-    /**
-     * Gets an item from the cache.
-     * @param key
-     * @return
-     * @throws IOException
-     */
-    public ICacheElement get( Serializable key )
-        throws IOException;
-
-    /**
-     * Removes an item from the cache.
-     * @param key
-     * @return
-     * @throws IOException
-     */
-    public boolean remove( Serializable key )
-        throws IOException;
-
-    /**
-     * Removes all cached items from the cache.
-     * @throws IOException
-     */
-    public void removeAll()
-        throws IOException;
-
-    /**
-     * Prepares for shutdown.
-     * @throws IOException
-     */
-    public void dispose()
-        throws IOException;
-
-    /**
-     * Returns the current cache size.
-     * @return
-     */
-    public int getSize();
-
-    /**
-     * Returns the cache status.
-     * @return
-     */
-    public int getStatus();
-
-    /**
-     * Returns the cache name.
-     * @return
-     */
-    public String getCacheName();
-
-    /**
      * Gets the set of keys of objects currently in the group
      * @param group
      * @return a set of group keys
      * @throws IOException
      */
-    public Set getGroupKeys( String group )
+    Set getGroupKeys( String group )
         throws IOException;
 
     /**
-     * Returns the historical and statistical data for a region's auxiliary cache.
-     * @return
+     * @return the historical and statistical data for a region's auxiliary cache.
      */
-    public IStats getStatistics();
+    IStats getStatistics();
 
     /**
      * This returns the generic attributes for an auxiliary cache. Most implementations will cast
      * this to a more specific type.
      * <p>
-     * @return
+     * @return the attributes for the auxiliary cache
      */
-    public AuxiliaryCacheAttributes getAuxiliaryCacheAttributes();
+    AuxiliaryCacheAttributes getAuxiliaryCacheAttributes();
 }

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?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- 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 Fri Apr 11 11:43:26 2008
@@ -24,6 +24,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -299,6 +300,36 @@
         }
 
         return null;
+    }
+
+    /**
+     * Gets multiple items from the cache based on the given set of keys.
+     * <p>
+     * @param keys
+     * @return a map of Serializable key to ICacheElement element, or an empty map if there is no data in cache for any of these keys
+     */
+    public final Map getMultiple( Set keys )
+    {
+        Map elements = new HashMap();
+
+        if ( keys != null && !keys.isEmpty() )
+        {
+            Iterator iterator = keys.iterator();
+
+            while ( iterator.hasNext() )
+            {
+                Serializable key = (Serializable) iterator.next();
+
+                ICacheElement element = get( key );
+
+                if ( element != null )
+                {
+                    elements.put( key, element );
+                }
+            }
+        }
+
+        return elements;
     }
 
     /**

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/LateralCache.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/LateralCache.java?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/LateralCache.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/LateralCache.java Fri Apr 11 11:43:26 2008
@@ -21,6 +21,9 @@
 
 import java.io.IOException;
 import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.commons.logging.Log;
@@ -138,6 +141,38 @@
             handleException( e, "Failed to get " + key + " from " + this.cattr.getCacheName() );
         }
         return obj;
+    }
+
+    /**
+     * Gets multiple items from the cache based on the given set of keys.
+     * <p>
+     * @param keys
+     * @return a map of Serializable key to ICacheElement element, or an empty map if there is no data in cache for any of these keys
+     * @throws IOException 
+     */
+    public Map getMultiple( Set keys )
+        throws IOException
+    {
+        Map elements = new HashMap();
+
+        if ( keys != null && !keys.isEmpty() )
+        {
+            Iterator iterator = keys.iterator();
+
+            while ( iterator.hasNext() )
+            {
+                Serializable key = (Serializable) iterator.next();
+
+                ICacheElement element = get( key );
+
+                if ( element != null )
+                {
+                    elements.put( key, element );
+                }
+            }
+        }
+
+        return elements;
     }
 
     /**

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/LateralCacheNoWait.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/LateralCacheNoWait.java?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/LateralCacheNoWait.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/LateralCacheNoWait.java Fri Apr 11 11:43:26 2008
@@ -24,7 +24,10 @@
 import java.rmi.UnmarshalException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.commons.logging.Log;
@@ -148,6 +151,36 @@
             }
         }
         return null;
+    }
+
+    /**
+     * Gets multiple items from the cache based on the given set of keys.
+     * <p>
+     * @param keys
+     * @return a map of Serializable key to ICacheElement element, or an empty map if there is no data in cache for any of these keys
+     */
+    public Map getMultiple( Set keys )
+    {
+        Map elements = new HashMap();
+
+        if ( keys != null && !keys.isEmpty() )
+        {
+            Iterator iterator = keys.iterator();
+
+            while ( iterator.hasNext() )
+            {
+                Serializable key = (Serializable) iterator.next();
+
+                ICacheElement element = get( key );
+
+                if ( element != null )
+                {
+                    elements.put( key, element );
+                }
+            }
+        }
+
+        return elements;
     }
 
     public Set getGroupKeys( String groupName )

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/LateralCacheNoWaitFacade.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/LateralCacheNoWaitFacade.java?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/LateralCacheNoWaitFacade.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/LateralCacheNoWaitFacade.java Fri Apr 11 11:43:26 2008
@@ -23,7 +23,10 @@
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.HashSet;
 
@@ -171,6 +174,36 @@
             return null;
         }
         return null;
+    }
+
+    /**
+     * Gets multiple items from the cache based on the given set of keys.
+     * <p>
+     * @param keys
+     * @return a map of Serializable key to ICacheElement element, or an empty map if there is no data in cache for any of these keys
+     */
+    public Map getMultiple( Set keys )
+    {
+        Map elements = new HashMap();
+
+        if ( keys != null && !keys.isEmpty() )
+        {
+            Iterator iterator = keys.iterator();
+
+            while ( iterator.hasNext() )
+            {
+                Serializable key = (Serializable) iterator.next();
+
+                ICacheElement element = get( key );
+
+                if ( element != null )
+                {
+                    elements.put( key, element );
+                }
+            }
+        }
+
+        return elements;
     }
 
     /*

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/behavior/ILateralCacheService.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/behavior/ILateralCacheService.java?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/behavior/ILateralCacheService.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/behavior/ILateralCacheService.java Fri Apr 11 11:43:26 2008
@@ -26,9 +26,7 @@
 import org.apache.jcs.engine.behavior.ICacheElement;
 import org.apache.jcs.engine.behavior.ICacheService;
 
-/**
- * Used to retrieve and update the lateral cache.
- */
+/** Used to retrieve and update the lateral cache. */
 public interface ILateralCacheService
     extends ICacheService
 {
@@ -39,7 +37,7 @@
      * @param requesterId
      * @throws IOException
      */
-    public void update( ICacheElement item, long requesterId )
+    void update( ICacheElement item, long requesterId )
         throws IOException;
 
     /**
@@ -50,7 +48,7 @@
      * @param requesterId
      * @throws IOException
      */
-    public void remove( String cacheName, Serializable key, long requesterId )
+    void remove( String cacheName, Serializable key, long requesterId )
         throws IOException;
 
     /**
@@ -60,13 +58,13 @@
      * @param requesterId
      * @throws IOException
      */
-    public void removeAll( String cacheName, long requesterId )
+    void removeAll( String cacheName, long requesterId )
         throws IOException;
 
     /**
      * @param cacheName
      * @param groupName
-     * @return
+     * @return keys
      */
-    public Set getGroupKeys( String cacheName, String groupName );
+    Set getGroupKeys( String cacheName, String groupName );
 }

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPSender.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPSender.java?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPSender.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPSender.java Fri Apr 11 11:43:26 2008
@@ -41,22 +41,31 @@
  */
 public class LateralTCPSender
 {
+    /** The logger */
     private final static Log log = LogFactory.getLog( LateralTCPSender.class );
 
+    /** Config */
     private ITCPLateralCacheAttributes tcpLateralCacheAttributes;
 
+    /** The hostname of the remote server. */
     private String remoteHost;
 
+    /** The address of the server */
     private InetAddress address;
 
+    /** The port the server is listening to. */
     int port = 1111;
 
+    /** The stream from the server connection. */
     private ObjectOutputStream oos;
 
+    /** The socket connection with the server. */
     private Socket socket;
 
+    /** counter, for periodic OOS reset. */
     int counter = 0;
 
+    /** how many messages sent */
     private int sendCnt = 0;
 
     // reset the ObjectOutputStream every 70 calls
@@ -67,6 +76,7 @@
     // a stream cached version.
     // I can't replicate an issue that was reported, so I'm not changing the
     // reset frequency for now.
+    /** How often we need to reset the stream. */
     private final static int RESET_FREQUENCY = 70;
 
     /**
@@ -250,7 +260,7 @@
      * laterals, then you have to make 10 failed gets to find out none of the caches have the item.
      * <p>
      * @param led
-     * @return
+     * @return ICacheElement
      * @throws IOException
      */
     public ICacheElement sendAndReceive( LateralElementDescriptor led )

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPService.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPService.java?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPService.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPService.java Fri Apr 11 11:43:26 2008
@@ -23,6 +23,9 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.commons.logging.Log;
@@ -235,6 +238,39 @@
             // nothing needs to be done
             return null;
         }
+    }
+
+    /**
+     * Gets multiple items from the cache based on the given set of keys.
+     * <p>
+     * @param cacheName 
+     * @param keys
+     * @return a map of Serializable key to ICacheElement element, or an empty map if there is no data in cache for any of these keys
+     * @throws IOException 
+     */
+    public Map getMultiple( String cacheName, Set keys )
+        throws IOException
+    {
+        Map elements = new HashMap();
+
+        if ( keys != null && !keys.isEmpty() )
+        {
+            Iterator iterator = keys.iterator();
+
+            while ( iterator.hasNext() )
+            {
+                Serializable key = (Serializable) iterator.next();
+
+                ICacheElement element = get( cacheName, key );
+
+                if ( element != null )
+                {
+                    elements.put( key, element );
+                }
+            }
+        }
+
+        return elements;
     }
 
     /**

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/RemoteCache.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/RemoteCache.java?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/RemoteCache.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/RemoteCache.java Fri Apr 11 11:43:26 2008
@@ -26,6 +26,9 @@
 import java.net.Socket;
 import java.rmi.server.RMISocketFactory;
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.commons.logging.Log;
@@ -204,8 +207,7 @@
 
                     // convert so we don't have to know about the object on the
                     // other end.
-                    serialized = SerializationConversionUtil
-                        .getSerializedCacheElement( ce, this.elementSerializer );
+                    serialized = SerializationConversionUtil.getSerializedCacheElement( ce, this.elementSerializer );
 
                     remote.update( serialized, getListenerId() );
                 }
@@ -281,6 +283,38 @@
     }
 
     /**
+     * Gets multiple items from the cache based on the given set of keys.
+     * <p>
+     * @param keys
+     * @return a map of Serializable key to ICacheElement element, or an empty map if there is no data in cache for any of these keys
+     * @throws IOException 
+     */
+    public Map getMultiple( Set keys )
+        throws IOException
+    {
+        Map elements = new HashMap();
+
+        if ( keys != null && !keys.isEmpty() )
+        {
+            Iterator iterator = keys.iterator();
+
+            while ( iterator.hasNext() )
+            {
+                Serializable key = (Serializable) iterator.next();
+
+                ICacheElement element = get( key );
+
+                if ( element != null )
+                {
+                    elements.put( key, element );
+                }
+            }
+        }
+
+        return elements;
+    }
+
+    /**
      * This allows gets to timeout in case of remote server machine shutdown.
      * <p>
      * @param key
@@ -504,7 +538,7 @@
         {
             se = new StatElement();
             se.setName( "Zombie Queue Size" );
-            se.setData( "" + ((ZombieRemoteCacheService)remote).getQueueSize() );
+            se.setData( "" + ( (ZombieRemoteCacheService) remote ).getQueueSize() );
             elems.add( se );
         }
 
@@ -554,11 +588,11 @@
     {
         if ( this.remote != null && this.remote instanceof ZombieRemoteCacheService )
         {
-            ZombieRemoteCacheService zombie = (ZombieRemoteCacheService)this.remote;
+            ZombieRemoteCacheService zombie = (ZombieRemoteCacheService) this.remote;
             this.remote = remote;
             try
             {
-                zombie.propagateEvents(  remote );
+                zombie.propagateEvents( remote );
             }
             catch ( Exception e )
             {
@@ -590,10 +624,10 @@
     private void handleException( Exception ex, String msg )
         throws IOException
     {
-        log.error( "Disabling remote cache due to error: " + msg , ex );
+        log.error( "Disabling remote cache due to error: " + msg, ex );
 
         // we should not switch if the existing is a zombie.
-        if ( remote == null || !(remote instanceof ZombieRemoteCacheService) )
+        if ( remote == null || !( remote instanceof ZombieRemoteCacheService ) )
         {
             // TODO make configurable
             remote = new ZombieRemoteCacheService( irca.getZombieQueueMaxSize() );

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/RemoteCacheNoWait.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/RemoteCacheNoWait.java?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/RemoteCacheNoWait.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/RemoteCacheNoWait.java Fri Apr 11 11:43:26 2008
@@ -24,7 +24,9 @@
 import java.rmi.UnmarshalException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.commons.logging.Log;
@@ -64,18 +66,28 @@
 public class RemoteCacheNoWait
     implements AuxiliaryCache
 {
+    /** For serialization. Don't change. */
     private static final long serialVersionUID = -3104089136003714717L;
 
+    /** log instance */
     private final static Log log = LogFactory.getLog( RemoteCacheNoWait.class );
 
+    /** The remote cache client */
     private final IRemoteCacheClient cache;
 
+    /** Event queue for queueing up calls like put and remove. */
     private ICacheEventQueue cacheEventQueue;
 
+    /** how many times get has been called. */
     private int getCount = 0;
 
+    /** how many times getMultiple has been called. */
+    private int getMultipleCount = 0;
+
+    /** how many times remove has been called. */
     private int removeCount = 0;
 
+    /** how many times put has been called. */
     private int putCount = 0;
 
     /**
@@ -87,10 +99,10 @@
     public RemoteCacheNoWait( IRemoteCacheClient cache )
     {
         this.cache = cache;
-        CacheEventQueueFactory fact = new CacheEventQueueFactory();
-        this.cacheEventQueue = fact.createCacheEventQueue( new CacheAdaptor( cache ), cache.getListenerId(), cache.getCacheName(),
-                                             cache.getAuxiliaryCacheAttributes().getEventQueuePoolName(), cache
-                                                 .getAuxiliaryCacheAttributes().getEventQueueTypeFactoryCode() );
+        CacheEventQueueFactory factory = new CacheEventQueueFactory();
+        this.cacheEventQueue = factory.createCacheEventQueue( new CacheAdaptor( cache ), cache.getListenerId(), cache
+            .getCacheName(), cache.getAuxiliaryCacheAttributes().getEventQueuePoolName(), cache
+            .getAuxiliaryCacheAttributes().getEventQueueTypeFactoryCode() );
 
         if ( cache.getStatus() == CacheConstants.STATUS_ERROR )
         {
@@ -104,19 +116,19 @@
      * (non-Javadoc)
      * @see org.apache.jcs.engine.behavior.ICache#update(org.apache.jcs.engine.behavior.ICacheElement)
      */
-    public void update( ICacheElement ce )
+    public void update( ICacheElement element )
         throws IOException
     {
         putCount++;
         try
         {
-            cacheEventQueue.addPutEvent( ce );
+            cacheEventQueue.addPutEvent( element );
         }
-        catch ( IOException ex )
+        catch ( IOException e )
         {
-            log.error( "Problem adding putEvent to queue.", ex );
+            log.error( "Problem adding putEvent to queue.", e );
             cacheEventQueue.destroy();
-            throw ex;
+            throw e;
         }
     }
 
@@ -124,7 +136,7 @@
      * Synchronously reads from the remote cache.
      * <p>
      * @param key
-     * @return
+     * @return element from the remote cache, or null if not present
      * @throws IOException
      */
     public ICacheElement get( Serializable key )
@@ -141,6 +153,7 @@
             {
                 log.debug( "Retrying the get owing to UnmarshalException..." );
             }
+
             try
             {
                 return cache.get( key );
@@ -160,9 +173,61 @@
             // Since get does not use the queue, I dont want to killing the queue.
             throw ex;
         }
+
         return null;
     }
 
+    /**
+     * Gets multiple items from the cache based on the given set of keys.  
+     * Sends the getMultiple request on to the server rather than looping through the requested keys.
+     * <p>
+     * @param keys
+     * @return a map of Serializable key to ICacheElement element, or an empty map if there is no data in cache for any of these keys
+     * @throws IOException 
+     */
+    public Map getMultiple( Set keys )
+        throws IOException
+    {
+        getMultipleCount++;
+        try
+        {
+            return cache.getMultiple( keys );
+        }
+        catch ( UnmarshalException ue )
+        {
+            if ( log.isDebugEnabled() )
+            {
+                log.debug( "Retrying the getMultiple owing to UnmarshalException..." );
+            }
+
+            try
+            {
+                return cache.getMultiple( keys );
+            }
+            catch ( IOException ex )
+            {
+                if ( log.isInfoEnabled() )
+                {
+                    log.info( "Failed in retrying the getMultiple for the second time. " + ex.getMessage() );
+                }
+            }
+        }
+        catch ( IOException ex )
+        {
+            // We don't want to destroy the queue on a get failure.
+            // The RemoteCache will Zombie and queue.
+            // Since get does not use the queue, I dont want to killing the queue.
+            throw ex;
+        }
+
+        return new HashMap();
+    }
+
+    /**
+     * @param groupName 
+     * @return the keys for the group name
+     * @throws IOException 
+     */
     public Set getGroupKeys( String groupName )
         throws IOException
     {
@@ -173,7 +238,7 @@
      * Adds a remove request to the remote cache.
      * <p>
      * @param key
-     * @return
+     * @return if this was successful
      * @throws IOException
      */
     public boolean remove( Serializable key )
@@ -184,11 +249,11 @@
         {
             cacheEventQueue.addRemoveEvent( key );
         }
-        catch ( IOException ex )
+        catch ( IOException e )
         {
-            log.error( "Problem adding RemoveEvent to queue.", ex );
+            log.error( "Problem adding RemoveEvent to queue.", e );
             cacheEventQueue.destroy();
-            throw ex;
+            throw e;
         }
         return false;
     }
@@ -205,11 +270,11 @@
         {
             cacheEventQueue.addRemoveAllEvent();
         }
-        catch ( IOException ex )
+        catch ( IOException e )
         {
-            log.error( "Problem adding RemoveAllEvent to queue.", ex );
+            log.error( "Problem adding RemoveAllEvent to queue.", e );
             cacheEventQueue.destroy();
-            throw ex;
+            throw e;
         }
     }
 
@@ -220,9 +285,9 @@
         {
             cacheEventQueue.addDisposeEvent();
         }
-        catch ( IOException ex )
+        catch ( IOException e )
         {
-            log.error( "Problem adding DisposeEvent to queue.", ex );
+            log.error( "Problem adding DisposeEvent to queue.", e );
             cacheEventQueue.destroy();
         }
     }
@@ -293,9 +358,9 @@
         ICacheEventQueue previousQueue = cacheEventQueue;
 
         CacheEventQueueFactory fact = new CacheEventQueueFactory();
-        this.cacheEventQueue = fact.createCacheEventQueue( new CacheAdaptor( cache ), cache.getListenerId(), cache.getCacheName(),
-                                             cache.getAuxiliaryCacheAttributes().getEventQueuePoolName(), cache
-                                                 .getAuxiliaryCacheAttributes().getEventQueueTypeFactoryCode() );
+        this.cacheEventQueue = fact.createCacheEventQueue( new CacheAdaptor( cache ), cache.getListenerId(), cache
+            .getCacheName(), cache.getAuxiliaryCacheAttributes().getEventQueuePoolName(), cache
+            .getAuxiliaryCacheAttributes().getEventQueueTypeFactoryCode() );
 
         if ( previousQueue.isWorking() )
         {
@@ -311,7 +376,7 @@
     /**
      * This is temporary. It allows the manager to get the lister.
      * <p>
-     * @return
+     * @return the instance of the remote cache client used by this object
      */
     protected IRemoteCacheClient getRemoteCache()
     {
@@ -357,9 +422,8 @@
         return getStatistics().toString();
     }
 
-    /*
-     * (non-Javadoc)
-     * @see org.apache.jcs.auxiliary.AuxiliaryCache#getStatistics()
+    /**
+     * @return statistics about this communication 
      */
     public IStats getStatistics()
     {
@@ -413,6 +477,11 @@
         se = new StatElement();
         se.setName( "Get Count" );
         se.setData( "" + this.getCount );
+        elems.add( se );
+
+        se = new StatElement();
+        se.setName( "GetMultiple Count" );
+        se.setData( "" + this.getMultipleCount );
         elems.add( se );
 
         se = new StatElement();

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/RemoteCacheNoWaitFacade.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/RemoteCacheNoWaitFacade.java?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/RemoteCacheNoWaitFacade.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/RemoteCacheNoWaitFacade.java Fri Apr 11 11:43:26 2008
@@ -23,8 +23,10 @@
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.commons.logging.Log;
@@ -50,18 +52,22 @@
 public class RemoteCacheNoWaitFacade
     implements AuxiliaryCache
 {
+    /** For serialization. Don't change.*/
     private static final long serialVersionUID = -4529970797620747110L;
 
+    /** log instance */
     private final static Log log = LogFactory.getLog( RemoteCacheNoWaitFacade.class );
 
     /** The connection to a remote server, or a zombie. */
     public RemoteCacheNoWait[] noWaits;
 
+    /** The cache name */
     private String cacheName;
 
     /** holds failover and cluster information */
     protected RemoteCacheAttributes remoteCacheAttributes;
 
+    /** A cache manager */
     private ICompositeCacheManager cacheMgr;
 
     /**
@@ -92,7 +98,7 @@
      * @param cacheMgr
      */
     public RemoteCacheNoWaitFacade( RemoteCacheNoWait[] noWaits, RemoteCacheAttributes rca,
-                                   ICompositeCacheManager cacheMgr )
+                                    ICompositeCacheManager cacheMgr )
     {
         if ( log.isDebugEnabled() )
         {
@@ -174,10 +180,37 @@
     }
 
     /**
+     * Gets multiple items from the cache based on the given set of keys.
+     * <p>
+     * @param keys
+     * @return a map of Serializable key to ICacheElement element, or an empty map if there is no data in cache for any of these keys
+     */
+    public Map getMultiple( Set keys )
+    {
+        if ( keys != null && !keys.isEmpty() )
+        {
+            for ( int i = 0; i < noWaits.length; i++ )
+            {
+                try
+                {
+                    return noWaits[i].getMultiple( keys );
+                }
+                catch ( Exception ex )
+                {
+                    log.debug( "Failed to get." );
+                    return new HashMap();
+                }
+            }
+        }
+
+        return new HashMap();
+    }
+
+    /**
      * Gets the set of keys of objects currently in the group.
      * <p>
      * @param group
-     * @return
+     * @return the set of keys of objects currently in the group
      * @throws IOException
      */
     public Set getGroupKeys( String group )
@@ -365,9 +398,8 @@
         return getStatistics().toString();
     }
 
-    /*
-     * (non-Javadoc)
-     * @see org.apache.jcs.auxiliary.AuxiliaryCache#getStatistics()
+    /**
+     * @return statistics about the cache region
      */
     public IStats getStatistics()
     {

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/ZombieRemoteCacheService.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/ZombieRemoteCacheService.java?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/ZombieRemoteCacheService.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/ZombieRemoteCacheService.java Fri Apr 11 11:43:26 2008
@@ -22,6 +22,8 @@
 import java.io.IOException;
 import java.io.Serializable;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.commons.logging.Log;
@@ -147,6 +149,17 @@
     {
         // Zombies have no inner life
         return null;
+    }
+
+    /**
+     * @param cacheName 
+     * @param keys
+     * @param requesterId 
+     * @return an empty map.  zombies have no internal data
+     */
+    public Map getMultiple( String cacheName, Set keys, long requesterId )
+    {
+        return new HashMap();
     }
 
     /**

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/behavior/IRemoteCacheService.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/behavior/IRemoteCacheService.java?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/behavior/IRemoteCacheService.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/behavior/IRemoteCacheService.java Fri Apr 11 11:43:26 2008
@@ -22,6 +22,7 @@
 import java.io.IOException;
 import java.io.Serializable;
 import java.rmi.Remote;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.jcs.access.exception.ObjectExistsException;
@@ -34,7 +35,6 @@
 public interface IRemoteCacheService
     extends Remote, ICacheService
 {
-
     /**
      * Puts a cache item to the cache.
      * <p>
@@ -43,7 +43,7 @@
      * @throws ObjectExistsException
      * @throws IOException
      */
-    public void update( ICacheElement item, long requesterId )
+    void update( ICacheElement item, long requesterId )
         throws ObjectExistsException, IOException;
 
     /**
@@ -54,7 +54,7 @@
      * @param requesterId
      * @throws IOException
      */
-    public void remove( String cacheName, Serializable key, long requesterId )
+    void remove( String cacheName, Serializable key, long requesterId )
         throws IOException;
 
     /**
@@ -64,7 +64,7 @@
      * @param requesterId
      * @throws IOException
      */
-    public void removeAll( String cacheName, long requesterId )
+    void removeAll( String cacheName, long requesterId )
         throws IOException;
 
     /**
@@ -80,7 +80,19 @@
      * @return ICacheElement
      * @throws IOException
      */
-    public ICacheElement get( String cacheName, Serializable key, long requesterId )
+    ICacheElement get( String cacheName, Serializable key, long requesterId )
+        throws IOException;
+
+    /**
+     * Gets multiple items from the cache based on the given set of keys.
+     * <p>
+     * @param cacheName 
+     * @param keys
+     * @param requesterId 
+     * @return a map of Serializable key to ICacheElement element, or an empty map if there is no data in cache for any of these keys
+     * @throws IOException 
+     */
+    Map getMultiple( String cacheName, Set keys, long requesterId )
         throws IOException;
 
     /**
@@ -89,6 +101,6 @@
      * @return A Set of keys
      * @throws java.rmi.RemoteException
      */
-    public Set getGroupKeys( String cacheName, String groupName )
+    Set getGroupKeys( String cacheName, String groupName )
         throws java.rmi.RemoteException;
 }

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServer.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServer.java?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServer.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServer.java Fri Apr 11 11:43:26 2008
@@ -68,27 +68,28 @@
     extends UnicastRemoteObject
     implements IRemoteCacheService, IRemoteCacheObserver, IRemoteCacheServiceAdmin, Unreferenced
 {
+    /** For serialization. Don't change.*/
     private static final long serialVersionUID = -8072345435941473116L;
 
+    /** log instance */
     private final static Log log = LogFactory.getLog( RemoteCacheServer.class );
 
     /** timing -- if we should record operation times. */
     protected final static boolean timing = true;
 
+    /** Number of puts into the cache. */
     private int puts = 0;
 
-    // Maps cache name to CacheListeners object.
-    // association of listeners (regions).
+    /** Maps cache name to CacheListeners object. association of listeners (regions). */
     private final Hashtable cacheListenersMap = new Hashtable();
 
     private final Hashtable clusterListenersMap = new Hashtable();
 
     private CompositeCacheManager cacheManager;
 
-    // relates listener id with a type
+    /** relates listener id with a type */
     private final Hashtable idTypeMap = new Hashtable();
 
-    // private transient int listenerId = 0;
     private int[] listenerId = new int[1];
 
     /** Configuration settings. */
@@ -103,7 +104,6 @@
      * <p>
      * @param rcsa
      * @throws RemoteException
-     * @exception IOException
      */
     RemoteCacheServer( IRemoteCacheServerAttributes rcsa )
         throws RemoteException
@@ -215,7 +215,6 @@
      * <p>
      * @param item
      * @throws IOException
-     *
      */
     public void put( ICacheElement item )
         throws IOException
@@ -223,10 +222,9 @@
         update( item );
     }
 
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.apache.jcs.engine.behavior.ICacheService#update(org.apache.jcs.engine.behavior.ICacheElement)
+    /**
+     * @param item 
+     * @throws IOException 
      */
     public void update( ICacheElement item )
         throws IOException
@@ -266,7 +264,6 @@
     public void update( ICacheElement item, long requesterId )
         throws IOException
     {
-
         long start = 0;
         if ( timing )
         {
@@ -487,8 +484,8 @@
 
         if ( log.isDebugEnabled() )
         {
-            log.debug( "get [" + key + "] from cache [" + cacheName + "] requesterId = [" + requesterId + "] remoteType = "
-                + remoteTypeL );
+            log.debug( "get [" + key + "] from cache [" + cacheName + "] requesterId = [" + requesterId
+                + "] remoteType = " + remoteTypeL );
         }
 
         // Since a non-receiving remote cache client will not register a
@@ -538,7 +535,8 @@
         {
             if ( log.isDebugEnabled() )
             {
-                log.debug( "NonLocalGet. fromCluster [" + fromCluster + "] AllowClusterGet [" + this.rcsa.getAllowClusterGet() + "]"  );
+                log.debug( "NonLocalGet. fromCluster [" + fromCluster + "] AllowClusterGet ["
+                    + this.rcsa.getAllowClusterGet() + "]" );
             }
             element = c.get( key );
         }
@@ -550,7 +548,8 @@
 
             if ( log.isDebugEnabled() )
             {
-                log.debug( "LocalGet.  fromCluster [" + fromCluster + "] AllowClusterGet [" + this.rcsa.getAllowClusterGet() + "]" );
+                log.debug( "LocalGet.  fromCluster [" + fromCluster + "] AllowClusterGet ["
+                    + this.rcsa.getAllowClusterGet() + "]" );
             }
             element = c.localGet( key );
         }
@@ -559,6 +558,111 @@
     }
 
     /**
+     * Gets multiple items from the cache based on the given set of keys.
+     * <p>
+     * @param cacheName 
+     * @param keys
+     * @return a map of Serializable key to ICacheElement element, or an empty map if there is no data in cache for any of these keys
+     * @throws IOException 
+     */
+    public Map getMultiple( String cacheName, Set keys )
+        throws IOException
+    {
+        return this.getMultiple( cacheName, keys, 0 );
+    }
+
+    /**
+     * Gets multiple items from the cache based on the given set of keys.
+     * <p>
+     * @param cacheName 
+     * @param keys
+     * @param requesterId 
+     * @return a map of Serializable key to ICacheElement element, or an empty map if there is no data in cache for any of these keys
+     * @throws IOException 
+     */
+    public Map getMultiple( String cacheName, Set keys, long requesterId )
+        throws IOException
+    {
+        Integer remoteTypeL = (Integer) idTypeMap.get( new Long( requesterId ) );
+
+        if ( log.isDebugEnabled() )
+        {
+            log.debug( "getMultiple [" + keys + "] from cache [" + cacheName + "] requesterId = [" + requesterId
+                + "] remoteType = " + remoteTypeL );
+        }
+
+        // Since a non-receiving remote cache client will not register a
+        // listener, it will not have a listener id assigned from the server. As
+        // such the remote server cannot determine if it is a cluster or a
+        // normal client. It will assume that it is a normal client.
+
+        boolean fromCluster = false;
+        if ( remoteTypeL != null && remoteTypeL.intValue() == IRemoteCacheAttributes.CLUSTER )
+        {
+            fromCluster = true;
+        }
+
+        CacheListeners cacheDesc = null;
+        try
+        {
+            cacheDesc = getCacheListeners( cacheName );
+        }
+        catch ( Exception e )
+        {
+            log.error( "Problem getting listeners.", e );
+        }
+
+        if ( cacheDesc == null )
+        {
+            return null;
+        }
+        CompositeCache c = (CompositeCache) cacheDesc.cache;
+
+        Map elements = null;
+
+        // If we have a getMultiple come in from a client and we don't have the item
+        // locally, we will allow the cache to look in other non local sources,
+        // such as a remote cache or a lateral.
+        //
+        // Since remote servers never get from clients and clients never go
+        // remote from a remote call, this
+        // will not result in any loops.
+        //
+        // This is the only instance I can think of where we allow a remote get
+        // from a remote call. The purpose is to allow remote cache servers to
+        // talk to each other. If one goes down, you want it to be able to get
+        // data from those that were up when the failed server comes back o
+        // line.
+
+        if ( !fromCluster && this.rcsa.getAllowClusterGet() )
+        {
+            if ( log.isDebugEnabled() )
+            {
+                log.debug( "NonLocalGetMultiple. fromCluster [" + fromCluster + "] AllowClusterGet ["
+                    + this.rcsa.getAllowClusterGet() + "]" );
+            }
+            
+            elements = c.getMultiple( keys );
+        }
+        else
+        {
+            // Gets from cluster type remote will end up here.
+            // Gets from all clients will end up here if allow cluster get is
+            // false.
+
+            if ( log.isDebugEnabled() )
+            {
+                log.debug( "LocalGetMultiple.  fromCluster [" + fromCluster + "] AllowClusterGet ["
+                    + this.rcsa.getAllowClusterGet() + "]" );
+            }
+            
+            elements = c.localGetMultiple( keys );
+        }
+
+        return elements;
+    }
+
+    /**
      * Gets the set of keys of objects currently in the group.
      * <p>
      * @param cacheName
@@ -581,6 +685,7 @@
         {
             return Collections.EMPTY_SET;
         }
+        
         CompositeCache c = (CompositeCache) cacheDesc.cache;
         return c.getGroupKeys( group );
     }
@@ -981,7 +1086,8 @@
      * registered, it will be removed from the event queue map list.
      * <p>
      * @param cacheName
-     * @param listenerId
+     * @param listener
+     * @throws IOException 
      */
     public void removeCacheListener( String cacheName, ICacheListener listener )
         throws IOException

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/engine/ZombieCacheService.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/engine/ZombieCacheService.java?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/engine/ZombieCacheService.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/engine/ZombieCacheService.java Fri Apr 11 11:43:26 2008
@@ -20,6 +20,10 @@
  */
 
 import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -58,14 +62,26 @@
         // zombies have no inner life
     }
 
-    /*
-     * (non-Javadoc)
-     * @see org.apache.jcs.engine.behavior.ICacheService#get(java.lang.String,
-     *      java.io.Serializable)
-     */
+    /**
+     * @param cacheName 
+     * @param key 
+     * @return null. zombies have no internal data
+     * */
     public ICacheElement get( String cacheName, Serializable key )
     {
         return null;
+    }
+
+    /**
+     * Returns an empty map.  Zombies have no internal data.
+     * <p>
+     * @param cacheName 
+     * @param keys
+     * @return an empty map 
+     */
+    public Map getMultiple( String cacheName, Set keys )
+    {
+        return new HashMap();
     }
 
     /**

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/engine/behavior/ICache.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/engine/behavior/ICache.java?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/engine/behavior/ICache.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/engine/behavior/ICache.java Fri Apr 11 11:43:26 2008
@@ -21,6 +21,8 @@
 
 import java.io.IOException;
 import java.io.Serializable;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * This is the top level interface for all cache like structures. It defines the methods used
@@ -35,30 +37,40 @@
     /**
      * Puts an item to the cache.
      * <p>
-     * @param ce
+     * @param element
      * @throws IOException
      */
-    public void update( ICacheElement ce )
+    void update( ICacheElement element )
         throws IOException;
 
     /**
      * Gets an item from the cache.
      * <p>
      * @param key
-     * @return
+     * @return a cache element, or null if there is no data in cache for this key
      * @throws IOException
      */
-    public ICacheElement get( Serializable key )
+    ICacheElement get( Serializable key )
+        throws IOException;
+
+    /**
+     * Gets multiple items from the cache based on the given set of keys.
+     * <p>
+     * @param keys
+     * @return a map of Serializable key to ICacheElement element, or an empty map if there is no data in cache for any of these keys
+     * @throws IOException
+     */
+    Map getMultiple( Set keys )
         throws IOException;
 
     /**
      * Removes an item from the cache.
      * <p>
      * @param key
-     * @return
+     * @return false if there was an error in removal
      * @throws IOException
      */
-    public boolean remove( Serializable key )
+    boolean remove( Serializable key )
         throws IOException;
 
     /**
@@ -66,14 +78,14 @@
      * <p>
      * @throws IOException
      */
-    public void removeAll()
+    void removeAll()
         throws IOException;
 
     /**
      * Prepares for shutdown.
      * @throws IOException
      */
-    public void dispose()
+    void dispose()
         throws IOException;
 
     /**
@@ -81,26 +93,26 @@
      * <p>
      * @return number of elements
      */
-    public int getSize();
+    int getSize();
 
     /**
      * Returns the cache status.
      * <p>
      * @return Alive or Error
      */
-    public int getStatus();
+    int getStatus();
 
     /**
      * Returns the cache stats.
      * <p>
      * @return String of important historical information.
      */
-    public String getStats();
+    String getStats();
 
     /**
      * Returns the cache name.
      * <p>
      * @return usually the region name.
      */
-    public String getCacheName();
+    String getCacheName();
 }

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/engine/behavior/ICacheService.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/engine/behavior/ICacheService.java?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/engine/behavior/ICacheService.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/engine/behavior/ICacheService.java Fri Apr 11 11:43:26 2008
@@ -21,6 +21,8 @@
 
 import java.io.IOException;
 import java.io.Serializable;
+import java.util.Map;
+import java.util.Set;
 
 import org.apache.jcs.access.exception.ObjectExistsException;
 import org.apache.jcs.access.exception.ObjectNotFoundException;
@@ -40,7 +42,7 @@
      * @throws ObjectExistsException
      * @throws IOException
      */
-    public void update( ICacheElement item )
+    void update( ICacheElement item )
         throws ObjectExistsException, IOException;
 
     /**
@@ -48,11 +50,23 @@
      * <p>
      * @param cacheName
      * @param key
-     * @return
+     * @return the ICacheElement or null if not found
      * @throws ObjectNotFoundException
      * @throws IOException
      */
-    public ICacheElement get( String cacheName, Serializable key )
+    ICacheElement get( String cacheName, Serializable key )
+        throws ObjectNotFoundException, IOException;
+
+    /**
+     * Gets multiple items from the cache based on the given set of keys.
+     * <p>
+     * @param cacheName 
+     * @param keys
+     * @return a map of Serializable key to ICacheElement element, or an empty map if there is no data in cache for any of these keys
+     * @throws ObjectNotFoundException 
+     * @throws IOException 
+     */
+    Map getMultiple( String cacheName, Set keys )
         throws ObjectNotFoundException, IOException;
 
     /**

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/engine/control/CompositeCache.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/engine/control/CompositeCache.java?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/engine/control/CompositeCache.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/engine/control/CompositeCache.java Fri Apr 11 11:43:26 2008
@@ -22,6 +22,7 @@
 import java.io.IOException;
 import java.io.Serializable;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
@@ -64,8 +65,10 @@
 public class CompositeCache
     implements ICache, Serializable
 {
+    /** For serialization. Don't change. */
     private static final long serialVersionUID = -2838097410378294960L;
 
+    /** log instance */
     private final static Log log = LogFactory.getLog( CompositeCache.class );
 
     /**
@@ -74,12 +77,13 @@
      */
     public static IElementEventQueue elementEventQ = new ElementEventQueue( "AllRegionQueue" );
 
-    // Auxiliary caches.
+    /** Auxiliary caches. */
     private AuxiliaryCache[] auxCaches = new AuxiliaryCache[0];
 
+    /** is this alive? */
     private boolean alive = true;
 
-    // this is in the cacheAttr, shouldn't be used, remove
+    /** TODO - this is in the cacheAttr, shouldn't be used, remove */
     final String cacheName;
 
     /** Region Elemental Attributes, default. */
@@ -88,9 +92,10 @@
     /** Cache Attributes, for hub and memory auxiliary. */
     private ICompositeCacheAttributes cacheAttr;
 
-    // Statistics
+    /** How many times update was called. */
     private int updateCount;
 
+    /** How many times remove was called. */
     private int removeCount;
 
     /** Memory cache hit count */
@@ -414,8 +419,7 @@
      * Gets an item from the cache.
      * <p>
      * @param key
-     * @return
-     * @throws IOException
+     * @return element from the cache, or null if not present
      * @see org.apache.jcs.engine.behavior.ICache#get(java.io.Serializable)
      */
     public ICacheElement get( Serializable key )
@@ -515,9 +519,9 @@
                             {
                                 element = aux.get( key );
                             }
-                            catch ( IOException ex )
+                            catch ( IOException e )
                             {
-                                log.error( "Error getting from aux", ex );
+                                log.error( "Error getting from aux", e );
                             }
                         }
 
@@ -526,10 +530,9 @@
                             log.debug( "Got CacheElement: " + element );
                         }
 
+                        // Item found in one of the auxiliary caches.
                         if ( element != null )
                         {
-                            // Item found in one of the auxiliary caches.
-
                             if ( isExpired( element ) )
                             {
                                 if ( log.isDebugEnabled() )
@@ -555,7 +558,6 @@
                                 }
 
                                 // Update counters
-
                                 hitCountAux++;
                                 auxHitCountByIndex[i]++;
 
@@ -603,6 +605,271 @@
     }
 
     /**
+     * Gets multiple items from the cache based on the given set of keys.
+     * <p>
+     * @param keys
+     * @return a map of Serializable key to ICacheElement element, or an empty map 
+     * if there is no data in cache for any of these keys
+     */
+    public Map getMultiple( Set keys )
+    {
+        return getMultiple( keys, false );
+    }
+
+    /**
+     * Gets multiple items from the cache based on the given set of keys.  
+     * Do not try to go remote or laterally for this data.
+     * <p>
+     * @param keys
+     * @return a map of Serializable key to ICacheElement element, or an empty map 
+     * if there is no data in cache for any of these keys
+     */
+    public Map localGetMultiple( Set keys )
+    {
+        return getMultiple( keys, true );
+    }
+
+    /**
+     * Look in memory, then disk, remote, or laterally for these items. The order is dependent on the
+     * order in the cache.ccf file.  Keep looking in each cache location until either the element is found,
+     * or the method runs out of places to look.
+     * <p>
+     * Do not try to go remote or laterally for this get if it is localOnly. Otherwise try to go
+     * remote or lateral if such an auxiliary is configured for this region.
+     * <p>
+     * @param keys
+     * @param localOnly
+     * @return ICacheElement
+     */
+    protected Map getMultiple( Set keys, boolean localOnly )
+    {
+        Map elements = new HashMap();
+
+        if ( log.isDebugEnabled() )
+        {
+            log.debug( "get: key = " + keys + ", localOnly = " + localOnly );
+        }
+
+        try
+        {
+            // First look in memory cache
+            elements.putAll( getMultipleFromMemory( keys ) );
+
+            // If fewer than all items were found in memory, then keep looking. 
+            if ( elements.size() != keys.size() )
+            {
+                Set remainingKeys = pruneKeysFound( keys, elements );
+                elements.putAll( getMultipleFromAuxiliaryCaches( remainingKeys, localOnly ) );
+            }
+        }
+        catch ( Exception e )
+        {
+            log.error( "Problem encountered getting elements.", e );
+        }
+
+        // if we didn't find all the elements, increment the miss count by the number of elements not found
+        if ( elements.size() != keys.size() )
+        {
+            missCountNotFound += ( keys.size() - elements.size() );
+
+            if ( log.isDebugEnabled() )
+            {
+                log.debug( cacheName + " - " + ( keys.size() - elements.size() ) + " Misses" );
+            }
+        }
+
+        return elements;
+    }
+
+    /**
+     * Gets items for the keys in the set.  Returns a map: key -> result.
+     * @param keys
+     * @return the elements found in the memory cache
+     * @throws IOException
+     */
+    private Map getMultipleFromMemory( Set keys )
+        throws IOException
+    {
+        Map elementsFromMemory = memCache.getMultiple( keys );
+
+        Iterator elementFromMemoryIterator = new HashMap( elementsFromMemory ).values().iterator();
+
+        while ( elementFromMemoryIterator.hasNext() )
+        {
+            ICacheElement element = (ICacheElement) elementFromMemoryIterator.next();
+
+            if ( element != null )
+            {
+                // Found in memory cache
+                if ( isExpired( element ) )
+                {
+                    if ( log.isDebugEnabled() )
+                    {
+                        log.debug( cacheName + " - Memory cache hit, but element expired" );
+                    }
+
+                    missCountExpired++;
+
+                    remove( element.getKey() );
+                    elementsFromMemory.remove( element.getKey() );
+                }
+                else
+                {
+                    if ( log.isDebugEnabled() )
+                    {
+                        log.debug( cacheName + " - Memory cache hit" );
+                    }
+
+                    // Update counters
+                    hitCountRam++;
+                }
+            }
+        }
+        return elementsFromMemory;
+    }
+
+    /**
+     * If local invocation look in aux caches, even if not local look in disk auxiliaries.
+     * <p>
+     * @param keys
+     * @param localOnly
+     * @return the elements found in the auxiliary caches
+     * @throws IOException
+     */
+    private Map getMultipleFromAuxiliaryCaches( Set keys, boolean localOnly )
+        throws IOException
+    {
+        Map elements = new HashMap();
+        Set remainingKeys = new HashSet( keys );
+
+        for ( int i = 0; i < auxCaches.length; i++ )
+        {
+            AuxiliaryCache aux = auxCaches[i];
+
+            if ( aux != null )
+            {
+                Map elementsFromAuxiliary = new HashMap();
+
+                long cacheType = aux.getCacheType();
+
+                if ( !localOnly || cacheType == AuxiliaryCache.DISK_CACHE )
+                {
+                    if ( log.isDebugEnabled() )
+                    {
+                        log.debug( "Attempting to get from aux [" + aux.getCacheName() + "] which is of type: "
+                            + cacheType );
+                    }
+
+                    try
+                    {
+                        elementsFromAuxiliary.putAll( aux.getMultiple( remainingKeys ) );
+                    }
+                    catch ( IOException e )
+                    {
+                        log.error( "Error getting from aux", e );
+                    }
+                }
+
+                if ( log.isDebugEnabled() )
+                {
+                    log.debug( "Got CacheElements: " + elementsFromAuxiliary );
+                }
+
+                Iterator elementFromAuxiliaryIterator = new HashMap( elementsFromAuxiliary ).values().iterator();
+
+                while ( elementFromAuxiliaryIterator.hasNext() )
+                {
+                    ICacheElement element = (ICacheElement) elementFromAuxiliaryIterator.next();
+
+                    // Item found in one of the auxiliary caches.
+                    if ( element != null )
+                    {
+                        if ( isExpired( element ) )
+                        {
+                            if ( log.isDebugEnabled() )
+                            {
+                                log.debug( cacheName + " - Aux cache[" + i + "] hit, but element expired." );
+                            }
+
+                            missCountExpired++;
+
+                            // This will tell the remotes to remove the item
+                            // based on the element's expiration policy. The elements attributes
+                            // associated with the item when it created govern its behavior
+                            // everywhere.
+                            remove( element.getKey() );
+                            elementsFromAuxiliary.remove( element.getKey() );
+                        }
+                        else
+                        {
+                            if ( log.isDebugEnabled() )
+                            {
+                                log.debug( cacheName + " - Aux cache[" + i + "] hit" );
+                            }
+
+                            // Update counters
+                            hitCountAux++;
+                            auxHitCountByIndex[i]++;
+
+                            // Spool the item back into memory
+                            // only spool if the mem cache size is greater
+                            // than 0, else the item will immediately get put
+                            // into purgatory
+                            if ( memCache.getCacheAttributes().getMaxObjects() > 0 )
+                            {
+                                memCache.update( element );
+                            }
+                            else
+                            {
+                                if ( log.isDebugEnabled() )
+                                {
+                                    log.debug( "Skipping memory update since no items are allowed in memory" );
+                                }
+                            }
+                        }
+                    }
+                }
+
+                elements.putAll( elementsFromAuxiliary );
+
+                if ( elements.size() == keys.size() )
+                {
+                    break;
+                }
+                else
+                {
+                    remainingKeys = pruneKeysFound( keys, elements );
+                }
+            }
+        }
+
+        return elements;
+    }
+
+    /**
+     * Returns a set of keys that were not found.
+     * <p>
+     * @param keys
+     * @param foundElements
+     * @return the original set of cache keys, minus any cache keys 
+     * present in the map keys of the foundElements map 
+     */
+    private Set pruneKeysFound( Set keys, Map foundElements )
+    {
+        Set remainingKeys = new HashSet( keys );
+
+        Iterator foundKeys = foundElements.keySet().iterator();
+
+        while ( foundKeys.hasNext() )
+        {
+            Serializable key = (Serializable) foundKeys.next();
+            remainingKeys.remove( key );
+        }
+
+        return remainingKeys;
+    }
+
+    /**
      * Determine if the element has exceeded its max life.
      * <p>
      * @param element
@@ -697,7 +964,7 @@
      * Removes an item from the cache.
      * <p>
      * @param key
-     * @return
+     * @return true is it was removed
      * @throws IOException
      * @see org.apache.jcs.engine.behavior.ICache#remove(java.io.Serializable)
      */

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/engine/memory/AbstractMemoryCache.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/engine/memory/AbstractMemoryCache.java?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/engine/memory/AbstractMemoryCache.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/engine/memory/AbstractMemoryCache.java Fri Apr 11 11:43:26 2008
@@ -21,6 +21,7 @@
 
 import java.io.IOException;
 import java.io.Serializable;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.Iterator;
@@ -54,8 +55,10 @@
 public abstract class AbstractMemoryCache
     implements MemoryCache, Serializable
 {
+    /** log instance */
     private final static Log log = LogFactory.getLog( AbstractMemoryCache.class );
 
+    /** default chunking size */
     private static final int DEFAULT_CHUNK_SIZE = 2;
 
     /** The region name. This defines a namespace of sorts. */
@@ -149,6 +152,39 @@
         throws IOException;
 
     /**
+     * Gets multiple items from the cache based on the given set of keys.
+     * <p>
+     * @param keys
+     * @return a map of Serializable key to ICacheElement element, or an empty map 
+     * if there is no data in cache for any of these keys
+     * @throws IOException 
+     */
+    public Map getMultiple( Set keys )
+        throws IOException
+    {
+        Map elements = new HashMap();
+
+        if ( keys != null && !keys.isEmpty() )
+        {
+            Iterator iterator = keys.iterator();
+
+            while ( iterator.hasNext() )
+            {
+                Serializable key = (Serializable) iterator.next();
+
+                ICacheElement element = get( key );
+
+                if ( element != null )
+                {
+                    elements.put( key, element );
+                }
+            }
+        }
+
+        return elements;
+    }
+
+    /**
      * Get an item from the cache without affecting its order or last access
      * time
      * @param key
@@ -200,9 +236,8 @@
         }
     }
 
-    /*
-     * (non-Javadoc)
-     * @see org.apache.jcs.engine.memory.MemoryCache#getStatistics()
+    /**
+     * @return statistics about the cache
      */
     public IStats getStatistics()
     {
@@ -286,6 +321,10 @@
         return this.cache;
     }
 
+    /**
+     * @param groupName 
+     * @return group keys
+     */
     public Set getGroupKeys( String groupName )
     {
         GroupId groupId = new GroupId( getCacheName(), groupName );
@@ -313,10 +352,9 @@
     class MyThreadFactory
         implements ThreadFactory
     {
-
-        /*
-         * (non-Javadoc)
-         * @see EDU.oswego.cs.dl.util.concurrent.ThreadFactory#newThread(java.lang.Runnable)
+        /**  
+         * @param runner 
+         * @return a new thread for the given Runnable
          */
         public Thread newThread( Runnable runner )
         {

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/engine/memory/behavior/IMemoryCache.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/engine/memory/behavior/IMemoryCache.java?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/engine/memory/behavior/IMemoryCache.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/engine/memory/behavior/IMemoryCache.java Fri Apr 11 11:43:26 2008
@@ -22,6 +22,7 @@
 import java.io.IOException;
 import java.io.Serializable;
 import java.util.Iterator;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.jcs.engine.behavior.ICacheElement;
@@ -29,26 +30,22 @@
 import org.apache.jcs.engine.control.CompositeCache;
 import org.apache.jcs.engine.stats.behavior.IStats;
 
-/**
- * For the framework. Insures methods a MemoryCache needs to access.
- *
- */
+/** For the framework. Insures methods a MemoryCache needs to access. */
 public interface IMemoryCache
 {
     /**
      * Initialize the memory cache
      * <p>
-     * @param cache
-     *            The cache (region) this memory store is attached to.
+     * @param cache The cache (region) this memory store is attached to.
      */
-    public void initialize( CompositeCache cache );
+    void initialize( CompositeCache cache );
 
     /**
      * Destroy the memory cache
      * <p>
      * @throws IOException
      */
-    public void dispose()
+    void dispose()
         throws IOException;
 
     /**
@@ -56,14 +53,14 @@
      * <p>
      * @return Element count
      */
-    public int getSize();
+    int getSize();
 
     /**
      * Returns the historical and statistical data for a region's memory cache.
      * <p>
      * @return Statistics and Infor for the Memory Cache.
      */
-    public IStats getStatistics();
+    IStats getStatistics();
 
     /**
      * Get an iterator for all elements in the memory cache. This should be
@@ -72,7 +69,7 @@
      * <p>
      * @return An iterator
      */
-    public Iterator getIterator();
+    Iterator getIterator();
 
     /**
      * Get an Array of the keys for all elements in the memory cache.
@@ -82,7 +79,7 @@
      *       will be a problem if someone puts a 1,000,000 or so items in a
      *       region.
      */
-    public Object[] getKeyArray();
+    Object[] getKeyArray();
 
     /**
      * Removes an item from the cache
@@ -93,7 +90,7 @@
      * @exception IOException
      *                Description of the Exception
      */
-    public boolean remove( Serializable key )
+    boolean remove( Serializable key )
         throws IOException;
 
     /**
@@ -102,7 +99,7 @@
      * @exception IOException
      *                Description of the Exception
      */
-    public void removeAll()
+    void removeAll()
         throws IOException;
 
     /**
@@ -116,7 +113,7 @@
      *         only 3, you will get 3.
      * @throws IOException
      */
-    public int freeElements( int numberToFree )
+    int freeElements( int numberToFree )
         throws IOException;
 
     /**
@@ -128,7 +125,18 @@
      * @exception IOException
      *                Description of the Exception
      */
-    public ICacheElement get( Serializable key )
+    ICacheElement get( Serializable key )
+        throws IOException;
+
+    /**
+     * Gets multiple items from the cache based on the given set of keys.
+     * <p>
+     * @param keys
+     * @return a map of Serializable key to ICacheElement element, or an empty map 
+     * if there is no data in cache for any of these keys
+     * @throws IOException 
+     */
+    Map getMultiple( Set keys )
         throws IOException;
 
     /**
@@ -141,7 +149,7 @@
      * @exception IOException
      *                Description of the Exception
      */
-    public ICacheElement getQuiet( Serializable key )
+    ICacheElement getQuiet( Serializable key )
         throws IOException;
 
     /**
@@ -152,7 +160,7 @@
      * @exception IOException
      *                Description of the Exception
      */
-    public void waterfal( ICacheElement ce )
+    void waterfal( ICacheElement ce )
         throws IOException;
 
     /**
@@ -163,7 +171,7 @@
      * @exception IOException
      *                Description of the Exception
      */
-    public void update( ICacheElement ce )
+    void update( ICacheElement ce )
         throws IOException;
 
     /**
@@ -171,7 +179,7 @@
      * <p>
      * @return The cacheAttributes value
      */
-    public ICompositeCacheAttributes getCacheAttributes();
+    ICompositeCacheAttributes getCacheAttributes();
 
     /**
      * Sets the CacheAttributes of the region.
@@ -179,14 +187,14 @@
      * @param cattr
      *            The new cacheAttributes value
      */
-    public void setCacheAttributes( ICompositeCacheAttributes cattr );
+    void setCacheAttributes( ICompositeCacheAttributes cattr );
 
     /**
      * Gets the cache hub / region that uses the MemoryCache.
      * <p>
      * @return The cache value
      */
-    public CompositeCache getCompositeCache();
+    CompositeCache getCompositeCache();
 
     /**
      * Gets the set of keys of objects currently in the group.
@@ -194,6 +202,5 @@
      * @param group
      * @return a Set of group keys.
      */
-    public Set getGroupKeys( String group );
-
+    Set getGroupKeys( String group );
 }

Modified: jakarta/jcs/trunk/src/test-conf/TestTCPLateralIssueRemoveCache.ccf
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test-conf/TestTCPLateralIssueRemoveCache.ccf?rev=647264&r1=647263&r2=647264&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/test-conf/TestTCPLateralIssueRemoveCache.ccf (original)
+++ jakarta/jcs/trunk/src/test-conf/TestTCPLateralIssueRemoveCache.ccf Fri Apr 11 11:43:26 2008
@@ -36,8 +36,8 @@
 # simple Lateral TCP auxiliary
 jcs.auxiliary.LTCP=org.apache.jcs.auxiliary.lateral.socket.tcp.LateralTCPCacheFactory
 jcs.auxiliary.LTCP.attributes=org.apache.jcs.auxiliary.lateral.socket.tcp.TCPLateralCacheAttributes
-jcs.auxiliary.LTCP.attributes.TcpServers=localhost:1111
-jcs.auxiliary.LTCP.attributes.TcpListenerPort=1110
+jcs.auxiliary.LTCP.attributes.TcpServers=localhost:1117
+jcs.auxiliary.LTCP.attributes.TcpListenerPort=1118
 jcs.auxiliary.LTCP.attributes.AllowGet=false
 jcs.auxiliary.LTCP.attributes.IssueRemoveOnPut=true
 



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