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/01 10:01:44 UTC

svn commit: r1003423 - in /jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence: PersistenceManager.java bundle/AbstractBundlePersistenceManager.java pool/AbstractBundlePersistenceManager.java

Author: jukka
Date: Fri Oct  1 08:01:43 2010
New Revision: 1003423

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

Use more fine-grained synchronization in the bundle persistence managers to allow readers to concurrently access the bundle cache.
Document these concurrency assumptions (guaranteed by the SISM and ISMLocking classes) in the PersistenceManager interface.

Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/PersistenceManager.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/pool/AbstractBundlePersistenceManager.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/PersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/PersistenceManager.java?rev=1003423&r1=1003422&r2=1003423&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/PersistenceManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/PersistenceManager.java Fri Oct  1 08:01:43 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/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java?rev=1003423&r1=1003422&r2=1003423&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java Fri Oct  1 08:01:43 2010
@@ -37,7 +37,6 @@ import org.apache.jackrabbit.core.persis
 import org.apache.jackrabbit.core.persistence.PersistenceManager;
 import org.apache.jackrabbit.core.util.StringIndex;
 import org.apache.jackrabbit.core.persistence.util.BLOBStore;
-import org.apache.jackrabbit.core.persistence.util.BundleBinding;
 import org.apache.jackrabbit.core.persistence.util.BundleCache;
 import org.apache.jackrabbit.core.persistence.util.FileBasedIndex;
 import org.apache.jackrabbit.core.persistence.util.LRUNodeIdCache;
@@ -408,7 +407,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) {
@@ -422,7 +421,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) {
@@ -460,7 +459,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());
     }
@@ -470,7 +469,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;
     }
@@ -653,12 +652,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/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/pool/AbstractBundlePersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/pool/AbstractBundlePersistenceManager.java?rev=1003423&r1=1003422&r2=1003423&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/pool/AbstractBundlePersistenceManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/pool/AbstractBundlePersistenceManager.java Fri Oct  1 08:01:43 2010
@@ -407,7 +407,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());
@@ -420,7 +420,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());
@@ -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;