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 17:27:44 UTC

svn commit: r1026027 - in /jackrabbit/branches/2.0: ./ 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 15:27:44 2010
New Revision: 1026027

URL: http://svn.apache.org/viewvc?rev=1026027&view=rev
Log:
2.0: Merged revisions 1025999 and 1026002 (JCR-2699 and JCR-2770)

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

Propchange: jackrabbit/branches/2.0/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Oct 21 15:27:44 2010
@@ -1,6 +1,6 @@
 /jackrabbit/branches/1.5:794012,794100,794102
-/jackrabbit/branches/2.1:955309,955314,982266,982277,982505,998310,1025933,1025957,1025962,1025964,1025981,1025985,1025990,1025995
+/jackrabbit/branches/2.1:955309,955314,982266,982277,982505,998310,1025933,1025957,1025962,1025964,1025981,1025985,1025990,1025995,1025999,1026002
 /jackrabbit/sandbox/JCR-1456:774917-886178
 /jackrabbit/sandbox/JCR-2170:812417-816332
 /jackrabbit/sandbox/tripod-JCR-2209:795441-795863
-/jackrabbit/trunk:891595,891629,892253,892263,894150-894151,896408,896513,896532,896857,896870,896876,896908,896940,896942-896943,896969,896977,897071,897836,897842,897858,897935,897983,897992-897993,897996,898002,898042,898267,898325,898540,898677,898699,898701,898715,898872,899102,899181,899391,899393-899394,899583,899594,899643,900305,900310,900314,900453,900702,900736,900762-900763,900767,900782,901095,901122,901139,901144,901170,901176,901191,901193,901196,901216,901228,901285,902058,902062,926324,928888,936668,955222,955229,955307,955852,965539,996810,1001707,1002065-1002066,1002084,1002101-1002102,1002168,1002170,1002589,1002608,1002657,1002729,1003423,1003470,1003542,1003773,1004182,1004184,1004223-1004224
+/jackrabbit/trunk:891595,891629,892253,892263,894150-894151,896408,896513,896532,896857,896870,896876,896908,896940,896942-896943,896969,896977,897071,897836,897842,897858,897935,897983,897992-897993,897996,898002,898042,898267,898325,898540,898677,898699,898701,898715,898872,899102,899181,899391,899393-899394,899583,899594,899643,900305,900310,900314,900453,900702,900736,900762-900763,900767,900782,901095,901122,901139,901144,901170,901176,901191,901193,901196,901216,901228,901285,902058,902062,926324,928888,936668,955222,955229,955307,955852,965539,996810,1001707,1002065-1002066,1002084,1002101-1002102,1002168,1002170,1002589,1002608,1002657,1002729,1003423,1003470,1003542,1003773,1004182,1004184,1004223-1004224,1004652,1005057,1005112

Modified: jackrabbit/branches/2.0/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/ConcurrentCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.0/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/ConcurrentCache.java?rev=1026027&r1=1026026&r2=1026027&view=diff
==============================================================================
--- jackrabbit/branches/2.0/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/ConcurrentCache.java (original)
+++ jackrabbit/branches/2.0/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/ConcurrentCache.java Thu Oct 21 15:27:44 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;
@@ -50,7 +63,7 @@ public class ConcurrentCache<K, V> exten
     public ConcurrentCache(int numberOfSegments) {
         this.segments = new Map[numberOfSegments];
         for (int i = 0; i < segments.length; i++) {
-            segments[i] = new LinkedHashMap<K, E<V>>(1024, 0.75f, true) {
+            segments[i] = new LinkedHashMap<K, E<V>>(16, 0.75f, true) {
                 @Override
                 protected boolean removeEldestEntry(Map.Entry<K, E<V>> eldest) {
                     if (isTooBig()) {
@@ -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.0/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ItemStateReferenceCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.0/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ItemStateReferenceCache.java?rev=1026027&r1=1026026&r2=1026027&view=diff
==============================================================================
--- jackrabbit/branches/2.0/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ItemStateReferenceCache.java (original)
+++ jackrabbit/branches/2.0/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ItemStateReferenceCache.java Thu Oct 21 15:27:44 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