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/10/21 15:47:01 UTC

svn commit: r1025999 - in /jackrabbit/branches/2.1: ./ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/ConcurrentCache.java jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ItemStateReferenceCache.java

Author: jukka
Date: Thu Oct 21 13:47:01 2010
New Revision: 1025999

URL: http://svn.apache.org/viewvc?rev=1025999&view=rev
Log:
2.1: Merged revisions 1004652 and 1005057 (JCR-2699)

Modified:
    jackrabbit/branches/2.1/   (props changed)
    jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/ConcurrentCache.java
    jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ItemStateReferenceCache.java

Propchange: jackrabbit/branches/2.1/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Oct 21 13:47:01 2010
@@ -2,4 +2,4 @@
 /jackrabbit/sandbox/JCR-1456:774917-886178
 /jackrabbit/sandbox/JCR-2170:812417-816332
 /jackrabbit/sandbox/tripod-JCR-2209:795441-795863
-/jackrabbit/trunk:931121,931479,931483-931484,931504,931609,931613,931838,931919,932318-932319,933144,933197,933203,933213,933216,933554,933646,933694,934405,934412,934849,935557,936668,938099,945528,950440,950680,955222,955229,955307,955852,961487,961626,964362,965539,986682,986686,986715,991144,996810,1001707,1002065-1002066,1002084,1002101-1002102,1002168,1002170,1002589,1002608,1002657,1002729,1003423,1003470,1003542,1003773,1004182,1004184,1004223-1004224
+/jackrabbit/trunk:931121,931479,931483-931484,931504,931609,931613,931838,931919,932318-932319,933144,933197,933203,933213,933216,933554,933646,933694,934405,934412,934849,935557,936668,938099,945528,950440,950680,955222,955229,955307,955852,961487,961626,964362,965539,986682,986686,986715,991144,996810,1001707,1002065-1002066,1002084,1002101-1002102,1002168,1002170,1002589,1002608,1002657,1002729,1003423,1003470,1003542,1003773,1004182,1004184,1004223-1004224,1004652,1005057

Modified: jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/ConcurrentCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/ConcurrentCache.java?rev=1025999&r1=1025998&r2=1025999&view=diff
==============================================================================
--- jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/ConcurrentCache.java (original)
+++ jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/ConcurrentCache.java Thu Oct 21 13:47:01 2010
@@ -31,6 +31,19 @@ import java.util.Map;
  */
 public class ConcurrentCache<K, V> extends AbstractCache {
 
+    /**
+     * Default number of cache segments to use. Use the number of available
+     * processors (even if that might change during runtime!) as a reasonable
+     * approximation of the amount of parallelism we should expect in the
+     * worst case.
+     * <p>
+     * One reason for this value being a constant is that the
+     * {@link Runtime#availableProcessors()} call is somewhat expensive at
+     * least in some environments.
+     */
+    private static int DEFAULT_NUMBER_OF_SEGMENTS =
+        Runtime.getRuntime().availableProcessors();
+
     private static class E<V> {
 
         private final V value;
@@ -65,7 +78,7 @@ public class ConcurrentCache<K, V> exten
     }
 
     public ConcurrentCache() {
-        this(Runtime.getRuntime().availableProcessors());
+        this(DEFAULT_NUMBER_OF_SEGMENTS);
     }
 
     /**
@@ -147,16 +160,21 @@ public class ConcurrentCache<K, V> exten
      * @return the previous value, or <code>null</code>
      */
     public V put(K key, V value, long size) {
+        E<V> previous;
+
         Map<K, E<V>> segment = getSegment(key);
         synchronized (segment) {
             recordSizeChange(size);
-            E<V> previous = segment.put(key, new E<V>(value, size));
-            if (previous != null) {
-                recordSizeChange(-previous.size);
-                return previous.value;
-            } else {
-                return null;
-            }
+            previous = segment.put(key, new E<V>(value, size));
+        }
+
+        if (previous != null) {
+            recordSizeChange(-previous.size);
+            shrinkIfNeeded();
+            return previous.value;
+        } else {
+            shrinkIfNeeded();
+            return null;
         }
     }
 
@@ -210,7 +228,13 @@ public class ConcurrentCache<K, V> exten
     @Override
     public void setMaxMemorySize(long size) {
         super.setMaxMemorySize(size);
+        shrinkIfNeeded();
+    }
 
+    /**
+     * Removes old entries from the cache until the cache is small enough.
+     */
+    private void shrinkIfNeeded() {
         // Semi-random start index to prevent bias against the first segments
         int start = (int) getAccessCount() % segments.length;
         for (int i = start; isTooBig(); i = (i + 1) % segments.length) {
@@ -218,10 +242,9 @@ public class ConcurrentCache<K, V> exten
                 Iterator<Map.Entry<K, E<V>>> iterator =
                     segments[i].entrySet().iterator();
                 if (iterator.hasNext()) {
-                    Map.Entry<K, E<V>> entry = iterator.next();
                     // Removing and re-adding the first entry will
-                    // automatically the last entry if the cache is
-                    // too big
+                    // evict the last entry if the cache is too big
+                    Map.Entry<K, E<V>> entry = iterator.next();
                     segments[i].remove(entry.getKey());
                     segments[i].put(entry.getKey(), entry.getValue());
                 }

Modified: jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ItemStateReferenceCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ItemStateReferenceCache.java?rev=1025999&r1=1025998&r2=1025999&view=diff
==============================================================================
--- jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ItemStateReferenceCache.java (original)
+++ jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ItemStateReferenceCache.java Thu Oct 21 13:47:01 2010
@@ -46,7 +46,21 @@ import java.util.Map;
 public class ItemStateReferenceCache implements ItemStateCache {
 
     /** Logger instance */
-    private static Logger log = LoggerFactory.getLogger(ItemStateReferenceCache.class);
+    private static final Logger log =
+        LoggerFactory.getLogger(ItemStateReferenceCache.class);
+
+    /**
+     * The number of cache segments to use. Use the number of available
+     * processors (even if that might change during runtime!) as a reasonable
+     * approximation of the amount of parallelism we should expect in the
+     * worst case.
+     * <p>
+     * One reason for this value being a constant is that the
+     * {@link Runtime#availableProcessors()} call is somewhat expensive at
+     * least in some environments.
+     */
+    private static int NUMBER_OF_SEGMENTS =
+        Runtime.getRuntime().availableProcessors();
 
     /**
      * Cache that automatically flushes entries based on some eviction policy;
@@ -79,7 +93,7 @@ public class ItemStateReferenceCache imp
     @SuppressWarnings("unchecked")
     public ItemStateReferenceCache(ItemStateCache cache) {
         this.cache = cache;
-        this.segments = new Map[Runtime.getRuntime().availableProcessors()];
+        this.segments = new Map[NUMBER_OF_SEGMENTS];
         for (int i = 0; i < segments.length; i++) {
             // I tried using soft instead of weak references here, but that
             // seems to have some unexpected performance consequences (notable