Author: thomasm
Date: Tue Oct 18 13:10:28 2016
New Revision: 1765434

URL: http://svn.apache.org/viewvc?rev=1765434&view=rev
Log:
OAK-4950 LIRS cache: improve hit rate

Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/cache/CacheLIRS.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/cache/CacheTest.java

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/cache/CacheLIRS.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/cache/CacheLIRS.java?rev=1765434&r1=1765433&r2=1765434&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/cache/CacheLIRS.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/cache/CacheLIRS.java
 Tue Oct 18 13:10:28 2016
@@ -78,7 +78,8 @@ public class CacheLIRS<K, V> implements
     static final Logger LOG = LoggerFactory.getLogger(CacheLIRS.class);
     static final ThreadLocal<Integer> CURRENTLY_LOADING = new 
ThreadLocal<Integer>();
     private static final AtomicInteger NEXT_CACHE_ID = new AtomicInteger();
-
+    private static final boolean PUT_HOT = 
Boolean.parseBoolean(System.getProperty("oak.cacheLIRS.putHot", "true"));
+    
     /**
      * Listener for items that are evicted from the cache. The listener
      * is called for both, resident and non-resident items. In the
@@ -1137,9 +1138,12 @@ public class CacheLIRS<K, V> implements
             }
             V old;
             Entry<K, V> e = find(key, hash);
+            boolean existed;
             if (e == null) {
+                existed = false;
                 old = null;
             } else {
+                existed = true;
                 old = e.value;
                 invalidate(key, hash, RemovalCause.REPLACED);
             }
@@ -1160,6 +1164,12 @@ public class CacheLIRS<K, V> implements
             mapSize++;
             // added entries are always added to the stack
             addToStack(e);
+            if (existed) {
+                // if it was there before (even non-resident), it becomes hot
+                if (PUT_HOT) {
+                    access(key, hash);
+                }
+            }
             return old;
         }
 

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/cache/CacheTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/cache/CacheTest.java?rev=1765434&r1=1765433&r2=1765434&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/cache/CacheTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/cache/CacheTest.java
 Tue Oct 18 13:10:28 2016
@@ -244,7 +244,7 @@ public class CacheTest {
         assertTrue(test.containsValue(50));
         verify(test, "mem: 4 stack: 5 4 3 2 cold: 5 non-resident: 1");
         test.put(1, 10);
-        verify(test, "mem: 4 stack: 1 5 4 3 2 cold: 1 non-resident: 5");
+        verify(test, "mem: 4 stack: 1 5 4 3 cold: 2 non-resident: 5");
         assertFalse(test.containsValue(50));
         test.remove(2);
         test.remove(3);
@@ -354,6 +354,21 @@ public class CacheTest {
         assertEquals(99, test.sizeNonResident());
         assertEquals(93, test.sizeHot());
     }
+    
+    @Test
+    public void testNonResidentBecomeHot() throws ExecutionException {
+        CacheLIRS<Integer, Integer> test = createCache(4);
+        for (int i = 0; i < 20; i++) {
+            test.put(i, 1);
+        }
+        verify(test, "mem: 4 stack: 19 18 17 16 3 2 1 cold: 19 non-resident: 
18 17 16");
+        // 18 is a non-resident entry, so should become hot
+        test.put(18, 1);
+        verify(test, "mem: 4 stack: 18 19 17 16 3 2 cold: 1 non-resident: 19 
17 16");
+        // 28 was never seen before, so should become cold
+        test.put(28, 1);
+        verify(test, "mem: 4 stack: 28 18 19 3 2 cold: 28 non-resident: 1 19");
+    }
 
     @Test
     public void testLimitNonResident() {


Reply via email to