You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by ju...@apache.org on 2013/03/04 18:10:01 UTC

svn commit: r1452399 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment: MemoryStore.java MongoStore.java SegmentNodeStore.java SegmentNodeStoreBranch.java SegmentNodeStoreService.java SegmentStore.java

Author: jukka
Date: Mon Mar  4 17:10:01 2013
New Revision: 1452399

URL: http://svn.apache.org/r1452399
Log:
OAK-633: SegmentMK: Hierarchy of journals

Use the Journal interface to simplify more complex journal operations

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MemoryStore.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoStore.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/SegmentNodeStoreService.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MemoryStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MemoryStore.java?rev=1452399&r1=1452398&r2=1452399&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MemoryStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MemoryStore.java Mon Mar  4 17:10:01 2013
@@ -44,18 +44,23 @@ public class MemoryStore implements Segm
     }
 
     @Override
-    public RecordId getJournalHead(String name) {
-        RecordId head = journals.get(name);
-        if (head != null) {
-            return head;
-        } else {
-            throw new IllegalArgumentException("Journal not found: " + name);
-        }
-    }
-
-    @Override
-    public boolean setJournalHead(String name, RecordId head, RecordId base) {
-        return journals.replace(name, base, head);
+    public Journal getJournal(final String name) {
+        return new Journal() {
+            @Override
+            public RecordId getHead() {
+                RecordId head = journals.get(name);
+                if (head != null) {
+                    return head;
+                } else {
+                    throw new IllegalArgumentException(
+                            "Journal not found: " + name);
+                }
+            }
+            @Override
+            public boolean setHead(RecordId base, RecordId head) {
+                return journals.replace(name, base, head);
+            }
+        };
     }
 
     @Override

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoStore.java?rev=1452399&r1=1452398&r2=1452399&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoStore.java Mon Mar  4 17:10:01 2013
@@ -63,18 +63,22 @@ public class MongoStore implements Segme
     }
 
     @Override
-    public RecordId getJournalHead(String name) {
-        DBObject journal = journals.findOne(new BasicDBObject("_id", name));
-        return RecordId.fromString(journal.get("head").toString());
-    }
-
-    @Override
-    public boolean setJournalHead(String name, RecordId head, RecordId base) {
-        DBObject baseObject = new BasicDBObject(
-                ImmutableMap.of("_id", name, "head", base.toString()));
-        DBObject headObject = new BasicDBObject(
-                ImmutableMap.of("_id", name, "head", head.toString()));
-        return journals.findAndModify(baseObject, headObject) != null;
+    public Journal getJournal(final String name) {
+        return new Journal() {
+            @Override
+            public RecordId getHead() {
+                DBObject journal = journals.findOne(new BasicDBObject("_id", name));
+                return RecordId.fromString(journal.get("head").toString());
+            }
+            @Override
+            public boolean setHead(RecordId base, RecordId head) {
+                DBObject baseObject = new BasicDBObject(
+                        ImmutableMap.of("_id", name, "head", base.toString()));
+                DBObject headObject = new BasicDBObject(
+                        ImmutableMap.of("_id", name, "head", head.toString()));
+                return journals.findAndModify(baseObject, headObject) != null;
+            }
+        };
     }
 
     @Override

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=1452399&r1=1452398&r2=1452399&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 Mar  4 17:10:01 2013
@@ -30,13 +30,13 @@ public class SegmentNodeStore implements
 
     private final SegmentStore store;
 
-    private final String journal;
+    private final Journal journal;
 
     private final SegmentReader reader;
 
     public SegmentNodeStore(SegmentStore store, String journal) {
         this.store = store;
-        this.journal = journal;
+        this.journal = store.getJournal(journal);
         this.reader = new SegmentReader(store);
     }
 
@@ -46,7 +46,7 @@ public class SegmentNodeStore implements
 
     @Override @Nonnull
     public NodeState getRoot() {
-        return new SegmentNodeState(reader, store.getJournalHead(journal));
+        return new SegmentNodeState(reader, journal.getHead());
     }
 
     @Override @Nonnull

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=1452399&r1=1452398&r2=1452399&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 Mar  4 17:10:01 2013
@@ -16,7 +16,7 @@
  */
 package org.apache.jackrabbit.oak.plugins.segment;
 
-import java.util.concurrent.TimeUnit;
+import java.util.Random;
 
 import javax.annotation.Nonnull;
 
@@ -31,9 +31,9 @@ import org.apache.jackrabbit.oak.spi.sta
 
 class SegmentNodeStoreBranch implements NodeStoreBranch {
 
-    private final SegmentStore store;
+    private static final Random RANDOM = new Random();
 
-    private final String journal;
+    private final Journal journal;
 
     private final SegmentReader reader;
 
@@ -43,12 +43,12 @@ class SegmentNodeStoreBranch implements 
 
     private RecordId rootId;
 
-    SegmentNodeStoreBranch(SegmentStore store, String journal, SegmentReader reader) {
-        this.store = store;
+    SegmentNodeStoreBranch(
+            SegmentStore store, Journal journal, SegmentReader reader) {
         this.journal = journal;
         this.reader = reader;
         this.writer = new SegmentWriter(store, reader);
-        this.baseId = store.getJournalHead(journal);
+        this.baseId = journal.getHead();
         this.rootId = baseId;
     }
 
@@ -70,7 +70,7 @@ class SegmentNodeStoreBranch implements 
 
     @Override
     public synchronized void rebase() {
-        RecordId newBaseId = store.getJournalHead(journal);
+        RecordId newBaseId = journal.getHead();
         if (!baseId.equals(newBaseId)) {
             NodeBuilder builder =
                     new MemoryNodeBuilder(new SegmentNodeState(reader, newBaseId));
@@ -84,36 +84,42 @@ class SegmentNodeStoreBranch implements 
     @Override @Nonnull
     public synchronized NodeState merge(CommitHook hook)
             throws CommitFailedException {
+        rebase();
+
         RecordId originalBaseId = baseId;
         RecordId originalRootId = rootId;
         long backoff = 1;
-        for (int i = 0; i < 10; i++) {
-            // rebase to latest head and apply commit hooks
-            rebase();
+        while (baseId != rootId) {
+            // apply commit hooks on the rebased changes
             RecordId headId = writer.writeNode(
                     hook.processCommit(getBase(), getHead())).getRecordId();
             writer.flush();
 
             // use optimistic locking to update the journal
-            if (store.setJournalHead(journal, headId, baseId)) {
+            if (journal.setHead(baseId, headId)) {
                 baseId = headId;
                 rootId = headId;
-                return getHead();
-            }
-
-            // someone else was faster, so clear state and try again later
-            baseId = originalBaseId;
-            rootId = originalRootId;
-
-            // use exponential backoff to reduce contention
-            try {
-                TimeUnit.MICROSECONDS.sleep(backoff);
-                backoff *= 2;
-            } catch (InterruptedException e) {
-                throw new CommitFailedException("Commit was interrupted", e);
+            } else if (backoff < 10000) {
+                // someone else was faster, so try again later
+                // use exponential backoff to reduce contention
+                try {
+                    Thread.sleep(backoff, RANDOM.nextInt(1000000));
+                    backoff *= 2;
+                } catch (InterruptedException e) {
+                    throw new CommitFailedException("Commit was interrupted", e);
+                }
+
+                // rebase to latest head before trying again
+                baseId = originalBaseId;
+                rootId = originalRootId;
+                rebase();
+            } else {
+                // 
+                throw new CommitFailedException("System overloaded, try again later");
             }
         }
-        throw new CommitFailedException("System overloaded, try again later");
+
+        return getHead();
     }
 
     @Override

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreService.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreService.java?rev=1452399&r1=1452398&r2=1452399&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreService.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreService.java Mon Mar  4 17:10:01 2013
@@ -61,13 +61,8 @@ public class SegmentNodeStoreService ext
     public SegmentNodeStoreService(final SegmentStore[] store) {
         super(new SegmentStore() {
             @Override
-            public RecordId getJournalHead(String name) {
-                return store[0].getJournalHead(name);
-            }
-            @Override
-            public boolean setJournalHead(
-                    String name, RecordId head, RecordId base) {
-                return store[0].setJournalHead(name, head, base);
+            public Journal getJournal(String name) {
+                return store[0].getJournal(name);
             }
             @Override
             public Segment readSegment(UUID segmentId) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java?rev=1452399&r1=1452398&r2=1452399&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java Mon Mar  4 17:10:01 2013
@@ -20,9 +20,7 @@ import java.util.UUID;
 
 public interface SegmentStore {
 
-    RecordId getJournalHead(String name);
-
-    boolean setJournalHead(String name, RecordId head, RecordId base);
+    Journal getJournal(String name);
 
     Segment readSegment(UUID segmentId);