jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ju...@apache.org
Subject svn commit: r1503273 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak: plugins/memory/ plugins/segment/ plugins/segment/file/ plugins/segment/memory/ plugins/segment/mongo/ spi/state/
Date Mon, 15 Jul 2013 14:40:18 GMT
Author: jukka
Date: Mon Jul 15 14:40:18 2013
New Revision: 1503273

URL: http://svn.apache.org/r1503273
Log:
OAK-786: Fall back to pessimism

Instead of extending the journal API, we can simply put extra metadata in the content tree,
at a "super-root" above the one visible to clients.

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/EmptyNodeState.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreBranch.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileJournal.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/memory/MemoryJournal.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/memory/MemoryStore.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/mongo/MongoJournal.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/mongo/MongoStore.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeState.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeState.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/EmptyNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/EmptyNodeState.java?rev=1503273&r1=1503272&r2=1503273&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/EmptyNodeState.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/EmptyNodeState.java
Mon Jul 15 14:40:18 2013
@@ -70,6 +70,16 @@ public final class EmptyNodeState implem
         return false;
     }
 
+    @Override
+    public long getLong(String name) {
+        return 0;
+    }
+
+    @Override
+    public String getString(String name) {
+        return null;
+    }
+
     @Override @CheckForNull
     public String getName(@Nonnull String name) {
         return null;

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java?rev=1503273&r1=1503272&r2=1503273&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java
Mon Jul 15 14:40:18 2013
@@ -34,6 +34,8 @@ import org.apache.jackrabbit.oak.spi.sta
 
 public class SegmentNodeStore extends AbstractNodeStore {
 
+    static final String ROOT = "root";
+
     private final SegmentStore store;
 
     private final Journal journal;
@@ -42,36 +44,41 @@ public class SegmentNodeStore extends Ab
 
     private final Observer observer;
 
-    private SegmentNodeState root;
+    private SegmentNodeState head;
 
     public SegmentNodeStore(SegmentStore store, String journal) {
         this.store = store;
         this.journal = store.getJournal(journal);
         this.reader = new SegmentReader(store);
         this.observer = EmptyObserver.INSTANCE;
-        this.root = new SegmentNodeState(store, this.journal.getHead());
+        this.head = new SegmentNodeState(store, this.journal.getHead());
     }
 
     public SegmentNodeStore(SegmentStore store) {
         this(store, "root");
     }
 
+    synchronized SegmentNodeState getHead() {
+        NodeState before = head.getChildNode(ROOT);
+        head = new SegmentNodeState(store, journal.getHead());
+        NodeState after = head.getChildNode(ROOT);
+        observer.contentChanged(before, after);
+        return head;
+    }
+
     boolean setHead(SegmentNodeState base, SegmentNodeState head) {
         return journal.setHead(base.getRecordId(), head.getRecordId());
     }
 
     @Override @Nonnull
-    public synchronized SegmentNodeState getRoot() {
-        NodeState before = root;
-        root = new SegmentNodeState(store, journal.getHead());
-        observer.contentChanged(before, root);
-        return root;
+    public synchronized NodeState getRoot() {
+        return getHead().getChildNode(ROOT);
     }
 
     @Override @Nonnull
     public NodeStoreBranch branch() {
         return new SegmentNodeStoreBranch(
-                this, new SegmentWriter(store), getRoot());
+                this, new SegmentWriter(store), getHead());
     }
 
     @Override
@@ -86,14 +93,14 @@ public class SegmentNodeStore extends Ab
     public synchronized String checkpoint(long lifetime) {
         checkArgument(lifetime > 0);
         // TODO: Guard the checkpoint from garbage collection
-        return getRoot().getRecordId().toString();
+        return getHead().getRecordId().toString();
     }
 
     @Override @CheckForNull
     public synchronized NodeState retrieve(@Nonnull String checkpoint) {
         // TODO: Verify validity of the checkpoint
         RecordId id = RecordId.fromString(checkNotNull(checkpoint));
-        return new SegmentNodeState(store, id);
+        return new SegmentNodeState(store, id).getChildNode(ROOT);
     }
 
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreBranch.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreBranch.java?rev=1503273&r1=1503272&r2=1503273&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreBranch.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreBranch.java
Mon Jul 15 14:40:18 2013
@@ -16,6 +16,8 @@
  */
 package org.apache.jackrabbit.oak.plugins.segment;
 
+import static org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore.ROOT;
+
 import java.util.Random;
 
 import javax.annotation.Nonnull;
@@ -51,27 +53,30 @@ class SegmentNodeStoreBranch extends Abs
 
     @Override @Nonnull
     public NodeState getBase() {
-        return base;
+        return base.getChildNode(ROOT);
     }
 
     @Override @Nonnull
     public synchronized NodeState getHead() {
-        return head;
+        return head.getChildNode(ROOT);
     }
 
     @Override
     public synchronized void setRoot(NodeState newRoot) {
-        head = writer.writeNode(newRoot);
+        NodeBuilder builder = head.builder();
+        builder.setChildNode(ROOT, newRoot);
+        head = writer.writeNode(builder.getNodeState());
         writer.flush();
     }
 
     @Override
     public synchronized void rebase() {
-        SegmentNodeState newBase = store.getRoot();
+        SegmentNodeState newBase = store.getHead();
         if (!base.getRecordId().equals(newBase.getRecordId())) {
             NodeBuilder builder = newBase.builder();
-            head.compareAgainstBaseState(
-                    base, new ConflictAnnotatingRebaseDiff(builder));
+            head.getChildNode(ROOT).compareAgainstBaseState(
+                    base.getChildNode(ROOT),
+                    new ConflictAnnotatingRebaseDiff(builder.child(ROOT)));
             base = newBase;
             head = writer.writeNode(builder.getNodeState());
             writer.flush();
@@ -81,19 +86,23 @@ class SegmentNodeStoreBranch extends Abs
     @Override @Nonnull
     public synchronized NodeState merge(CommitHook hook)
             throws CommitFailedException {
+        int backoff = 1;
         SegmentNodeState originalBase = base;
         SegmentNodeState originalHead = head;
-        long backoff = 1;
         while (base != head) {
             // apply commit hooks on the rebased changes
-            SegmentNodeState root = writer.writeNode(
-                    hook.processCommit(base, head));
+            NodeBuilder builder = head.builder();
+            builder.removeProperty("token");
+            builder.removeProperty("timeout");
+            builder.setChildNode(ROOT, hook.processCommit(
+                    base.getChildNode(ROOT), head.getChildNode(ROOT)));
+            SegmentNodeState newHead = writer.writeNode(builder.getNodeState());
             writer.flush();
 
             // use optimistic locking to update the journal
-            if (store.setHead(base, root)) {
-                base = root;
-                head = root;
+            if (store.setHead(base, newHead)) {
+                base = newHead;
+                head = newHead;
             } else {
                 // someone else was faster, so restore state and retry later
                 base = originalBase;
@@ -105,6 +114,7 @@ class SegmentNodeStoreBranch extends Abs
                         Thread.sleep(backoff, RANDOM.nextInt(1000000));
                         backoff *= 2;
                     } catch (InterruptedException e) {
+                        // TODO: correct interrupt handling?
                         throw new CommitFailedException(
                                 "Segment", 1, "Commit was interrupted", e);
                     }
@@ -118,7 +128,6 @@ class SegmentNodeStoreBranch extends Abs
                 rebase();
             }
         }
-
         return getHead();
     }
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileJournal.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileJournal.java?rev=1503273&r1=1503272&r2=1503273&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileJournal.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileJournal.java
Mon Jul 15 14:40:18 2013
@@ -24,8 +24,8 @@ class FileJournal extends MemoryJournal 
 
     private final FileStore store;
 
-    FileJournal(FileStore store, NodeState root) {
-        super(store, root);
+    FileJournal(FileStore store, NodeState head) {
+        super(store, head);
         this.store = store;
     }
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java?rev=1503273&r1=1503272&r2=1503273&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java
Mon Jul 15 14:40:18 2013
@@ -40,6 +40,7 @@ import org.apache.jackrabbit.oak.plugins
 import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeState;
 import org.apache.jackrabbit.oak.plugins.segment.SegmentStore;
 import org.apache.jackrabbit.oak.plugins.segment.Template;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -95,7 +96,9 @@ public class FileStore implements Segmen
         }
 
         if (!journals.containsKey("root")) {
-            journals.put("root", new FileJournal(this, root));
+            NodeBuilder builder = EMPTY_NODE.builder();
+            builder.setChildNode("root", root);
+            journals.put("root", new FileJournal(this, builder.getNodeState()));
         }
     }
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/memory/MemoryJournal.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/memory/MemoryJournal.java?rev=1503273&r1=1503272&r2=1503273&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/memory/MemoryJournal.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/memory/MemoryJournal.java
Mon Jul 15 14:40:18 2013
@@ -37,12 +37,12 @@ public class MemoryJournal implements Jo
 
     private RecordId head;
 
-    public MemoryJournal(SegmentStore store, NodeState root) {
+    public MemoryJournal(SegmentStore store, NodeState head) {
         this.store = checkNotNull(store);
         this.parent = null;
 
         SegmentWriter writer = new SegmentWriter(store);
-        RecordId id = writer.writeNode(root).getRecordId();
+        RecordId id = writer.writeNode(head).getRecordId();
         writer.flush();
 
         this.base = id;

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/memory/MemoryStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/memory/MemoryStore.java?rev=1503273&r1=1503272&r2=1503273&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/memory/MemoryStore.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/memory/MemoryStore.java
Mon Jul 15 14:40:18 2013
@@ -29,6 +29,7 @@ import org.apache.jackrabbit.oak.plugins
 import org.apache.jackrabbit.oak.plugins.segment.Segment;
 import org.apache.jackrabbit.oak.plugins.segment.SegmentStore;
 import org.apache.jackrabbit.oak.plugins.segment.Template;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 
 import com.google.common.collect.Maps;
@@ -41,7 +42,9 @@ public class MemoryStore implements Segm
             Maps.newConcurrentMap();
 
     public MemoryStore(NodeState root) {
-        journals.put("root", new MemoryJournal(this, root));
+        NodeBuilder builder = EMPTY_NODE.builder();
+        builder.setChildNode("root", root);
+        journals.put("root", new MemoryJournal(this, builder.getNodeState()));
     }
 
     public MemoryStore() {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/mongo/MongoJournal.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/mongo/MongoJournal.java?rev=1503273&r1=1503272&r2=1503273&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/mongo/MongoJournal.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/mongo/MongoJournal.java
Mon Jul 15 14:40:18 2013
@@ -61,7 +61,7 @@ class MongoJournal implements Journal {
 
     MongoJournal(
             SegmentStore store, DBCollection journals,
-            WriteConcern concern, NodeState root) {
+            WriteConcern concern, NodeState head) {
         this.store = checkNotNull(store);
         this.journals = checkNotNull(journals);
         this.concern = checkNotNull(concern);
@@ -71,11 +71,11 @@ class MongoJournal implements Journal {
         state = journals.findOne(id, null, primaryPreferred());
         if (state == null) {
             SegmentWriter writer = new SegmentWriter(store);
-            RecordId head = writer.writeNode(root).getRecordId();
+            RecordId headId = writer.writeNode(head).getRecordId();
             writer.flush();
             state = new BasicDBObject(of(
                     "_id",  "root",
-                    "head", head.toString()));
+                    "head", headId.toString()));
             try {
                 journals.insert(state, concern);
             } catch (MongoException.DuplicateKey e) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/mongo/MongoStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/mongo/MongoStore.java?rev=1503273&r1=1503272&r2=1503273&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/mongo/MongoStore.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/mongo/MongoStore.java
Mon Jul 15 14:40:18 2013
@@ -36,6 +36,7 @@ import org.apache.jackrabbit.oak.plugins
 import org.apache.jackrabbit.oak.plugins.segment.SegmentCache;
 import org.apache.jackrabbit.oak.plugins.segment.SegmentStore;
 import org.apache.jackrabbit.oak.plugins.segment.Template;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
@@ -62,8 +63,11 @@ public class MongoStore implements Segme
         this.db = checkNotNull(db);
         this.segments = db.getCollection("segments");
         this.cache = cache;
+        NodeBuilder builder = EMPTY_NODE.builder();
+        builder.child("root");
         journals.put("root", new MongoJournal(
-                this, db.getCollection("journals"), concern, EMPTY_NODE));
+                this, db.getCollection("journals"),
+                concern, builder.getNodeState()));
     }
 
     public MongoStore(DB db, long cacheSize) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeState.java?rev=1503273&r1=1503272&r2=1503273&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeState.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeState.java
Mon Jul 15 14:40:18 2013
@@ -18,8 +18,10 @@ package org.apache.jackrabbit.oak.spi.st
 
 import static java.util.Collections.emptyList;
 import static org.apache.jackrabbit.oak.api.Type.BOOLEAN;
+import static org.apache.jackrabbit.oak.api.Type.LONG;
 import static org.apache.jackrabbit.oak.api.Type.NAME;
 import static org.apache.jackrabbit.oak.api.Type.NAMES;
+import static org.apache.jackrabbit.oak.api.Type.STRING;
 
 import java.util.HashSet;
 import java.util.Iterator;
@@ -61,6 +63,26 @@ public abstract class AbstractNodeState 
                 && property.getValue(BOOLEAN);
     }
 
+    @Override
+    public long getLong(String name) {
+        PropertyState property = getProperty(name);
+        if (property != null && property.getType() == LONG) {
+            return property.getValue(LONG);
+        } else {
+            return 0;
+        }
+    }
+
+    @Override
+    public String getString(String name) {
+        PropertyState property = getProperty(name);
+        if (property != null && property.getType() == STRING) {
+            return property.getValue(STRING);
+        } else {
+            return null;
+        }
+    }
+
     @Override @CheckForNull
     public String getName(@Nonnull String name) {
         PropertyState property = getProperty(name);

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeState.java?rev=1503273&r1=1503272&r2=1503273&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeState.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeState.java
Mon Jul 15 14:40:18 2013
@@ -172,6 +172,41 @@ public interface NodeState {
     boolean getBoolean(@Nonnull String name);
 
     /**
+     * Returns the long value of the named property. The implementation
+     * is equivalent to the following code, but may be optimized.
+     * <pre>
+     * PropertyState property = state.getProperty(name);
+     * if (property != null && property.getType() == Type.LONG) {
+     *     return property.getValue(Type.LONG);
+     * } else {
+     *     return 0;
+     * }
+     * </pre>
+     *
+     * @param name property name
+     * @return long value of the named property, or zero
+     */
+    long getLong(String name);
+
+
+    /**
+     * Returns the string value of the named property. The implementation
+     * is equivalent to the following code, but may be optimized.
+     * <pre>
+     * PropertyState property = state.getProperty(name);
+     * if (property != null && property.getType() == Type.STRING) {
+     *     return property.getValue(Type.STRING);
+     * } else {
+     *     return null;
+     * }
+     * </pre>
+     *
+     * @param name property name
+     * @return string value of the named property, or {@code null}
+     */
+    String getString(String name);
+
+    /**
      * Returns the name value of the named property. The implementation
      * is equivalent to the following code, but may be optimized.
      * <pre>



Mime
View raw message