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 al...@apache.org on 2013/12/03 17:11:57 UTC

svn commit: r1547453 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java test/java/org/apache/jackrabbit/oak/plugins/segment/CheckpointTest.java

Author: alexparvulescu
Date: Tue Dec  3 16:11:57 2013
New Revision: 1547453

URL: http://svn.apache.org/r1547453
Log:
OAK-1250 Guard against invalid/missing checkpoints

Added:
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CheckpointTest.java   (with props)
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java

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=1547453&r1=1547452&r2=1547453&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 Tue Dec  3 16:11:57 2013
@@ -178,17 +178,45 @@ public class SegmentNodeStore implements
     @Override @Nonnull
     public synchronized String checkpoint(long lifetime) {
         checkArgument(lifetime > 0);
-        // TODO: Guard the checkpoint from garbage collection
-        return head.getRecordId().toString();
+        String name = UUID.randomUUID().toString();
+
+        // try 5 times
+        for (int i = 0; i < 5; i++) {
+            if (commitSemaphore.tryAcquire()) {
+                try {
+                    refreshHead();
+
+                    SegmentNodeState ns = head;
+                    RecordId ri = head.getRecordId();
+
+                    SegmentRootBuilder builder = ns.builder();
+                    NodeBuilder cp = builder.child(name);
+                    cp.setProperty("timestamp", System.currentTimeMillis()
+                            + lifetime);
+                    cp.setChildNode(ROOT, ns.getChildNode(ROOT));
+
+                    if (journal.setHead(ri, builder.getNodeState()
+                            .getRecordId())) {
+                        refreshHead();
+                        return name;
+                    }
+
+                } finally {
+                    commitSemaphore.release();
+                }
+            }
+        }
+
+        return name;
     }
 
     @Override @CheckForNull
     public synchronized NodeState retrieve(@Nonnull String checkpoint) {
-        // TODO: Verify validity of the checkpoint
-        RecordId id = RecordId.fromString(checkNotNull(checkpoint));
-        SegmentNodeState root =
-                new SegmentNodeState(store.getWriter().getDummySegment(), id);
-        return root.getChildNode(ROOT);
+        NodeState cp = head.getChildNode(checkpoint).getChildNode(ROOT);
+        if (cp.exists()) {
+            return cp;
+        }
+        return null;
     }
 
     private class Commit {

Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CheckpointTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CheckpointTest.java?rev=1547453&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CheckpointTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CheckpointTest.java Tue Dec  3 16:11:57 2013
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.segment;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.plugins.segment.memory.MemoryStore;
+import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.junit.Test;
+
+public class CheckpointTest {
+
+    @Test
+    public void testCheckpoint() throws CommitFailedException {
+        SegmentNodeStore store = new SegmentNodeStore(new MemoryStore());
+        addTestNode(store, "test-checkpoint");
+        verifyNS(store, true);
+        rmTestNode(store, "test-checkpoint");
+        verifyNS(store, false);
+
+        // gc?
+        store.retrieve(SegmentIdFactory.newDataSegmentId().toString());
+    }
+
+    private static void verifyNS(SegmentNodeStore store, boolean exists) {
+        String cp = store.checkpoint(TimeUnit.HOURS.toMillis(1));
+        assertNotNull("Checkpoint must not be null", cp);
+
+        NodeState root = store.head;
+        assertTrue("Checkpoint doesn't exist", root.getChildNode(cp).exists());
+
+        NodeState cpns = store.retrieve(cp);
+        assertNotNull(cpns);
+        if (exists) {
+            assertTrue("Node doesn't exist in checkpoint",
+                    cpns.getChildNode("test-checkpoint").exists());
+        } else {
+            assertFalse("Node shouldn't exist in checkpoint", cpns
+                    .getChildNode("test-checkpoint").exists());
+        }
+    }
+
+    private static void addTestNode(NodeStore store, String name)
+            throws CommitFailedException {
+        NodeBuilder builder = store.getRoot().builder();
+        builder.child(name);
+        store.merge(builder, EmptyHook.INSTANCE, null);
+    }
+
+    private static void rmTestNode(NodeStore store, String name)
+            throws CommitFailedException {
+        NodeBuilder builder = store.getRoot().builder();
+        builder.child(name).remove();
+        store.merge(builder, EmptyHook.INSTANCE, null);
+    }
+
+}

Propchange: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CheckpointTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain