Author: tv
Date: Sat Dec 31 13:47:19 2016
New Revision: 1776744

URL: http://svn.apache.org/viewvc?rev=1776744&view=rev
Log:
Performance improvements

Modified:
    
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/struct/AbstractLRUMap.java

Modified: 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/struct/AbstractLRUMap.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/struct/AbstractLRUMap.java?rev=1776744&r1=1776743&r2=1776744&view=diff
==============================================================================
--- 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/struct/AbstractLRUMap.java
 (original)
+++ 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/struct/AbstractLRUMap.java
 Sat Dec 31 13:47:19 2016
@@ -64,21 +64,19 @@ public abstract class AbstractLRUMap<K,
     private final DoubleLinkedList<LRUElementDescriptor<K, V>> list;
 
     /** Map where items are stored by key. */
-    private Map<K, LRUElementDescriptor<K, V>> map;
+    private final Map<K, LRUElementDescriptor<K, V>> map;
 
-    /** stats */
-    int hitCnt = 0;
+    /** lock to keep map and list synchronous */
+    private final Lock lock = new ReentrantLock();
 
     /** stats */
-    int missCnt = 0;
+    private long hitCnt = 0;
 
     /** stats */
-    int putCnt = 0;
+    private long missCnt = 0;
 
-    /** make configurable */
-    private int chunkSize = 1;
-
-    private final Lock lock = new ReentrantLock();
+    /** stats */
+    private long putCnt = 0;
 
     /**
      * This creates an unbounded version. Setting the max objects will result 
in spooling on
@@ -196,7 +194,7 @@ public abstract class AbstractLRUMap<K,
     @Override
     public V get( Object key )
     {
-        V retVal = null;
+        V retVal;
 
         if ( log.isDebugEnabled() )
         {
@@ -205,22 +203,28 @@ public abstract class AbstractLRUMap<K,
 
         LRUElementDescriptor<K, V> me = map.get( key );
 
-        if ( me != null )
+        if ( me == null )
+        {
+            missCnt++;
+            retVal = null;
+        }
+        else
         {
             hitCnt++;
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "LRUMap hit for " + key );
-            }
-
             retVal = me.getPayload();
-
             list.makeFirst( me );
         }
-        else
+
+        if ( log.isDebugEnabled() )
         {
-            missCnt++;
-            log.debug( "LRUMap miss for " + key );
+            if ( me == null )
+            {
+                log.debug( "LRUMap miss for " + key );
+            }
+            else
+            {
+                log.debug( "LRUMap hit for " + key );
+            }
         }
 
         // verifyCache();
@@ -238,20 +242,23 @@ public abstract class AbstractLRUMap<K,
     public V getQuiet( Object key )
     {
         V ce = null;
-
         LRUElementDescriptor<K, V> me = map.get( key );
+
         if ( me != null )
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "LRUMap quiet hit for " + key );
-            }
-
             ce = me.getPayload();
         }
-        else if ( log.isDebugEnabled() )
+
+        if ( log.isDebugEnabled() )
         {
-            log.debug( "LRUMap quiet miss for " + key );
+            if ( me == null )
+            {
+                log.debug( "LRUMap quiet miss for " + key );
+            }
+            else
+            {
+                log.debug( "LRUMap quiet hit for " + key );
+            }
         }
 
         return ce;
@@ -300,17 +307,16 @@ public abstract class AbstractLRUMap<K,
         putCnt++;
 
         LRUElementDescriptor<K, V> old = null;
+        LRUElementDescriptor<K, V> me = new LRUElementDescriptor<K, V>(key, 
value);
+
         lock.lock();
         try
         {
-            // TODO address double synchronization of addFirst, use write lock
-            addFirst( key, value );
-            // this must be synchronized
-            LRUElementDescriptor<K, V> first = list.getFirst();
-            old = map.put(first.getKey(), first);
+            list.addFirst( me );
+            old = map.put(key, me);
 
             // If the node was the same as an existing node, remove it.
-            if ( old != null && first.getKey().equals(old.getKey()))
+            if ( old != null && key.equals(old.getKey()))
             {
                 list.remove( old );
             }
@@ -321,7 +327,6 @@ public abstract class AbstractLRUMap<K,
         }
 
         // If the element limit is reached, we need to spool
-
         if (shouldRemove())
         {
             if (log.isDebugEnabled())
@@ -332,7 +337,6 @@ public abstract class AbstractLRUMap<K,
             // The spool will put them in a disk event queue, so there is no
             // need to pre-queue the queuing. This would be a bit wasteful
             // and wouldn't save much time in this synchronous call.
-
             while ( shouldRemove() )
             {
                 lock.lock();
@@ -366,10 +370,10 @@ public abstract class AbstractLRUMap<K,
             {
                 log.debug( "update: After spool map size: " + map.size() );
             }
-            if ( map.size() != dumpCacheSize() )
+            if ( map.size() != list.size() )
             {
-                log.error("update: After spool, size mismatch: map.size() = " 
+ map.size() + ", linked list size = "
-                        + dumpCacheSize());
+                log.error("update: After spool, size mismatch: map.size() = " 
+ map.size() +
+                        ", linked list size = " + list.size());
             }
         }
 
@@ -382,37 +386,6 @@ public abstract class AbstractLRUMap<K,
 
     protected abstract boolean shouldRemove();
 
-
-    /**
-     * Adds a new node to the start of the link list.
-     * <p>
-     * @param key
-     * @param val The feature to be added to the First
-     */
-    private void addFirst(K key, V val)
-    {
-        lock.lock();
-        try
-        {
-            LRUElementDescriptor<K, V> me = new LRUElementDescriptor<K, 
V>(key, val);
-            list.addFirst( me );
-        }
-        finally
-        {
-            lock.unlock();
-        }
-    }
-
-    /**
-     * Returns the size of the list.
-     * <p>
-     * @return int
-     */
-    private int dumpCacheSize()
-    {
-        return list.size();
-    }
-
     /**
      * Dump the cache entries from first to list for debugging.
      */
@@ -458,8 +431,8 @@ public abstract class AbstractLRUMap<K,
         }
 
         boolean found = false;
-        log.debug( "verifycache: mapContains " + map.size() + " elements, 
linked list contains " + dumpCacheSize()
-            + " elements" );
+        log.debug( "verifycache: mapContains " + map.size() +
+                " elements, linked list contains " + list.size() + " elements" 
);
         log.debug( "verifycache: checking linked list by key " );
         for (LRUElementDescriptor<K, V> li = list.getFirst(); li != null; li = 
(LRUElementDescriptor<K, V>) li.next )
         {
@@ -537,37 +510,6 @@ public abstract class AbstractLRUMap<K,
     }
 
     /**
-     * Logs an error is an element that should be in the cache is not.
-     * <p>
-     * @param key
-     */
-    @SuppressWarnings("unchecked") // No generics for public fields
-    protected void verifyCache( Object key )
-    {
-        if ( !log.isDebugEnabled() )
-        {
-            return;
-        }
-
-        boolean found = false;
-
-        // go through the linked list looking for the key
-        for (LRUElementDescriptor<K, V> li = list.getFirst(); li != null; li = 
(LRUElementDescriptor<K, V>) li.next )
-        {
-            if ( li.getKey() == key )
-            {
-                found = true;
-                log.debug( "verifycache(key) key match: " + key );
-                break;
-            }
-        }
-        if ( !found )
-        {
-            log.error( "verifycache(key), couldn't find key! : " + key );
-        }
-    }
-
-    /**
      * This is called when an item is removed from the LRU. We just log some 
information.
      * <p>
      * Children can implement this method for special behavior.
@@ -584,24 +526,6 @@ public abstract class AbstractLRUMap<K,
     }
 
     /**
-     * The chunk size is the number of items to remove when the max is 
reached. By default it is 1.
-     * <p>
-     * @param chunkSize The chunkSize to set.
-     */
-    public void setChunkSize( int chunkSize )
-    {
-        this.chunkSize = chunkSize;
-    }
-
-    /**
-     * @return Returns the chunkSize.
-     */
-    public int getChunkSize()
-    {
-        return chunkSize;
-    }
-
-    /**
      * @return IStats
      */
     public IStats getStatistics()
@@ -613,9 +537,9 @@ public abstract class AbstractLRUMap<K,
 
         elems.add(new StatElement<Integer>( "List Size", 
Integer.valueOf(list.size()) ) );
         elems.add(new StatElement<Integer>( "Map Size", 
Integer.valueOf(map.size()) ) );
-        elems.add(new StatElement<Integer>( "Put Count", 
Integer.valueOf(putCnt) ) );
-        elems.add(new StatElement<Integer>( "Hit Count", 
Integer.valueOf(hitCnt) ) );
-        elems.add(new StatElement<Integer>( "Miss Count", 
Integer.valueOf(missCnt) ) );
+        elems.add(new StatElement<Long>( "Put Count", Long.valueOf(putCnt) ) );
+        elems.add(new StatElement<Long>( "Hit Count", Long.valueOf(hitCnt) ) );
+        elems.add(new StatElement<Long>( "Miss Count", Long.valueOf(missCnt) ) 
);
 
         stats.setStatElements( elems );
 


Reply via email to