logo       


svn commit: r430809 [1/2] - in /jakarta/jcs/trunk/src: experimental/org/apa: msg#00011

Subject: svn commit: r430809 [1/2] - in /jakarta/jcs/trunk/src: experimental/org/apache/jcs/engine/memory/arc/ java/org/apache/jcs/access/ java/org/apache/jcs/access/behavior/ java/org/apache/jcs/auxiliary/lateral/ java/org/apache/jcs/auxiliary/lateral/socket/t...
Author: asmuts
Date: Fri Aug 11 08:51:10 2006
New Revision: 430809

URL: http://svn.apache.org/viewvc?rev=430809&view=rev
Log:
Added a freeMemoryElements method.
Formatted a few classes.
Added some tests to the ARC memory cache implementation in the experimental 
folder.

Added:
    
jakarta/jcs/trunk/src/experimental/org/apache/jcs/engine/memory/arc/ARCMemoryCacheUnitTest.java
    jakarta/jcs/trunk/src/test-conf/TestARCCache.ccf
Modified:
    
jakarta/jcs/trunk/src/experimental/org/apache/jcs/engine/memory/arc/ARCMemoryCache.java
    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/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/LateralElementDescriptor.java
    
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPCacheManager.java
    
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPListener.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/engine/memory/AbstractMemoryCache.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/engine/memory/MemoryCache.java
    
jakarta/jcs/trunk/src/java/org/apache/jcs/engine/memory/lru/LRUMemoryCache.java
    
jakarta/jcs/trunk/src/java/org/apache/jcs/engine/memory/mru/MRUMemoryCache.java
    
jakarta/jcs/trunk/src/java/org/apache/jcs/utils/serialization/StandardSerializer.java
    jakarta/jcs/trunk/src/test-conf/TestTCPLateralCacheConcurrent.ccf
    jakarta/jcs/trunk/src/test-conf/log4j.properties
    
jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPConcurrentRandomTestUtil.java
    
jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPNoDeadLockConcurrentTest.java
    
jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/lateral/socket/tcp/TestTCPLateral.java
    
jakarta/jcs/trunk/src/test/org/apache/jcs/engine/memory/MemoryCacheMockImpl.java

Modified: 
jakarta/jcs/trunk/src/experimental/org/apache/jcs/engine/memory/arc/ARCMemoryCache.java
URL: 
http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/experimental/org/apache/jcs/engine/memory/arc/ARCMemoryCache.java?rev=430809&r1=430808&r2=430809&view=diff
==============================================================================
--- 
jakarta/jcs/trunk/src/experimental/org/apache/jcs/engine/memory/arc/ARCMemoryCache.java
 (original)
+++ 
jakarta/jcs/trunk/src/experimental/org/apache/jcs/engine/memory/arc/ARCMemoryCache.java
 Fri Aug 11 08:51:10 2006
@@ -1,623 +1,797 @@
 package org.apache.jcs.engine.memory.arc;
 
 /*
- * 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;
 import java.io.Serializable;
 import java.util.ArrayList;
 
-import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-
 import org.apache.jcs.engine.CacheElement;
-import org.apache.jcs.engine.control.CompositeCache;
 import org.apache.jcs.engine.behavior.ICacheElement;
+import org.apache.jcs.engine.control.CompositeCache;
 import org.apache.jcs.engine.memory.AbstractMemoryCache;
-import org.apache.jcs.utils.struct.DoubleLinkedList;
 import org.apache.jcs.engine.memory.util.MemoryElementDescriptor;
 import org.apache.jcs.engine.stats.StatElement;
 import org.apache.jcs.engine.stats.Stats;
 import org.apache.jcs.engine.stats.behavior.IStatElement;
 import org.apache.jcs.engine.stats.behavior.IStats;
+import org.apache.jcs.utils.struct.DoubleLinkedList;
+
+import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
 
 /**
- *  This is a rough implmentation of an adaptive replacement cache.
- *  ARC is a hybrid LFU / LRU that adapts to user behavior.
- *
- *  See the ARC method for more detail on how the algorithm works.
- *
- *  @see  
http://www.almaden.ibm.com/StorageSystems/autonomic_storage/ARC/index.shtml
+ * This is a rough implmentation of an adaptive replacement cache. ARC is a
+ * hybrid LFU / LRU that adapts to user behavior.
+ * <p>
+ * See the ARC method for more detail on how the algorithm works.
+ * <p>
+ * @see 
http://www.almaden.ibm.com/StorageSystems/autonomic_storage/ARC/index.shtml
+ * @see http://www.almaden.ibm.com/cs/people/dmodha/ARC.pdf
  */
 public class ARCMemoryCache
     extends AbstractMemoryCache
 {
+    private static final long serialVersionUID = 1L;
+
+    private final static Log log = LogFactory.getLog( ARCMemoryCache.class );
+
+    // private int[] loc = new int[0];
+
+    // maximum size
+    private int maxSize = 0;
+
+    private DoubleLinkedList T1 = new DoubleLinkedList();
+
+    private DoubleLinkedList T2 = new DoubleLinkedList();
+
+    private DoubleLinkedList B1 = new DoubleLinkedList();
+
+    private DoubleLinkedList B2 = new DoubleLinkedList();
+
+    /** id of list T1 */
+    protected static final int _T1_ = 1;
+
+    /** id of list T2 */
+    protected static final int _T2_ = 2;
+
+    /** id of list B1 */
+    protected static final int _B1_ = 3;
+
+    /** id of list B2 */
+    protected static final int _B2_ = 4;
+
+    // ideal size of T1
+    private int target_T1 = 0;
+
+    private ConcurrentHashMap map = new ConcurrentHashMap();
+
+    private int cnt = 0;
+
+    private int hitCnt = 0;
+
+    private int missCnt = 0;
+
+    private int putCnt = 0;
+
+    /**
+     * Default constructor.
+     */
+    public ARCMemoryCache()
+    {
+        if ( log.isInfoEnabled() )
+        {
+            log.info( "Loading Arc" );
+        }
+    }
+
+    /**
+     * Get an Array of the keys for all elements in the memory cache
+     * @return Object[]
+     */
+    public Object[] getKeyArray()
+    {
+        // need to lock to map here?
+        synchronized ( map )
+        {
+            return map.keySet().toArray();
+        }
+    }
+
+    public ICacheElement getQuiet( Serializable key )
+        throws IOException
+    {
+        return get( key );
+    }
+
+    /**
+     * For post reflection creation initialization
+     * <p>
+     * @param hub
+     */
+    public synchronized void initialize( CompositeCache hub )
+    {
+        super.initialize( hub );
+        maxSize = this.cattr.getMaxObjects(); // / 2;
+        target_T1 = maxSize / 2;
+        log.info( "initialized LRUMemoryCache for " + cacheName );
+    }
+
+    /**
+     * Looks for the item in the lists.
+     */
+    public ICacheElement get( Serializable key )
+        throws IOException
+    {
+        CacheElement ce = new CacheElement( cacheName, key, null );
+
+        ICacheElement ice = null;
+        try
+        {
+            ice = ARC( ce, true );
+        }
+        catch ( Exception e )
+        {
+            log.error( e );
+        }
+        return ice;
+    }
+
+    /**
+     * Adds an element to the cache.
+     */
+    public void update( ICacheElement ce )
+    {
+        try
+        {
+            ARC( ce, false );
+        }
+        catch ( Exception e )
+        {
+            log.error( e );
+        }
+    }
 
-  private final static Log log =
-      LogFactory.getLog(ARCMemoryCache.class);
+    /**
+     * This is the primary method for the ARC. It handles both puts and gets.
+     * <p>
+     * The ARC has 4 linked lists: T1, T2, B1, and B2. The 'T' lists are tops
+     * and the 'B' lists are bottoms. Bottom lists do not hold object, only
+     * keys.
+     * <p>
+     * The T1 list is an LRU (Least Recently Used) list. The T2 list is a near
+     * LFU (Least Frequently Used) list.
+     * <p>
+     * After items are removed from T1 and T2, their keys are stored in B1 and
+     * B2. The number of keys in B1 and B2 is restricted to the number of max
+     * items.
+     * <p>
+     * When there is a put or a get for an item whose key exists on one of the
+     * bottom lists, the maximum number of items in T1 is adjusted. If the item
+     * was found on B2 (the bottom LFU list) the maximum allowed in T1 (the top
+     * LRU list) is reduced. If the item is found in B1 list (the bottom LRU)
+     * the maximum allowed in T1 is increased.
+     * <p>
+     * The maximum allowed in T1 will not exceed the maxSize. The maximum in T1
+     * and T2 combined will not exceed the maxSize. The maximum number of
+     * elements and keys allowed in all 4 lists will not exceed twice the
+     * maximum size.
+     * <p>
+     * All the elements are stored in a map. The lists keep track of when the
+     * element was last used, or when it was deleted and from where. We first
+     * look for the item in the map, if we find it, we go looking for it in the
+     * lists.
+     * <p>
+     * @param ce
+     *            ICacheElement
+     * @param isGet
+     *            boolean
+     * @return ICacheElement
+     */
+    public ICacheElement ARC( ICacheElement ce, boolean isGet )
+    {
+        cnt++;
+        logStatsOccassionally( ce, isGet );
+        if ( !isGet )
+        {
+            putCnt++;
+        }
 
-  int[] loc = new int[0];
+        ElementDescriptor temp = (ElementDescriptor) map.get( ce.getKey() );
+        boolean isHit = true;
 
-  // maximum size
-  int c = 0;
+        if ( temp != null )
+        {
+            if ( isGet )
+            {
+                hitCnt++;
+            }
 
-  DoubleLinkedList T1 = new DoubleLinkedList();
-  DoubleLinkedList T2 = new DoubleLinkedList();
-  DoubleLinkedList B1 = new DoubleLinkedList();
-  DoubleLinkedList B2 = new DoubleLinkedList();
-
-  private static final int _T1_ = 1;
-  private static final int _T2_ = 2;
-  private static final int _B1_ = 3;
-  private static final int _B2_ = 4;
-
-  // ideal size of T1
-  int target_T1 = 0;
-
-  ConcurrentHashMap map = new ConcurrentHashMap();
-
-  int cnt = 0;
-
-  int hitCnt = 0;
-  int missCnt = 0;
-  int putCnt = 0;
-
-  public ARCMemoryCache()
-  {
-    log.debug("Loading Arc");
-  }
-
-  public Object[] getKeyArray()
-  {
-    return null;
-  }
-
-  public ICacheElement getQuiet(Serializable key) throws IOException
-  {
-    return get(key);
-  }
-
-  /**
-   *  For post reflection creation initialization
-   *
-   *@param  hub
-   */
-  public synchronized void initialize(CompositeCache hub)
-  {
-    super.initialize(hub);
-    c = this.cattr.getMaxObjects(); // / 2;
-    target_T1 = c / 2;
-    log.info("initialized LRUMemoryCache for " + cacheName);
-  }
-
-  public ICacheElement get(Serializable key) throws IOException
-  {
-    CacheElement ce = new CacheElement(cacheName,
-                                       (Serializable) key,
-                                       null);
-
-    ICacheElement ice = null;
-    try {
-      ice = ARC(ce, true);
-    } catch( Exception e ) {
-      log.error( e );
-    }
-    return ice;
-  }
-
-  public void update(ICacheElement ce)
-  {
-    try {
-      ARC(ce, false);
-    } catch( Exception e ) {
-      log.error( e );
-    }
-  }
-
-  /**
-   * This is the primary method for the ARC.  It handles both puts and gets.
-   * The ARC has 4 linked lists: T1, T2, B1, and B2.  The 'T' lists are tops
-   * and the 'B' lists are bottoms.  Bottom lists do not hold object, only 
keys.
-   *
-   * The T1 list is an LRU (Least Recently Used) list.  The T2 list is a near
-   * LFU (Least Frequently Used) list.
-   *
-   * After items are removed from T1 and T2, their keys are stored in B1 and 
B2.
-   * The number of keys in B1 and B2 is restricted to the number of max items.
-   *
-   * When there is a put or a get for an item whose key exists on one of the
-   * bottom lists, the maximum number of items in T1 is adjusted.  If the item
-   * was found on B2 (the bottom LFU list) the maximum allowed in T1 (the top
-   * LRU list) is reduced.  If the item is found in B1 list (the bottom LRU) 
the
-   * maximum allowed in T1 is increased.
-   *
-   * The maximum allowed in T1 will not exceed the maxSize.  The maximum in T1
-   * and T2 combined will not exceed the maxSize.  The maximum number of 
elements
-   * and keys allowed in all 4 lists will not exceed twice the maximum size.
-   *
-   * @param ce ICacheElement
-   * @param isGet boolean
-   * @return ICacheElement
-   */
-  public ICacheElement ARC(ICacheElement ce, boolean isGet)
-  {
-
-    cnt++;
-
-    if (cnt % 10000 == 0)
-    //if ( true )
-    {
-      if (log.isInfoEnabled())
-      {
-        StringBuffer buf = new StringBuffer();
-        buf.append("\n ce.key() = " + ce.getKey());
-        buf.append("\n isGet = " + isGet);
-        buf.append(getStats());
-        log.info(buf.toString());
-      }
-    }
-
-    if (!isGet)
-    {
-      putCnt++;
-    }
-
-    ElementDescriptor temp = (ElementDescriptor) map.get(ce.getKey());
-    boolean isHit = true;
-
-    if (temp != null)
-    {
-
-      if (isGet)
-      {
-        hitCnt++;
-      }
-
-      switch (temp.listNum)
-      {
-        case _T1_:
-          if (log.isDebugEnabled())
-          {
-            log.debug("T1");
-          }
-
-          log.debug("T1 to T2, before remove = " + T1.size());
-          boolean stat1 = T1.remove(temp); // need to implement our own list
-          log.debug("T1 to T2, after remove = " + T1.size() + " stat = " + 
stat1);
-
-          temp.listNum = _T2_;
-          T2.addFirst(temp);
-          break;
-
-        case _T2_:
-          if (log.isDebugEnabled())
-          {
-            log.debug("T2");
-          }
-
-          temp.listNum = _T2_;
-          T2.makeFirst(temp);
-          break;
-
-        case _B1_:
-
-          // B1 hit: favor recency
-
-          // adapt the target size
-          target_T1 = Math.min(target_T1 + Math.max(B2.size() / B1.size(), 1),
-                               c);
-          if (log.isDebugEnabled())
-          {
-            log.debug("B1, targetT1 = " + target_T1 );
-          }
-
-          if (!isGet)
-          {
-            if (log.isDebugEnabled())
+            // determine where the element lives.
+            switch ( temp.listNum )
+            {
+                case _T1_:
+                    handleFoundInT1( temp );
+                    break;
+
+                case _T2_:
+                    handleFoundInT2( temp );
+                    break;
+
+                case _B1_:
+                    temp = handleFoundInB1( ce, isGet, temp );
+                    break;
+
+                case _B2_:
+                    temp = handleFoundInB2( ce, isGet, temp );
+                    break;
+            }
+        }
+        else
+        {
+            /* Element is not in cache */
+            isHit = false;
+            if ( isGet )
             {
-              log.debug("B1 before remove = " + B1.size());
+                missCnt++;
             }
-            boolean stat3 = B1.remove(temp); // need to implement our own list
-            if (log.isDebugEnabled())
+            if ( log.isDebugEnabled() )
             {
-              log.debug("B1 after remove = " + B1.size() + " stat = " + stat3);
+                log.debug( "Element is not in cache" );
             }
-            replace(temp);
-            temp.listNum = _T2_;
+        }
+
+        // 
////////////////////////////////////////////////////////////////////////////
+        // Do some size Checks if this is a put
+        if ( !isGet && !isHit )
+        {
+            if ( T1.size() + B1.size() >= maxSize )
+            {
+                /* B1 + T1 full? */
+                if ( T1.size() < maxSize )
+                {
+                    /* Still room in T1? */
+                    temp = (ElementDescriptor) B1.removeLast();
+                    if ( temp != null )
+                    {
+                        map.remove( temp.key );
+                    }
+                    /* yes: take page off B1 */
+                    // temp->pointer = replace(); /* find new place to put page
+                    // */
+                    replace( temp );
+                }
+                else
+                {
+                    /* no: B1 must be empty */
+                    temp = (ElementDescriptor) T1.removeLast(); /*
+                                                                 * take page //
+                                                                 * off // T1
+                                                                 */
+                    map.remove( temp.ce.getKey() );
+                    // if (temp->dirty) destage(temp); /* if dirty, evict 
before
+                    // overwrite */
+                    replace( temp );
+                }
+            }
+            else
+            {
+                /* B1 + T1 have less than the maxSize elements */
+                if ( T1.size() + T2.size() + B1.size() + B2.size() >= maxSize )
+                {
+                    /* cache full? */
+                    /* Yes, cache full: */
+                    if ( T1.size() + T2.size() + B1.size() + B2.size() >= 2 * 
maxSize )
+                    {
+                        /* cache is full: */
+                        /* x find and reuse B2’s LRU */
+                        temp = (ElementDescriptor) B2.removeLast();
+                        if ( temp != null )
+                        {
+                            map.remove( temp.key );
+                        }
+                    }
+                    else
+                    {
+                        /* cache directory not full, easy case */
+                        // nop
+                    }
+                    replace( temp );
+                }
+                else
+                {
+                    /* cache not full, easy case */
+                    // nop
+                }
+            }
+        }
+
+        if ( !isGet && !isHit )
+        {
+            temp = new ElementDescriptor( ce );
             temp.ce = ce;
-            T2.addFirst(temp); // seen twice recently, put on T2
+            temp.listNum = _T1_;
+            T1.addFirst( temp );
+            // seen once recently, put on T1
+            this.map.put( temp.ce.getKey(), temp );
+        }
+        // end if put
+
+        if ( temp == null )
+        {
+            return null;
+        }
+        return temp.ce;
+    }
+
+    /**
+     * Move to T2 if the item was found in T1.
+     * <p>
+     * @param temp
+     */
+    protected void handleFoundInT1( ElementDescriptor temp )
+    {
+        if ( log.isDebugEnabled() )
+        {
+            log.debug( "T1" );
+        }
+        if ( log.isDebugEnabled() )
+        {
+            log.debug( "T1 to T2, before remove = " + T1.size() );
+        }
+        boolean stat1 = T1.remove( temp );
+        // need to implement our
+        // own list
+        if ( log.isDebugEnabled() )
+        {
+            log.debug( "T1 to T2, after remove = " + T1.size() + " stat = " + 
stat1 );
+        }
+
+        temp.listNum = _T2_;
+        T2.addFirst( temp );
+    }
 
-          }
-          else
-          {
+    /**
+     * If it was found in T2, we move it to the top of the T2 list.
+     * <p>
+     * @param temp
+     */
+    protected void handleFoundInT2( ElementDescriptor temp )
+    {
+        if ( log.isDebugEnabled() )
+        {
+            log.debug( "T2" );
+        }
+
+        temp.listNum = _T2_;
+        T2.makeFirst( temp );
+    }
+
+    /**
+     * B1 hit: favor recency
+     * <p>
+     * @param ce
+     * @param isGet
+     * @param temp
+     * @return
+     */
+    protected ElementDescriptor handleFoundInB1( ICacheElement ce, boolean 
isGet, ElementDescriptor temp )
+    {
+        // B1 hit: favor recency
+
+        // adapt the target size
+        target_T1 = Math.min( target_T1 + Math.max( B2.size() / B1.size(), 1 
), maxSize );
+        if ( log.isDebugEnabled() )
+        {
+            log.debug( "B1, targetT1 = " + target_T1 );
+        }
+
+        if ( !isGet )
+        {
+            if ( log.isDebugEnabled() )
+            {
+                log.debug( "B1 before remove = " + B1.size() );
+            }
+            boolean stat3 = B1.remove( temp ); // need to implement
+            // our own list
+            if ( log.isDebugEnabled() )
+            {
+                log.debug( "B1 after remove = " + B1.size() + " stat = " + 
stat3 );
+            }
+            replace( temp );
+            temp.listNum = _T2_;
+            temp.ce = ce;
+            // seen twice recently, put on T2
+            T2.addFirst( temp );
+        }
+        else
+        {
             // if this is just a get, then adjust the cache
             // it is essentially a miss.
             temp = null;
             hitCnt--;
             missCnt++;
-          }
-          break;
-
-        case _B2_:
-
-          // B2 hit: favor frequency
+        }
+        return temp;
+    }
 
-          // adapt the target size
-          target_T1 = Math.max(target_T1 - Math.max(B1.size() / B2.size(), 1),
-                               0);
-          if (log.isDebugEnabled())
-          {
-            log.debug("B2, targetT1 = " + target_T1 );
-          }
+    /**
+     * B2 hit: favor frequency
+     * <p>
+     * @param ce
+     * @param isGet
+     * @param temp
+     * @return
+     */
+    protected ElementDescriptor handleFoundInB2( ICacheElement ce, boolean 
isGet, ElementDescriptor temp )
+    {
+        // adapt the target size
+        target_T1 = Math.max( target_T1 - Math.max( B1.size() / B2.size(), 1 
), 0 );
+        if ( log.isDebugEnabled() )
+        {
+            log.debug( "B2, targetT1 = " + target_T1 );
+        }
 
-          if (!isGet)
-          {
-            if (log.isDebugEnabled())
+        if ( !isGet )
+        {
+            if ( log.isDebugEnabled() )
             {
-              log.debug("B2 before remove = " + B2.size());
+                log.debug( "B2 before remove = " + B2.size() );
             }
-            boolean stat4 = B2.remove(temp); // need to implement our own list
-            if (log.isDebugEnabled())
+            boolean stat4 = B2.remove( temp ); // need to implement
+            // our own list
+            if ( log.isDebugEnabled() )
             {
-              log.debug("B2 after remove = " + B2.size() + " stat = " + stat4);
+                log.debug( "B2 after remove = " + B2.size() + " stat = " + 
stat4 );
             }
 
-            replace(temp);
+            replace( temp );
             temp.listNum = _T2_;
             temp.ce = ce;
-            T2.addFirst(temp); // seen twice recently, put on T2
+            // seen twice recently, put on T2
+            T2.addFirst( temp );
 
-            replace(temp);
-          }
-          else
-          {
+            replace( temp );
+        }
+        else
+        {
             // if this is just a get, then adjust the cache
             // it is essentially a miss.
             temp = null;
             hitCnt--;
             missCnt++;
-          }
-          break;
-      }
-
-      // was null
-    }
-    else
-    {
-      /* page is not in cache  */
-
-      isHit = false;
-      if (isGet)
-      {
-        missCnt++;
-      }
-
-      if (log.isDebugEnabled())
-      {
-        log.debug("Page is not in cache");
-      }
-
-    } // end if not in cache
-
-    
//////////////////////////////////////////////////////////////////////////////
-    // Do some size Checks if this is a put
-    //if (!isGet)
-    //{
-      if (T1.size() + B1.size() >= c)
-      {
-        /* B1 + T1 full? */
-        if (T1.size() < c)
-        {
-          /* Still room in T1? */
-          temp = (ElementDescriptor) B1.removeLast();
-          if ( temp != null ) {
-            map.remove(temp.key);
-          }
-          /* yes: take page off B1 */
-          //temp->pointer = replace(); /* find new place to put page */
-          replace(temp);
         }
-        else
+        return temp;
+    }
+
+    /**
+     * Prints the stats every 10000 or so operations.
+     * <p>
+     * @param ce
+     * @param isGet
+     */
+    protected void logStatsOccassionally( ICacheElement ce, boolean isGet )
+    {
+        if ( cnt % 10000 == 0 )
+        // if ( true )
         {
-          /* no: B1 must be empty */
-          //temp = (ElementDescriptor) T1.removeLast(); /* take page off T1 */
-          //map.remove(temp.ce.getKey());
-          //if (temp->dirty) destage(temp); /* if dirty, evict before 
overwrite */
-          replace(temp);
-        }
-      }
-      else
-      {
-        /* B1 + T1 have less than c pages */
-        if (T1.size() + T2.size() + B1.size() + B2.size() >= c)
-        {
-          /* cache full? */
-          /* Yes, cache full: */
-          if (T1.size() + T2.size() + B1.size() + B2.size() >= 2 * c)
-          {
-            /* cache is full: */
-            /* x find and reuse B2’s LRU */
-            temp = (ElementDescriptor) B2.removeLast();
-            if ( temp != null ) {
-              map.remove(temp.key);
-            }
-          }
-          else
-          {
-            /* cache directory not full, easy case */
-            ; //nop
-          }
-          replace(temp);
+            if ( log.isInfoEnabled() )
+            {
+                StringBuffer buf = new StringBuffer();
+                buf.append( "\n ce.key() = " + ce.getKey() );
+                buf.append( "\n isGet = " + isGet );
+                buf.append( getStats() );
+                log.info( buf.toString() );
+            }
         }
-        else
+    }
+
+    /**
+     * This method doesn't so much replace as remove. It pushes the least
+     * recently used in t1 or t2 to a dummy holder. The holder keeps a dummy
+     * object that stores the key so that subsequent gets and puts can help
+     * train the cache. Items are spooled if there is a disk cache at this
+     * point.
+     * <p>
+     * @param orig
+     *            ElementDescriptor
+     */
+    public void replace( ElementDescriptor orig )
+    {
+        try
         {
-          /* cache not full, easy case */
-          ; //nop
-        }
-      }
+            ElementDescriptor temp;
+            if ( T1.size() >= Math.max( 1, target_T1 ) )
+            {
+                // T1’s size exceeds target?
+                // yes: T1 is too big
+                temp = (ElementDescriptor) T1.getLast();
+                if ( orig == null || !orig.key.equals( temp.key ) )
+                {
+                    if ( log.isDebugEnabled() )
+                    {
+                        log.debug( "replace -- T1 to B1" );
+                        log.debug( getStats() );
+                    }
+                    temp = (ElementDescriptor) T1.removeLast(); // grab LRU 
from
+                    // T1
+                    // nullify object, temp is now just a dummy container to
+                    // help adjust the lru size
+                    try
+                    {
+                        this.waterfal( temp.ce );
+                    }
+                    catch ( Exception e )
+                    {
+                        log.error( e );
+                    }
+                    temp.ce = null;
+                    temp.listNum = _B1_; // note that fact
+                    B1.addFirst( temp ); // put it on B1
+                    // T1Length—; B1Length++; // bookkeep
+                }
+                else
+                {
+                    if ( log.isDebugEnabled() )
+                    {
+                        log.debug( "orig == temp, t1" );
+                    }
+                }
+            }
+            else
+            // if t2 is greater than or equal to what is left in c after the
+            // target
+            if ( ( T2.size() + T1.size() ) > maxSize )
+            {
 
-      if (!isGet && !isHit)
-      {
-        temp = new ElementDescriptor(ce);
-        temp.ce = ce;
-        temp.listNum = _T1_;
-        T1.addFirst(temp); /* seen once recently, put on T1 */
-        this.map.put(temp.ce.getKey(), temp);
-      } // end if put
-
-
-    if (temp == null)
-    {
-      return null;
-    }
-    return temp.ce;
-  }
-
-  /**
-   * This method doesn't so much replace as remove.  It pushes the least
-   * recently used in t1 or t2 to a dummy holder. The holder keeps a dummy 
object
-   * that stores the key so that subsequent gets and puts can help train the
-   * cache.  Items are spooled if there is a disk cache at this point.
-   *
-   * @param orig ElementDescriptor
-   */
-  public void replace(ElementDescriptor orig)
-  {
-    try
-    {
-      ElementDescriptor temp;
-      if (T1.size() >= Math.max(1, target_T1))
-      { // T1’s size exceeds target?
-        // yes: T1 is too big
-        temp = (ElementDescriptor) T1.getLast();
-        if (orig == null || !orig.key.equals(temp.key))
-        {
-          if (log.isDebugEnabled())
-          {
-            log.debug("replace -- T1 to B1");
-            log.debug(getStats());
-          }
-          temp = (ElementDescriptor) T1.removeLast(); // grab LRU from T1
-          // nullify object, temp is now just a dummy container to help
-          // adjust the lru size
-          try
-          {
-            this.waterfal(temp.ce);
-          }
-          catch (Exception e)
-          {
-            log.error(e);
-          }
-          temp.ce = null;
-          temp.listNum = _B1_; // note that fact
-          B1.addFirst(temp); // put it on B1
-          //T1Length—; B1Length++; // bookkeep
+                // no: T1 is not too big
+                temp = (ElementDescriptor) T2.getLast();
+                if ( orig == null || !orig.key.equals( temp.key ) )
+                {
+                    if ( log.isDebugEnabled() )
+                    {
+                        log.debug( "replace -- T2 to B2" );
+                        log.debug( getStats() );
+                    }
+
+                    temp = (ElementDescriptor) T2.removeLast(); // grab LRU 
page
+                    // of T2
+                    // nullify object, temp is now just a dummy container to
+                    // help
+                    // adjust the lru size
+                    try
+                    {
+                        this.waterfal( temp.ce );
+                    }
+                    catch ( Exception e )
+                    {
+                        log.error( e );
+                    }
+                    temp.ce = null;
+                    temp.listNum = _B2_; // note that fact
+                    B2.addFirst( temp ); // put it on B2
+                    // T2Length—; B2Length++; // bookkeep
+                }
+                else
+                {
+                    if ( log.isDebugEnabled() )
+                    {
+                        log.debug( "orig == temp, t2" );
+                    }
+                }
+            }
         }
-        else
+        catch ( Exception e )
         {
-          if (log.isDebugEnabled())
-          {
-            log.debug("orig == temp, t1");
-          }
-        }
-      }
-      else
-      // if t2 is greater than or equal to what is left in c after the target
-      if ( ( T2.size() + T1.size() ) > c )
-      {
-
-        // no: T1 is not too big
-        temp = (ElementDescriptor) T2.getLast();
-        if (orig == null || !orig.key.equals(temp.key))
-        {
-          if (log.isDebugEnabled())
-          {
-            log.debug("replace -- T2 to B2");
-            log.debug(getStats());
-          }
-
-          temp = (ElementDescriptor) T2.removeLast(); // grab LRU page of T2
-          // nullify object, temp is now just a dummy container to help
-          // adjust the lru size
-          try
-          {
-            this.waterfal(temp.ce);
-          }
-          catch (Exception e)
-          {
-            log.error(e);
-          }
-          temp.ce = null;
-          temp.listNum = _B2_; // note that fact
-          B2.addFirst(temp); // put it on B2
-          //T2Length—; B2Length++; // bookkeep
+            log.error( e );
         }
-        else
+    }
+
+    /**
+     * remove the element if it is in any of the lists.
+     * @param key
+     *            Serializable
+     * @return boolean
+     */
+    public boolean remove( Serializable key )
+    {
+        ElementDescriptor temp = (ElementDescriptor) map.remove( key );
+        if ( temp != null )
         {
-          if (log.isDebugEnabled())
-          {
-            log.debug("orig == temp, t2");
-          }
-        }
-      }
-    }
-    catch (Exception e)
-    {
-      log.error(e);
-    }
-  }
-
-  /**
-   * remove
-   *
-   * @param key Serializable
-   * @return boolean
-   */
-  public boolean remove(Serializable key)
-  {
-    ElementDescriptor temp = (ElementDescriptor) map.remove(key);
-    if ( temp != null ) {
-      int loc = temp.listNum;
-      if (loc == _T1_)
-      {
-        T1.remove(temp);
-      }
-      else
-      if (loc == _T2_)
-      {
-        T2.remove(temp);
-      }
-      else
-      if (loc == _B1_)
-      {
-        B1.remove(temp);
-      }
-      else
-      if (loc == _B2_)
-      {
-        B2.remove(temp);
-      }
-    }
-    return true;
-  }
-
-  /**
-   * Remove all of the elements from both the Map and the linked
-   * list implementation. Overrides base class.
-   */
-  public synchronized void removeAll() throws IOException
-  {
-    map.clear();
-    T1.removeAll();
-    T2.removeAll();
-    B1.removeAll();
-    B2.removeAll();
-  }
-
-  /////////////////////////////////////////////////////////////////////////
-  public String getStats()
-  {
-    return getStatistics().toString();
-  }
-
-  
-  /*
-   *  (non-Javadoc)
-   * @see org.apache.jcs.engine.memory.MemoryCache#getStatistics()
-   */
-  public IStats getStatistics()
-  {
-       IStats stats = new Stats();
-       stats.setTypeName( "LRU Memory Cache" );
-       
-       ArrayList elems = new ArrayList();
-       
-       IStatElement se = null;
-       
-       se = new StatElement();
-       se.setName( "T1 Size" );
-       se.setData("" + T1.size());
-       elems.add(se);
-
-       se = new StatElement();
-       se.setName( "T2 Size" );
-       se.setData("" + T2.size());
-       elems.add(se);
-       
-       se = new StatElement();
-       se.setName( "B1 Size" );
-       se.setData("" + B1.size());
-       elems.add(se);
-
-       se = new StatElement();
-       se.setName( "B2 Size" );
-       se.setData("" + B2.size());
-       elems.add(se);
-
-       se = new StatElement();
-       se.setName( "Target T1 Size" );
-       se.setData("" + target_T1);
-       elems.add(se);
-
-       se = new StatElement();
-       se.setName( "Map Size" );
-       se.setData("" + map.size());
-       elems.add(se);
-       
-       se = new StatElement();
-       se.setName( "Put Count" );
-       se.setData("" + putCnt);        
-       elems.add(se);
-       
-       se = new StatElement();
-       se.setName( "Hit Count" );
-       se.setData("" + hitCnt);
-       elems.add(se);
-
-       se = new StatElement();
-       se.setName( "Miss Count" );
-       se.setData("" + missCnt);
-       elems.add(se);
-       
-       // get an array and put them in the Stats object
-       IStatElement[] ses = (IStatElement[])elems.toArray( new StatElement[0] 
);
-       stats.setStatElements( ses );
-
-       // int rate = ((hitCnt + missCnt) * 100) / (hitCnt * 100) * 100;
-    //buf.append("\n Hit Rate = " + rate + " %" );
-       
-       return stats;
-  }   
-  
-/////////////////////////////////////////////////
-  public class ElementDescriptor
-      extends MemoryElementDescriptor
-  {
-    public int listNum;
-
-    public Serializable key;
+            int loc = temp.listNum;
+            if ( loc == _T1_ )
+            {
+                T1.remove( temp );
+            }
+            else if ( loc == _T2_ )
+            {
+                T2.remove( temp );
+            }
+            else if ( loc == _B1_ )
+            {
+                B1.remove( temp );
+            }
+            else if ( loc == _B2_ )
+            {
+                B2.remove( temp );
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Remove all of the elements from both the Map and the linked list
+     * implementation. Overrides base class.
+     */
+    public synchronized void removeAll()
+        throws IOException
+    {
+        map.clear();
+        T1.removeAll();
+        T2.removeAll();
+        B1.removeAll();
+        B2.removeAll();
+    }
 
-    public ElementDescriptor(ICacheElement ce)
+    // ///////////////////////////////////////////////////////////////////////
+    /**
+     * @return
+     */
+    public String getStats()
     {
-      super(ce);
-      key = ce.getKey();
+        return getStatistics().toString();
     }
 
-  }
+    /*
+     * (non-Javadoc)
+     * @see org.apache.jcs.engine.memory.MemoryCache#getStatistics()
+     */
+    public IStats getStatistics()
+    {
+        IStats stats = new Stats();
+        stats.setTypeName( "LRU Memory Cache" );
+
+        ArrayList elems = new ArrayList();
+
+        IStatElement se = null;
+
+        se = new StatElement();
+        se.setName( "T1 Size" );
+        se.setData( "" + T1.size() );
+        elems.add( se );
+
+        se = new StatElement();
+        se.setName( "T2 Size" );
+        se.setData( "" + T2.size() );
+        elems.add( se );
+
+        se = new StatElement();
+        se.setName( "B1 Size" );
+        se.setData( "" + B1.size() );
+        elems.add( se );
+
+        se = new StatElement();
+        se.setName( "B2 Size" );
+        se.setData( "" + B2.size() );
+        elems.add( se );
+
+        se = new StatElement();
+        se.setName( "Target T1 Size" );
+        se.setData( "" + target_T1 );
+        elems.add( se );
+
+        se = new StatElement();
+        se.setName( "Map Size" );
+        se.setData( "" + map.size() );
+        elems.add( se );
+
+        se = new StatElement();
+        se.setName( "Put Count" );
+        se.setData( "" + putCnt );
+        elems.add( se );
+
+        se = new StatElement();
+        se.setName( "Hit Count" );
+        se.setData( "" + hitCnt );
+        elems.add( se );
+
+        se = new StatElement();
+        se.setName( "Miss Count" );
+        se.setData( "" + missCnt );
+        elems.add( se );
+
+        // get an array and put them in the Stats object
+        IStatElement[] ses = (IStatElement[]) elems.toArray( new 
StatElement[0] );
+        stats.setStatElements( ses );
+
+        // int rate = ((hitCnt + missCnt) * 100) / (hitCnt * 100) * 100;
+        // buf.append("\n Hit Rate = " + rate + " %" );
+
+        return stats;
+    }
+
+    // ///////////////////////////////////////////////
+    /**
+     * @author Aaron Smuts
+     */
+    public class ElementDescriptor
+        extends MemoryElementDescriptor
+    {
+        private static final long serialVersionUID = -6271920830449238031L;
+
+        /** Where this is located */
+        public int listNum;
+
+        /** Its key */
+        public Serializable key;
+
+        /**
+         * Constructs a usable object
+         * @param ce
+         */
+        public ElementDescriptor( ICacheElement ce )
+        {
+            super( ce );
+            key = ce.getKey();
+        }
+    }
+
+    /**
+     * This is currently not implemented. It should remove items from t2. If
+     * there are none in t2, it should move them to t2 and then remove them.
+     * <p>
+     * (non-Javadoc)
+     * @see org.apache.jcs.engine.memory.MemoryCache#freeElements(int)
+     */
+    public int freeElements( int numberToFree )
+        throws IOException
+    {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    /**
+     * At the start this will be 1/2 the max.
+     * <p>
+     * @return Returns the target_T1.
+     */
+    protected int getTarget_T1()
+    {
+        return target_T1;
+    }
+
+    /**
+     * Returns the size of the list.
+     * @param listNumber
+     * @return -1 if the list is unknown.
+     */
+    protected int getListSize( int listNumber )
+    {
+        switch ( listNumber )
+        {
+            case _T1_:
+                return T1.size();
+
+            case _T2_:
+                return T2.size();
+
+            case _B1_:
+                return B1.size();
+
+            case _B2_:
+                return B2.size();
+        }
+        return -1;
+    }
 
 }

Added: 
jakarta/jcs/trunk/src/experimental/org/apache/jcs/engine/memory/arc/ARCMemoryCacheUnitTest.java
URL: 
http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/experimental/org/apache/jcs/engine/memory/arc/ARCMemoryCacheUnitTest.java?rev=430809&view=auto
==============================================================================
--- 
jakarta/jcs/trunk/src/experimental/org/apache/jcs/engine/memory/arc/ARCMemoryCacheUnitTest.java
 (added)
+++ 
jakarta/jcs/trunk/src/experimental/org/apache/jcs/engine/memory/arc/ARCMemoryCacheUnitTest.java
 Fri Aug 11 08:51:10 2006
@@ -0,0 +1,271 @@
+package org.apache.jcs.engine.memory.arc;
+
+import junit.framework.TestCase;
+
+import org.apache.jcs.JCS;
+import org.apache.jcs.access.exception.CacheException;
+import org.apache.jcs.engine.CacheElement;
+import org.apache.jcs.engine.behavior.ICacheElement;
+import org.apache.jcs.engine.control.CompositeCache;
+import org.apache.jcs.engine.control.CompositeCacheManager;
+
+/**
+ * Initial tests for the ARCMemoryCache
+ * <p>
+ * @author Aaron Smuts
+ */
+public class ARCMemoryCacheUnitTest
+    extends TestCase
+{
+    /**
+     * Test setup
+     */
+    public void setUp()
+    {
+        JCS.setConfigFilename( "/TestARCCache.ccf" );
+    }
+
+    /**
+     * Put a few items on, get them, and then remove them.
+     * @throws CacheException
+     */
+    public void testPutGetRemoveThroughHub()
+        throws CacheException
+    {
+        JCS cache = JCS.getInstance( "testPutGetThroughHub" );
+
+        int max = cache.getCacheAttributes().getMaxObjects();
+        int items = max * 2;
+
+        for ( int i = 0; i < items; i++ )
+        {
+            cache.put( i + ":key", "myregion" + " data " + i );
+        }
+
+        // Test that first items are not in the cache
+        for ( int i = max; i >= 0; i-- )
+        {
+            String value = (String) cache.get( i + ":key" );
+            assertNull( "Should not have value for key [" + i + ":key" + "] in 
the cache.", value );
+        }
+
+        // Test that last items are in cache
+        // skip 2 for the buffer.
+        for ( int i = max + 2; i < items; i++ )
+        {
+            String value = (String) cache.get( i + ":key" );
+            assertEquals( "myregion" + " data " + i, value );
+        }
+
+        System.out.println( cache.getStats() );
+    }
+
+    /**
+     * Put half the max, get the key array, and verify that it has the correct
+     * number of items.
+     * <p>
+     * @throws Exception
+     */
+    public void testGetKeyArray()
+        throws Exception
+    {
+        CompositeCacheManager cacheMgr = 
CompositeCacheManager.getUnconfiguredInstance();
+        cacheMgr.configure( "/TestARCCache.ccf" );
+        CompositeCache cache = cacheMgr.getCache( "testGetKeyArray" );
+
+        ARCMemoryCache arc = new ARCMemoryCache();
+        arc.initialize( cache );
+
+        int max = cache.getCacheAttributes().getMaxObjects();
+        int items = max / 2;
+
+        for ( int i = 0; i < items; i++ )
+        {
+            ICacheElement ice = new CacheElement( cache.getCacheName(), i + 
":key", cache.getCacheName() + " data " + i );
+            ice.setElementAttributes( cache.getElementAttributes() );
+            arc.update( ice );
+        }
+
+        System.out.println( "testGetKeyArray " + arc.getStats() );
+
+        Object[] keys = arc.getKeyArray();
+        assertEquals( "Wrong number of keys.", items, keys.length );
+        assertEquals( "Target t1 should be 1/2 until dupe gets or puts.", max 
/ 2, arc.getTarget_T1() );
+    }
+
+    /**
+     * Put half the max and then get the first element.  It should now be in 
t2.
+     * <p>
+     * @throws Exception
+     */
+    public void testHitInT1BelowMax()
+        throws Exception
+    {
+        CompositeCacheManager cacheMgr = 
CompositeCacheManager.getUnconfiguredInstance();
+        cacheMgr.configure( "/TestARCCache.ccf" );
+        CompositeCache cache = cacheMgr.getCache( "testGetKeyArray" );
+
+        ARCMemoryCache arc = new ARCMemoryCache();
+        arc.initialize( cache );
+
+        int max = cache.getCacheAttributes().getMaxObjects();
+        int items = max / 2;
+
+        for ( int i = 0; i < items; i++ )
+        {
+            ICacheElement ice = new CacheElement( cache.getCacheName(), i + 
":key", cache.getCacheName() + " data " + i );
+            ice.setElementAttributes( cache.getElementAttributes() );
+            arc.update( ice );
+        }
+
+        ICacheElement element = arc.get( 0 + ":key" );
+
+        System.out.println( "testHitInT1BelowMax " + arc.getStats() );
+
+        assertNotNull( "Should have the element.", element );
+        assertEquals( "Target t1 should be 1/2 until dupe gets or puts.", max 
/ 2, arc.getTarget_T1() );
+        
+        assertEquals( "T2 should have one item.", 1, arc.getListSize( 
ARCMemoryCache._T2_ ) );
+    }
+
+    /**
+     * Put half the max and then get the first element. then get it again.  ti 
shoudl be in t2
+     * <p>
+     * @throws Exception
+     */
+    public void testHitInT1ThenT2BelowMax()
+        throws Exception
+    {
+        CompositeCacheManager cacheMgr = 
CompositeCacheManager.getUnconfiguredInstance();
+        cacheMgr.configure( "/TestARCCache.ccf" );
+        CompositeCache cache = cacheMgr.getCache( "testGetKeyArray" );
+
+        ARCMemoryCache arc = new ARCMemoryCache();
+        arc.initialize( cache );
+
+        int max = cache.getCacheAttributes().getMaxObjects();
+        int items = max / 2;
+
+        for ( int i = 0; i < items; i++ )
+        {
+            ICacheElement ice = new CacheElement( cache.getCacheName(), i + 
":key", cache.getCacheName() + " data " + i );
+            ice.setElementAttributes( cache.getElementAttributes() );
+            arc.update( ice );
+        }
+
+        ICacheElement element = arc.get( 0 + ":key" );
+
+        System.out.println( "testHitInT1ThenT2BelowMax " + arc.getStats() );
+
+        assertNotNull( "Should have the element.", element );
+        assertEquals( "Target t1 should be 1/2 until dupe gets or puts.", max 
/ 2, arc.getTarget_T1() );
+        
+        assertEquals( "T2 should have one item.", 1, arc.getListSize( 
ARCMemoryCache._T2_ ) );
+    }   
+    
+    /**
+     * Put half the max and then get the first element.  It should now be in 
t2.
+     * <p>
+     * @throws Exception
+     */
+    public void testHitInT1AtMax()
+        throws Exception
+    {
+        CompositeCacheManager cacheMgr = 
CompositeCacheManager.getUnconfiguredInstance();
+        cacheMgr.configure( "/TestARCCache.ccf" );
+        CompositeCache cache = cacheMgr.getCache( "testGetKeyArray" );
+
+        ARCMemoryCache arc = new ARCMemoryCache();
+        arc.initialize( cache );
+
+        int max = cache.getCacheAttributes().getMaxObjects();
+        int items = max;
+
+        for ( int i = 0; i < items; i++ )
+        {
+            ICacheElement ice = new CacheElement( cache.getCacheName(), i + 
":key", cache.getCacheName() + " data " + i );
+            ice.setElementAttributes( cache.getElementAttributes() );
+            arc.update( ice );
+        }
+
+        ICacheElement element = arc.get( 0 + ":key" );
+
+        System.out.println( "testHitInT1AtMax " + arc.getStats() );
+
+        assertNotNull( "Should have the element.", element );
+        assertEquals( "Target t1 should be 1/2 until dupe gets or puts.", max 
/ 2, arc.getTarget_T1() );
+        
+        assertEquals( "T2 should have one item.", 1, arc.getListSize( 
ARCMemoryCache._T2_ ) );
+    }  
+    
+    /**
+     * Put half the max and then get the first element.  It should now be in 
t2.
+     * <p>
+     * @throws Exception
+     */
+    public void SKIPtestHitInT1OverMax()
+        throws Exception
+    {
+        CompositeCacheManager cacheMgr = 
CompositeCacheManager.getUnconfiguredInstance();
+        cacheMgr.configure( "/TestARCCache.ccf" );
+        CompositeCache cache = cacheMgr.getCache( "testGetKeyArray" );
+
+        ARCMemoryCache arc = new ARCMemoryCache();
+        arc.initialize( cache );
+
+        int max = cache.getCacheAttributes().getMaxObjects();
+        int items = max + 1;
+
+        for ( int i = 0; i < items; i++ )
+        {
+            ICacheElement ice = new CacheElement( cache.getCacheName(), i + 
":key", cache.getCacheName() + " data " + i );
+            ice.setElementAttributes( cache.getElementAttributes() );
+            arc.update( ice );
+        }
+
+        ICacheElement element = arc.get( 0 + ":key" );
+
+        System.out.println( "testHitInT1OverMax " + arc.getStats() );
+
+        assertNull( "Should not have the element since it was the first.", 
element );
+        assertEquals( "Target t1 should be 1/2 until dupe gets or puts.", max 
/ 2, arc.getTarget_T1() );
+        
+        assertEquals( "T2 should have one item.", 1, arc.getListSize( 
ARCMemoryCache._T2_ ) );
+    }     
+    
+    /**
+     * Put half the max and then get the first element.  It should now be in 
t2.
+     * <p>
+     * @throws Exception
+     */
+    public void testPutInT1ToMax()
+        throws Exception
+    {
+        CompositeCacheManager cacheMgr = 
CompositeCacheManager.getUnconfiguredInstance();
+        cacheMgr.configure( "/TestARCCache.ccf" );
+        CompositeCache cache = cacheMgr.getCache( "testGetKeyArray" );
+
+        ARCMemoryCache arc = new ARCMemoryCache();
+        arc.initialize( cache );
+
+        int max = cache.getCacheAttributes().getMaxObjects();
+        int items = max;
+
+        for ( int i = 0; i < items; i++ )
+        {
+            ICacheElement ice = new CacheElement( cache.getCacheName(), i + 
":key", cache.getCacheName() + " data " + i );
+            ice.setElementAttributes( cache.getElementAttributes() );
+            arc.update( ice );
+        }
+
+        //ICacheElement element = arc.get( 0 + ":key" );
+
+        System.out.println( "testPutInT1ToMax " + arc.getStats() );
+
+        //assertNotNull( "Should have the element.", element );
+        assertEquals( "Target t1 should be 1/2 until dupe gets or puts.", max 
/ 2, arc.getTarget_T1() );
+        
+        assertEquals( "Wrong number of items in T1.", max, arc.getListSize( 
ARCMemoryCache._T1_ ) );
+        assertEquals( "Wrong number of items in T2.", 0, arc.getListSize( 
ARCMemoryCache._T2_ ) );
+    }  
+}

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=430809&r1=430808&r2=430809&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 Aug 
11 08:51:10 2006
@@ -567,4 +567,32 @@
     {
         this.cacheControl.setCacheAttributes( cattr );
     }
+
+    /**
+     * This instructs the memory cache to remove the <i>numberToFree</i>
+     * according to its eviction policy. For example, the LRUMemoryCache will
+     * remove the <i>numberToFree</i> least recently used items. These will be
+     * spooled to disk if a disk auxiliary is available.
+     * <p>
+     * @param numberToFree
+     * @return the number that were removed. if you ask to free 5, but there 
are
+     *         only 3, you will get 3.
+     * @throws CacheException
+     */
+    public int freeMemoryElements( int numberToFree )
+        throws CacheException
+    {
+        int numFreed = -1;
+        try
+        {
+            numFreed = this.cacheControl.getMemoryCache().freeElements( 
numberToFree );
+        }
+        catch ( IOException ioe )
+        {
+            String message = "Failure freeing memory elements.  ";
+            log.error( message, ioe );
+            throw new CacheException( message + ioe.getMessage() );
+        }
+        return numFreed;
+    }
 }

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=430809&r1=430808&r2=430809&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 Aug 11 08:51:10 2006
@@ -159,4 +159,17 @@
      */
     public void setCacheAttributes( ICompositeCacheAttributes cattr );
 
+    /**
+     * This instructs the memory cache to remove the <i>numberToFree</i>
+     * according to its eviction policy. For example, the LRUMemoryCache will
+     * remove the <i>numberToFree</i> least recently used items. These will be
+     * spooled to disk if a disk auxiliary is available.
+     * <p>
+     * @param numberToFree
+     * @return the number that were removed. if you ask to free 5, but there 
are
+     *         only 3, you will get 3.
+     * @throws CacheException
+     */
+    public int freeMemoryElements( int numberToFree )
+        throws CacheException;
 }

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=430809&r1=430808&r2=430809&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 Aug 11 08:51:10 2006
@@ -34,7 +34,6 @@
 /**
  * Lateral distributor. Returns null on get by default. Net search not
  * implemented.
- *  
  */
 public class LateralCache
     implements ICache
@@ -55,7 +54,7 @@
     
     /**
      * Constructor for the LateralCache object
-     * 
+     * <p>
      * @param cattr
      * @param lateral
      * @param monitor
@@ -70,7 +69,7 @@
 
     /**
      * Constructor for the LateralCache object
-     * 
+     * <p>
      * @param cattr
      */
     protected LateralCache( ILateralCacheAttributes cattr )
@@ -81,7 +80,7 @@
 
     /**
      * Update lateral.
-     * 
+     * <p>
      * @param ce
      * @throws IOException
      */
@@ -92,7 +91,7 @@
         {
             if ( log.isDebugEnabled() )
             {
-                log.debug( "update: lateral = " + lateral + ", " + 
"LateralCacheInfo.listenerId = "
+                log.debug( "update: lateral = [" + lateral + "], " + 
"LateralCacheInfo.listenerId = "
                     + LateralCacheInfo.listenerId );
             }
             lateral.update( ce, LateralCacheInfo.listenerId );
@@ -100,21 +99,19 @@
         catch ( NullPointerException npe )
         {
             log.error( "Failure updating lateral. lateral = " + lateral, npe );
-            handleException( npe, "Failed to put " + ce.getKey() + " to " + 
ce.getCacheName() );
+            handleException( npe, "Failed to put [" + ce.getKey() + "] to " + 
ce.getCacheName() );
             return;
         }
         catch ( Exception ex )
         {
-            handleException( ex, "Failed to put " + ce.getKey() + " to " + 
ce.getCacheName() );
+            handleException( ex, "Failed to put [" + ce.getKey() + "] to " + 
ce.getCacheName() );
         }
     }
 
-    // end update
-
     /**
      * The performace costs are too great. It is not recommended that you 
enable
      * lateral gets.
-     * 
+     * <p>
      * @param key
      * @return
      * @throws IOException
@@ -153,7 +150,7 @@
     /**
      * Synchronously remove from the remote cache; if failed, replace the 
remote
      * handle with a zombie.
-     * 
+     * <p>
      * @param key
      * @return
      * @throws IOException
@@ -165,10 +162,6 @@
 
         try
         {
-            //DeleteLateralCacheMulticaster dlcm = new
-            // DeleteLateralCacheMulticaster( cattr.getCacheName(), 
(String)key,
-            // cattr.getLateralCacheAddrs(), cattr.getLateralDeleteServlet() );
-            //dlcm.multicast();
             lateral.remove( cacheName, key, LateralCacheInfo.listenerId );
         }
         catch ( Exception ex )
@@ -181,7 +174,7 @@
     /**
      * Synchronously removeAll from the remote cache; if failed, replace the
      * remote handle with a zombie.
-     * 
+     * <p>
      * @throws IOException
      */
     public void removeAll()
@@ -189,10 +182,6 @@
     {
         try
         {
-            //DeleteLateralCacheMulticaster dlcm = new
-            // DeleteLateralCacheMulticaster( cattr.getCacheName(), "ALL",
-            // cattr.getLateralCacheAddrs(), cattr.getLateralDeleteServlet() );
-            //dlcm.multicast();
             lateral.removeAll( cacheName, LateralCacheInfo.listenerId );
         }
         catch ( Exception ex )
@@ -230,7 +219,7 @@
 
     /**
      * Returns the cache status.
-     * 
+     * <p>
      * @return The status value
      */
     public int getStatus()
@@ -240,7 +229,7 @@
 
     /**
      * Returns the current cache size.
-     * 
+     * <p>
      * @return The size value
      */
     public int getSize()
@@ -250,7 +239,7 @@
 
     /**
      * Gets the cacheType attribute of the LateralCache object
-     * 
+     * <p>
      * @return The cacheType value
      */
     public int getCacheType()
@@ -260,7 +249,7 @@
 
     /**
      * Gets the cacheName attribute of the LateralCache object
-     * 
+     * <p>
      * @return The cacheName value
      */
     public String getCacheName()
@@ -270,7 +259,7 @@
 
     /**
      * Not yet sure what to do here.
-     * 
+     * <p>
      * @param ex
      * @param msg
      * @throws IOException
@@ -278,7 +267,6 @@
     private void handleException( Exception ex, String msg )
         throws IOException
     {
-
         log.error( "Disabling lateral cache due to error " + msg, ex );
 
         lateral = new ZombieLateralCacheService();
@@ -297,7 +285,7 @@
 
     /**
      * Replaces the current remote cache service handle with the given handle.
-     * 
+     * <p>
      * @param lateral
      */
     public void fixCache( ILateralCacheService lateral )
@@ -315,7 +303,7 @@
 
     /**
      * getStats
-     * 
+     * <p>
      * @return String
      */
     public String getStats()

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=430809&r1=430808&r2=430809&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 Aug 11 08:51:10 2006
@@ -42,7 +42,6 @@
 /**
  * Used to queue up update requests to the underlying cache. These requests 
will
  * be processed in their order of arrival via the cache event queue processor.
- *  
  */
 public class LateralCacheNoWait
     implements AuxiliaryCache
@@ -107,13 +106,12 @@
 
     /**
      * Synchronously reads from the lateral cache.
-     * 
+     * <p>
      * @param key
      * @return ICacheElement if found, else null
      */
     public ICacheElement get( Serializable key )
     {
-
         if ( this.getStatus() != CacheConstants.STATUS_ERROR )
         {
             try

Modified: 
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/LateralElementDescriptor.java
URL: 
http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/LateralElementDescriptor.java?rev=430809&r1=430808&r2=430809&view=diff
==============================================================================
--- 
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/LateralElementDescriptor.java
 (original)
+++ 
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/LateralElementDescriptor.java
 Fri Aug 11 08:51:10 2006
@@ -1,19 +1,14 @@
 package org.apache.jcs.auxiliary.lateral;
 
 /*
- * 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;
@@ -21,16 +16,15 @@
 import org.apache.jcs.engine.behavior.ICacheElement;
 
 /**
- * This class wraps command to other laterals.
- * 
+ * This class wraps command to other laterals. It is essentially a
+ * JCS-TCP-Lateral packet. The headers specify the action the receiver should
+ * take.
  */
 public class LateralElementDescriptor
     implements Serializable
 {
-
     private static final long serialVersionUID = 5268222498076063575L;
 
-    // command types
     /** The int for updates */
     public final static int UPDATE = 1;
 
@@ -63,7 +57,6 @@
      */
     public int valHashCode = -1;
 
-    // for update command
     /** Constructor for the LateralElementDescriptor object */
     public LateralElementDescriptor()
     {
@@ -72,12 +65,24 @@
 
     /**
      * Constructor for the LateralElementDescriptor object
-     * 
-     * @param ce
+     * <p>
+     * @param ce ICacheElement payload
      */
     public LateralElementDescriptor( ICacheElement ce )
     {
         this.ce = ce;
     }
-
+    
+    /**
+     * @return String, all the important values that can be configured
+     */
+    public String toString()
+    {
+        StringBuffer buf = new StringBuffer();
+        buf.append( "\n LateralElementDescriptor " );
+        buf.append( "\n command = [" + this.command + "]" );
+        buf.append( "\n valHashCode = [" + this.valHashCode + "]" );
+        buf.append( "\n ICacheElement = [" + this.ce + "]" );
+        return buf.toString();
+    }    
 }

Modified: 
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPCacheManager.java
URL: 
http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPCacheManager.java?rev=430809&r1=430808&r2=430809&view=diff
==============================================================================
--- 
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPCacheManager.java
 (original)
+++ 
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPCacheManager.java
 Fri Aug 11 08:51:10 2006
@@ -84,7 +84,7 @@
 
     /**
      * Returns an instance of the LateralCacheManager.
-     * 
+     * <p>
      * @param lca
      * @param cacheMgr
      *            this allows the auxiliary to be passed a cache manager.
@@ -115,9 +115,9 @@
 
     /**
      * The monitor needs reference to one instance, acutally just a type.
-     * 
-     * refactor this.
-     * 
+     * <p>
+     * TODO refactor this.
+     * <p>
      * @param instance
      */
     private static synchronized void createMonitor( ILateralCacheManager 
instance )
@@ -139,7 +139,7 @@
 
     /**
      * Constructor for the LateralCacheManager object.
-     * 
+     * <p>
      * @param lcaA
      * @param cacheMgr
      */
@@ -192,7 +192,7 @@
 
     /**
      * Adds the lateral cache listener to the underlying cache-watch service.
-     * 
+     * <p>
      * @param cacheName
      *            The feature to be added to the LateralCacheListener attribute
      * @param listener
@@ -218,7 +218,7 @@
      * <p>
      * There should be one manager per server and one cache per region per
      * manager.
-     * 
+     * <p>
      * @return AuxiliaryCache
      * @param cacheName
      */

Modified: 
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPListener.java
URL: 
http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPListener.java?rev=430809&r1=430808&r2=430809&view=diff
==============================================================================
--- 
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPListener.java
 (original)
+++ 
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/socket/tcp/LateralTCPListener.java
 Fri Aug 11 08:51:10 2006
@@ -1,19 +1,14 @@
 package org.apache.jcs.auxiliary.lateral.socket.tcp;
 
 /*
- * 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;
@@ -40,8 +35,10 @@
 import EDU.oswego.cs.dl.util.concurrent.ThreadFactory;
 
 /**
- * Listens for connections from other TCP lateral caches and handles them.
- *  
+ * Listens for connections from other TCP lateral caches and handles them. The
+ * initialization method starts a listening thread, which creates a socket
+ * server. When messages are received they are passed to a pooled executor 
which
+ * then calls the appropriate handle method.
  */
 public class LateralTCPListener
     implements ILateralCacheListener, Serializable
@@ -59,8 +56,6 @@
     /** Map of available instances, keyed by port */
     protected final static HashMap instances = new HashMap();
 
-    // ----------------------------------------------------- instance variables
-
     /** The socket listener */
     private ListenerThread receiver;
 
@@ -74,17 +69,17 @@
 
     private int removeCnt = 0;
 
+    private int getCnt = 0;
+
     /**
      * Use the vmid by default. This can be set for testing. If we ever need to
      * run more than one per vm, then we need a new technique.
      */
     private long listenerId = LateralCacheInfo.listenerId;
 
-    // -------------------------------------------------------- factory methods
-
     /**
      * Gets the instance attribute of the LateralCacheTCPListener class.
-     * 
+     * <p>
      * @param ilca
      *            ITCPLateralCacheAttributes
      * @param cacheMgr
@@ -114,12 +109,10 @@
         return ins;
     }
 
-    // ------------------------------------------------------- instance methods
-
     /**
      * Only need one since it does work for all regions, just reference by
      * multiple region names.
-     * 
+     * <p>
      * @param ilca
      */
     protected LateralTCPListener( ITCPLateralCacheAttributes ilca )
@@ -152,7 +145,7 @@
     }
 
     /**
-     * let the lateral cache set a listener_id. Since there is only one
+     * Let the lateral cache set a listener_id. Since there is only one
      * listerenr for all the regions and every region gets registered? the id
      * shouldn't be set if it isn't zero. If it is we assume that it is a
      * reconnect.
@@ -164,7 +157,7 @@
      * <p>
      * The service will use the value it sets in all send requests to the
      * sender.
-     * 
+     * <p>
      * @param id
      *            The new listenerId value
      * @throws IOException
@@ -181,7 +174,7 @@
 
     /**
      * Gets the listenerId attribute of the LateralCacheTCPListener object
-     * 
+     * <p>
      * @return The listenerId value
      * @throws IOException
      */
@@ -191,9 +184,10 @@
         return this.listenerId;
     }
 
-    /*
-     * (non-Javadoc)
-     * 
+    /**
+     * Increments the put count. Gets the cache that was injected by the 
lateral
+     * factory. Calls put on the cache.
+     * <p>
      * @see 
org.apache.jcs.engine.behavior.ICacheListener#handlePut(org.apache.jcs.engine.behavior.ICacheElement)
      */
     public void handlePut( ICacheElement element )
@@ -217,9 +211,10 @@
         getCache( element.getCacheName() ).localUpdate( element );
     }
 
-    /*
-     * (non-Javadoc)
-     * 
+    /**
+     * Increments the remove count. Gets the cache that was injected by the
+     * lateral factory. Calls remove on the cache.
+     * <p>
      * @see 
org.apache.jcs.engine.behavior.ICacheListener#handleRemove(java.lang.String,
      *      java.io.Serializable)
      */
@@ -243,14 +238,15 @@
         getCache( cacheName ).localRemove( key );
     }
 
-    /*
-     * (non-Javadoc)
-     * 
+    /**
+     * Gets the cache that was injected by the lateral factory. Calls removeAll
+     * on the cache.
+     * <p>
      * @see 
org.apache.jcs.engine.behavior.ICacheListener#handleRemoveAll(java.lang.String)
      */
     public void handleRemoveAll( String cacheName )
         throws IOException
-    {
+    {       
         if ( log.isDebugEnabled() )
         {
             log.debug( "handleRemoveAll> cacheName=" + cacheName );
@@ -260,6 +256,9 @@
     }
 
     /**
+     * Gets the cache that was injected by the lateral factory. Calls get on 
the
+     * cache.
+     * <p>
      * @param cacheName
      * @param key
      * @return Serializable
@@ -268,6 +267,16 @@
     public Serializable handleGet( String cacheName, Serializable key )
         throws IOException
     {
+        getCnt++;
+        if ( log.isInfoEnabled() )
+        {
+            if ( getGetCnt() % 100 == 0 )
+            {
+                log.info( "Get Count (port " + 
getTcpLateralCacheAttributes().getTcpListenerPort() + ") = "
+                    + getGetCnt() );
+            }
+        }
+        
         if ( log.isDebugEnabled() )
         {
             log.debug( "handleGet> cacheName=" + cacheName + ", key = " + key 
);
@@ -276,9 +285,9 @@
         return getCache( cacheName ).localGet( key );
     }
 
-    /*
-     * (non-Javadoc)
-     * 
+    /**
+     * Right now this does nothing.
+     * <p>
      * @see 
org.apache.jcs.engine.behavior.ICacheListener#handleDispose(java.lang.String)
      */
     public void handleDispose( String cacheName )
@@ -291,7 +300,7 @@
 
         // TODO handle active deregistration, rather than passive detection
         // through error
-        //getCacheManager().freeCache( cacheName, true );
+        // getCacheManager().freeCache( cacheName, true );
     }
 
     /**
@@ -299,7 +308,7 @@
      * <p>
      * Normally this is set by the factory. If it wasn't set the listener
      * defaults to the expected singleton behavior of the cache amanger.
-     * 
+     * <p>
      * @param name
      * @return CompositeCache
      */
@@ -319,11 +328,9 @@
         return getCacheManager().getCache( name );
     }
 
-    // ---------------------------------------------------------- inner classes
-
     /**
      * This is roughly the number of updates the lateral has received.
-     * 
+     * <p>
      * @return Returns the putCnt.
      */
     public int getPutCnt()
@@ -332,13 +339,21 @@
     }
 
     /**
+     * @return Returns the getCnt.
+     */
+    public int getGetCnt()
+    {
+        return getCnt;
+    }
+
+    /**
      * @return Returns the removeCnt.
      */
     public int getRemoveCnt()
     {
         return removeCnt;
     }
-
+    
     /**
      * @param cacheMgr
      *            The cacheMgr to set.
@@ -421,7 +436,8 @@
     }
 
     /**
-     * A Separate thread taht runs when a command comes into the 
LateralTCPReceiver.
+     * A Separate thread taht runs when a command comes into the
+     * LateralTCPReceiver.
      */
     public class ConnectionHandler
         implements Runnable
@@ -430,7 +446,6 @@
 
         /**
          * Construct for a given socket
-         * 
          * @param socket
          */
         public ConnectionHandler( Socket socket )
@@ -511,7 +526,7 @@
         /**
          * This calls the appropriate method, based on the command sent in the
          * Lateral element descriptor.
-         * 
+         * <p>
          * @param led
          * @throws IOException
          */
@@ -541,19 +556,21 @@
                             {
                                 if ( log.isDebugEnabled() )
                                 {
-                                    log.debug( "Filtering detected identical 
hashCode [" + led.valHashCode + "], not issuing a remove for led " + led );
-                                }                                
+                                    log.debug( "Filtering detected identical 
hashCode [" + led.valHashCode
+                                        + "], not issuing a remove for led " + 
led );
+                                }
                                 return;
                             }
                             else
                             {
                                 if ( log.isDebugEnabled() )
                                 {
-                                    log.debug( "Different hashcodes, in cache 
[" + test.getVal().hashCode() + "] sent [" + led.valHashCode + "]" );
+                                    log.debug( "Different hashcodes, in cache 
[" + test.getVal().hashCode()
+                                        + "] sent [" + led.valHashCode + "]" );
                                 }
                             }
                         }
-                    }        
+                    }
                 }
                 handleRemove( cacheName, key );
             }
@@ -578,16 +595,14 @@
 
     /**
      * Allows us to set the daemon status on the executor threads
-     * 
+     * <p>
      * @author aaronsm
-     *  
      */
     class MyThreadFactory
         implements ThreadFactory
     {
         /*
          * (non-Javadoc)
-         * 
          * @see 
EDU.oswego.cs.dl.util.concurrent.ThreadFactory#newThread(java.lang.Runnable)
          */
         public Thread newThread( Runnable runner )

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=430809&r1=430808&r2=430809&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 Aug 11 08:51:10 2006
@@ -29,7 +29,8 @@
 
 /**
  * This class is based on the log4j SocketAppender class. I'm using a differnet
- * repair structure, so it is significant;y different.
+ * repair structure, so it is significantly different.
+ * <p>
  * @version $Id$
  */
 public class LateralTCPSender
@@ -98,7 +99,7 @@
 
             if ( h2 == null )
             {
-                throw new IOException( "Cannot connect to invalid address " + 
h2 + ":" + po );
+                throw new IOException( "Cannot connect to invalid address [" + 
h2 + ":" + po + "]" );
             }
 
             init( h2, po );
@@ -121,7 +122,10 @@
 
         try
         {
-            log.debug( "Attempting connection to " + address.getHostName() );
+            if ( log.isInfoEnabled() )
+            {
+                log.info( "Attempting connection to [" + address.getHostName() 
+ "]" );
+            }
 
             // have time out socket open do this for us
             socket = SocketOpener.openSocket( host, port, openTimeOut );
@@ -139,15 +143,14 @@
         }
         catch ( java.net.ConnectException e )
         {
-            log.debug( "Remote host " + address.getHostName() + " refused 
connection." );
+            log.debug( "Remote host [" + address.getHostName() + "] refused 
connection." );
             throw e;
         }
         catch ( IOException e )
         {
-            log.debug( "Could not connect to " + address.getHostName() + ". 
Exception is " + e );
+            log.debug( "Could not connect to [" + address.getHostName() + "]. 
Exception is " + e );
             throw e;
         }
-
     }
 
     /**
@@ -202,7 +205,6 @@
         if ( address == null )
         {
             throw new IOException( "No remote host is set for 
LateralTCPSender." );
-            // return;
         }
 
         if ( oos != null )
@@ -271,7 +273,6 @@
             {
                 try
                 {
-
                     try
                     {
                         // clean up input stream, nothing should be there yet.
@@ -292,6 +293,8 @@
 
                     try
                     {
+                        // TODO make configurable
+                        //socket.setSoTimeout( 2000 );
                         ObjectInputStream ois = new ObjectInputStream( 
socket.getInputStream() );
                         Object obj = ois.readObject();
                         ice = (ICacheElement) obj;
@@ -303,7 +306,12 @@
                     }
                     catch ( IOException ioe )
                     {
-                        log.error( "Could not open ObjectInputStream to " + 
socket, ioe );
+                        String message = "Could not open ObjectInputStream to 
" + socket;
+                        if ( socket!= null )
+                        {
+                            message += " SoTimeout [" + socket.getSoTimeout() 
+"] Connected [" + socket.isConnected() + "]";
+                        }
+                        log.error( message, ioe );
                         throw ioe;
                     }
                     catch ( Exception e )
@@ -329,10 +337,8 @@
                 }
             }
         } 
-        // end synchronized block
 
         return ice;
-
     }
 
     /**
@@ -420,5 +426,4 @@
             System.out.println( e.toString() );
         }
     }
-
 }

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=430809&r1=430808&r2=430809&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 Aug 11 08:51:10 2006
@@ -1,19 +1,14 @@
 package org.apache.jcs.auxiliary.lateral.socket.tcp;
 
 /*
- * 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.BufferedReader;
@@ -35,7 +30,7 @@
 
 /**
  * A lateral cache service implementation. Does not implement getGroupKey
- * 
+ * <p>
  * @version $Id$
  */
 public class LateralTCPService
@@ -54,7 +49,7 @@
 
     /**
      * Constructor for the LateralTCPService object
-     * 
+     * <p>
      * @param lca
      *            ITCPLateralCacheAttributes
      * @exception IOException
@@ -69,7 +64,10 @@
 
             sender = new LateralTCPSender( lca );
 
-            log.debug( "created sender" );
+            if ( log.isInfoEnabled() )
+            {
+                log.debug( "Created sender to [" + lca.getTcpServer() + "]" ); 
               
+            }
         }
         catch ( IOException e )
         {
@@ -82,12 +80,9 @@
         }
     }
 
-    // -------------------------------------------------------- Service Methods
-
     /**
      * @param item
      * @throws IOException
-     * 
      */
     public void update( ICacheElement item )
         throws IOException
@@ -95,16 +90,18 @@
         update( item, getListenerId() );
     }
 
-    /*
-     * (non-Javadoc)
-     * 
+    /**
+     * If put is allowed, we will issue a put. If issue put on remove
+     * is configured, we will issue a remove. Either way, we create a lateral
+     * element descriptor, which is essentially a JCS TCP packet. It describes
+     * what operation the receiver should take when it gets the packet.
+     * <p>
      * @see 
org.apache.jcs.auxiliary.lateral.behavior.ILateralCacheService#update(org.apache.jcs.engine.behavior.ICacheElement,
      *      long)
      */
     public void update( ICacheElement item, long requesterId )
         throws IOException
     {
-
         // if we don't allow put, see if we should remove on put
         if ( !this.getTcpLateralCacheAttributes().isAllowPut() )
         {
@@ -129,7 +126,7 @@
         {
             if ( log.isDebugEnabled() )
             {
-                log.debug( "Issuing a remvoe for a put" );
+                log.debug( "Issuing a remove for a put" );
             }
             // set the value to null so we don't send the item
             CacheElement ce = new CacheElement( item.getCacheName(), 
item.getKey(), null );
@@ -141,9 +138,9 @@
         }
     }
 
-    /*
-     * (non-Javadoc)
-     * 
+    /**
+     * Uses the default listener id and calls the next remove method.
+     * <p>
      * @see 
org.apache.jcs.engine.behavior.ICacheService#remove(java.lang.String,
      *      java.io.Serializable)
      */
@@ -153,9 +150,9 @@
         remove( cacheName, key, getListenerId() );
     }
 
-    /*
-     * (non-Javadoc)
-     * 
+    /**
+     * Wraps the key in a LateralElementDescriptor.
+     * <p>
      * @see 
org.apache.jcs.auxiliary.lateral.behavior.ILateralCacheService#remove(java.lang.String,
      *      java.io.Serializable, long)
      */
@@ -171,7 +168,6 @@
 
     /*
      * (non-Javadoc)
-     * 
      * @see org.apache.jcs.engine.behavior.ICacheService#release()
      */
     public void release()
@@ -182,7 +178,7 @@
 
     /**
      * Will close the connection.
-     * 
+     * <p>
      * @param cache
      * @throws IOException
      */
@@ -193,8 +189,8 @@
     }
 
     /**
-     * The service does not get via this method, so this return null
-     * 
+     * The service does not get via this method, so this return null.
+     * <p>
      * @param key
      * @return always null.
      * @throws IOException
@@ -214,7 +210,6 @@
 
     /*
      * (non-Javadoc)
-     * 
      * @see org.apache.jcs.engine.behavior.ICacheService#get(java.lang.String,
      *      java.io.Serializable)
      */
@@ -240,7 +235,7 @@
     /**
      * Gets the set of keys of objects currently in the group throws
      * UnsupportedOperationException
-     * 
+     * <p>
      * @param cacheName
      * @param group
      * @return Set
@@ -256,7 +251,6 @@
 
     /*
      * (non-Javadoc)
-     * 
      * @see 
org.apache.jcs.engine.behavior.ICacheService#removeAll(java.lang.String)
      */
     public void removeAll( String cacheName )
@@ -267,7 +261,6 @@
 
     /*
      * (non-Javadoc)
-     * 
      * @see 
org.apache.jcs.auxiliary.lateral.behavior.ILateralCacheService#removeAll(java.lang.String,
      *      long)
      */
@@ -282,7 +275,6 @@
     }
 
     /**
-     * 
      * @param args
      */
     public static void main( String args[] )
@@ -318,7 +310,6 @@
 
     /*
      * (non-Javadoc)
-     * 
      * @see 
org.apache.jcs.engine.behavior.ICacheObserver#addCacheListener(java.lang.String,
      *      org.apache.jcs.engine.behavior.ICacheListener)
      */
@@ -330,7 +321,6 @@
 
     /*
      * (non-Javadoc)
-     * 
      * @see 
org.apache.jcs.engine.behavior.ICacheObserver#addCacheListener(org.apache.jcs.engine.behavior.ICacheListener)
      */
     public void addCacheListener( ICacheListener obj )
@@ -341,7 +331,6 @@
 
     /*
      * (non-Javadoc)
-     * 
      * @see 
org.apache.jcs.engine.behavior.ICacheObserver#removeCacheListener(java.lang.String,
      *      org.apache.jcs.engine.behavior.ICacheListener)
      */
@@ -353,7 +342,6 @@
 
     /*
      * (non-Javadoc)
-     * 
      * @see 
org.apache.jcs.engine.behavior.ICacheObserver#removeCacheListener(org.apache.jcs.engine.behavior.ICacheListener)
      */
     public void removeCacheListener( ICacheListener obj )


Ruby Jobs
Java Jobs
Jobs in California
more...
what
job title, keywords
where
city, state, zip
jobs by job search
Search:
Java, servers, webhosting, windows, cisco ...
more...
<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

Recently Viewed:
encryption.gpg....    ietf.rfc822/199...    freebsd.devel.i...    lang.haskell.li...    mail.squirrelma...    web.zope.plone....    yellowdog.gener...    text.xml.xalan....    recreation.phot...    kde.devel.educa...    hardware.bus.ca...    printing.ghosts...    voip.peering/20...    assembly/2006-0...    org.user-groups...    culture.interne...    network.i2p/200...    boot-loaders.ya...    xfree86.render/...    qnx.openqnx.dev...    jakarta.velocit...    user-groups.pal...   
Home | blog view | USPTO Patent Archive | advertise | OSDir is an inevitable website. super tiny logo

Free Magazines

Cisco News
Receive a free quarterly e-newsletter with exclusive articles on how Cisco IT uses its own products and solutions to enable the business.
subscribe

Systems Management News, the newspaper for IT systems administration and data center managers! Each issue of Systems Management News is chock-full of news and analysis to help you understand what's happening in your field.
subscribe

The Enterprise Newsweekly eWeek is the essential technology information source for builders of e-business.
subscribe

Oracle Magazine Oracle Magazine contains technology strategy articles, sample code, tips, Oracle and partner news, how to articles for developers and DBAs, and more. Oracle (NASDAQ: ORCL) is the world's largest enterprise software company.
subscribe

Total Telecom Total Telecom is "The Economist of the communications industry".
subscribe