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 14:56:07 UTC

svn commit: r1025981 - in /jackrabbit/branches/2.1: ./ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/ jackrabbit-core/src/main/java/org/apache/jackrabbi...

Author: jukka
Date: Thu Oct 21 12:56:07 2010
New Revision: 1025981

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

Modified:
    jackrabbit/branches/2.1/   (props changed)
    jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/PersistenceManager.java
    jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java
    jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/pool/AbstractBundlePersistenceManager.java
    jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/BundleCache.java
    jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/MLRUItemStateCache.java

Propchange: jackrabbit/branches/2.1/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Oct 21 12:56:07 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
+/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

Modified: jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/PersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/PersistenceManager.java?rev=1025981&r1=1025980&r2=1025981&view=diff
==============================================================================
--- jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/PersistenceManager.java (original)
+++ jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/PersistenceManager.java Thu Oct 21 12:56:07 2010
@@ -58,6 +58,15 @@ import org.apache.jackrabbit.core.state.
  *       to close the persistence manager and release all acquired
  *       resources.
  * </ol>
+ *
+ * <h2>Concurrency</h2>
+ * <p>
+ * A persistence manager instance should be thread-safe and guarantee that
+ * the {@link #store(ChangeLog)} method calls are atomic. Any load() or
+ * exists() calls started after a store() call has returned must access
+ * the updated content. The client accessing a persistence manager must
+ * guarantee that no two concurrent {@link #store(ChangeLog)} calls will
+ * modify the same items.
  */
 public interface PersistenceManager {
 

Modified: jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java?rev=1025981&r1=1025980&r2=1025981&view=diff
==============================================================================
--- jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java (original)
+++ jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java Thu Oct 21 12:56:07 2010
@@ -35,8 +35,8 @@ import org.apache.jackrabbit.core.persis
 import org.apache.jackrabbit.core.persistence.IterablePersistenceManager;
 import org.apache.jackrabbit.core.persistence.PMContext;
 import org.apache.jackrabbit.core.persistence.PersistenceManager;
-import org.apache.jackrabbit.core.util.StringIndex;
 import org.apache.jackrabbit.core.persistence.util.BundleBinding;
+import org.apache.jackrabbit.core.util.StringIndex;
 import org.apache.jackrabbit.core.persistence.util.BundleCache;
 import org.apache.jackrabbit.core.persistence.util.HashMapIndex;
 import org.apache.jackrabbit.core.persistence.util.LRUNodeIdCache;
@@ -405,7 +405,7 @@ public abstract class AbstractBundlePers
      *
      * Loads the state via the appropriate NodePropBundle.
      */
-    public synchronized NodeState load(NodeId id)
+    public NodeState load(NodeId id)
             throws NoSuchItemStateException, ItemStateException {
         NodePropBundle bundle = getBundle(id);
         if (bundle == null) {
@@ -419,7 +419,7 @@ public abstract class AbstractBundlePers
      *
      * Loads the state via the appropriate NodePropBundle.
      */
-    public synchronized PropertyState load(PropertyId id)
+    public PropertyState load(PropertyId id)
             throws NoSuchItemStateException, ItemStateException {
         NodePropBundle bundle = getBundle(id.getParentId());
         if (bundle == null) {
@@ -457,7 +457,7 @@ public abstract class AbstractBundlePers
      *
      * Loads the state via the appropriate NodePropBundle.
      */
-    public synchronized boolean exists(PropertyId id) throws ItemStateException {
+    public boolean exists(PropertyId id) throws ItemStateException {
         NodePropBundle bundle = getBundle(id.getParentId());
         return bundle != null && bundle.hasProperty(id.getName());
     }
@@ -467,7 +467,7 @@ public abstract class AbstractBundlePers
      *
      * Checks the existence via the appropriate NodePropBundle.
      */
-    public synchronized boolean exists(NodeId id) throws ItemStateException {
+    public boolean exists(NodeId id) throws ItemStateException {
         // anticipating a load followed by a exists
         return getBundle(id) != null;
     }
@@ -650,12 +650,14 @@ public abstract class AbstractBundlePers
         }
         NodePropBundle bundle = bundles.get(id);
         if (bundle == null) {
-            bundle = loadBundle(id);
-            if (bundle != null) {
-                bundle.markOld();
-                bundles.put(bundle);
-            } else {
-                missing.put(id);
+            synchronized (this) {
+                bundle = loadBundle(id);
+                if (bundle != null) {
+                    bundle.markOld();
+                    bundles.put(bundle);
+                } else {
+                    missing.put(id);
+                }
             }
         }
         return bundle;

Modified: jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/pool/AbstractBundlePersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/pool/AbstractBundlePersistenceManager.java?rev=1025981&r1=1025980&r2=1025981&view=diff
==============================================================================
--- jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/pool/AbstractBundlePersistenceManager.java (original)
+++ jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/pool/AbstractBundlePersistenceManager.java Thu Oct 21 12:56:07 2010
@@ -405,7 +405,7 @@ public abstract class AbstractBundlePers
      *
      * Loads the state via the appropriate NodePropBundle.
      */
-    public synchronized NodeState load(NodeId id) throws NoSuchItemStateException, ItemStateException {
+    public NodeState load(NodeId id) throws NoSuchItemStateException, ItemStateException {
         NodePropBundle bundle = getBundle(id);
         if (bundle == null) {
             throw new NoSuchItemStateException(id.toString());
@@ -418,7 +418,7 @@ public abstract class AbstractBundlePers
      *
      * Loads the state via the appropriate NodePropBundle.
      */
-    public synchronized PropertyState load(PropertyId id) throws NoSuchItemStateException, ItemStateException {
+    public PropertyState load(PropertyId id) throws NoSuchItemStateException, ItemStateException {
         NodePropBundle bundle = getBundle(id.getParentId());
         if (bundle == null) {
             throw new NoSuchItemStateException(id.toString());
@@ -455,7 +455,7 @@ public abstract class AbstractBundlePers
      *
      * Loads the state via the appropriate NodePropBundle.
      */
-    public synchronized boolean exists(PropertyId id) throws ItemStateException {
+    public boolean exists(PropertyId id) throws ItemStateException {
         NodePropBundle bundle = getBundle(id.getParentId());
         return bundle != null && bundle.hasProperty(id.getName());
     }
@@ -465,7 +465,7 @@ public abstract class AbstractBundlePers
      *
      * Checks the existence via the appropriate NodePropBundle.
      */
-    public synchronized boolean exists(NodeId id) throws ItemStateException {
+    public boolean exists(NodeId id) throws ItemStateException {
         // anticipating a load followed by a exists
         return getBundle(id) != null;
     }
@@ -648,12 +648,14 @@ public abstract class AbstractBundlePers
         }
         NodePropBundle bundle = bundles.get(id);
         if (bundle == null) {
-            bundle = loadBundle(id);
-            if (bundle != null) {
-                bundle.markOld();
-                bundles.put(bundle);
-            } else {
-                missing.put(id);
+            synchronized (this) {
+                bundle = loadBundle(id);
+                if (bundle != null) {
+                    bundle.markOld();
+                    bundles.put(bundle);
+                } else {
+                    missing.put(id);
+                }
             }
         }
         return bundle;

Modified: jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/BundleCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/BundleCache.java?rev=1025981&r1=1025980&r2=1025981&view=diff
==============================================================================
--- jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/BundleCache.java (original)
+++ jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/BundleCache.java Thu Oct 21 12:56:07 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/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/MLRUItemStateCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/MLRUItemStateCache.java?rev=1025981&r1=1025980&r2=1025981&view=diff
==============================================================================
--- jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/MLRUItemStateCache.java (original)
+++ jackrabbit/branches/2.1/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/MLRUItemStateCache.java Thu Oct 21 12:56:07 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.
      *