You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2010/09/29 18:41:48 UTC

svn commit: r1002729 - in /jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core: persistence/util/BundleCache.java state/MLRUItemStateCache.java

Author: jukka
Date: Wed Sep 29 16:41:48 2010
New Revision: 1002729

URL: http://svn.apache.org/viewvc?rev=1002729&view=rev
Log:
JCR-2699: Improve read/write concurrency

Better handling of the case where more than one entry needs to be removed from an LRU cache.

Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/BundleCache.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/MLRUItemStateCache.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/BundleCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/BundleCache.java?rev=1002729&r1=1002728&r2=1002729&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/BundleCache.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/BundleCache.java Wed Sep 29 16:41:48 2010
@@ -16,7 +16,9 @@
  */
 package org.apache.jackrabbit.core.persistence.util;
 
+import java.util.ArrayList;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.apache.jackrabbit.core.id.NodeId;
@@ -71,10 +73,14 @@ public class BundleCache {
             @Override
             protected boolean removeEldestEntry(
                     Map.Entry<NodeId, NodePropBundle> e) {
-                if (curSize > BundleCache.this.maxSize) {
+                long maxSize = BundleCache.this.maxSize;
+                if (curSize <= maxSize) {
+                    return false;
+                } else if (curSize - e.getValue().getSize() <= maxSize) {
                     curSize -= e.getValue().getSize();
                     return true;
                 } else {
+                    shrink();
                     return false;
                 }
             }
@@ -97,6 +103,20 @@ public class BundleCache {
      */
     public void setMaxSize(long maxSize) {
         this.maxSize = maxSize;
+
+        if (curSize > maxSize) {
+            shrink();
+        }
+    }
+
+    private void shrink() {
+        List<NodePropBundle> list =
+            new ArrayList<NodePropBundle>(bundles.values());
+        for (int i = list.size() - 1; curSize > maxSize && i >= 0; i--) {
+            NodePropBundle bundle = list.get(i);
+            curSize -= bundle.getSize();
+            bundles.remove(bundle.getId());
+        }
     }
 
     /**

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/MLRUItemStateCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/MLRUItemStateCache.java?rev=1002729&r1=1002728&r2=1002729&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/MLRUItemStateCache.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/MLRUItemStateCache.java Wed Sep 29 16:41:48 2010
@@ -84,10 +84,14 @@ public class MLRUItemStateCache implemen
                 maxMem / 1024, 0.75f, true /* access-ordered */) {
             @Override
             protected boolean removeEldestEntry(Map.Entry<ItemId, Entry> e) {
-                if (totalMem > MLRUItemStateCache.this.maxMem) {
+                long maxMem = MLRUItemStateCache.this.maxMem;
+                if (totalMem <= maxMem) {
+                    return false;
+                } else if (totalMem - e.getValue().size <= maxMem) {
                     totalMem -= e.getValue().size;
                     return true;
                 } else {
+                    shrink();
                     return false;
                 }
             }
@@ -248,21 +252,21 @@ public class MLRUItemStateCache implemen
 
             // remove items, if too many
             if (totalMem > maxMem) {
-                totalMem = 0;
-                List<Map.Entry<ItemId, Entry>> entries =
-                    new ArrayList<Map.Entry<ItemId, Entry>>(cache.entrySet());
-                for (Map.Entry<ItemId, Entry> entry : entries) {
-                    long entrySize = entry.getValue().size;
-                    if (totalMem + entrySize > maxMem) {
-                        cache.remove(entry.getKey());
-                    } else {
-                        totalMem += entrySize;
-                    }
-                }
+                shrink();
             }
         }
     }
 
+    private void shrink() {
+        List<Map.Entry<ItemId, Entry>> list =
+            new ArrayList<Map.Entry<ItemId, Entry>>(cache.entrySet());
+        for (int i = list.size() - 1; totalMem > maxMem && i >= 0; i--) {
+            Map.Entry<ItemId, Entry> last = list.get(i);
+            totalMem -= last.getValue().size;
+            cache.remove(last.getKey());
+        }
+    }
+
     /**
      * Set the cache access listener. Only one listener per cache is supported.
      *