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 2014/05/29 15:43:55 UTC

svn commit: r1598292 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java

Author: jukka
Date: Thu May 29 13:43:55 2014
New Revision: 1598292

URL: http://svn.apache.org/r1598292
Log:
OAK-1804: TarMK compaction

Move the compaction code outside flush() to deadlocks

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java
    jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java

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=1598292&r1=1598291&r2=1598292&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 Thu May 29 13:43:55 2014
@@ -67,6 +67,7 @@ import org.apache.jackrabbit.oak.plugins
 import org.apache.jackrabbit.oak.plugins.segment.SegmentStore;
 import org.apache.jackrabbit.oak.plugins.segment.SegmentWriter;
 import org.apache.jackrabbit.oak.spi.blob.BlobStore;
+import org.apache.jackrabbit.oak.spi.state.ApplyDiff;
 import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
@@ -338,7 +339,30 @@ public class FileStore implements Segmen
         return dataFiles;
     }
 
-    void compact(SegmentNodeState state, String name, int levels,
+    public void compact(int levels) throws IOException {
+        log.debug("TarMK compaction");
+
+        SegmentWriter segmentWriter = tracker.getWriter();
+        segmentWriter.dropCache();
+
+        SegmentNodeBuilder builder =
+                segmentWriter.writeNode(EMPTY_NODE).builder();
+        SegmentNodeState before = getHead();
+        compact(before, "/", levels, builder);
+
+        SegmentNodeState after = builder.getNodeState();
+        while (!setHead(before, after)) {
+            // Some other concurrent changes have been made.
+            // Rebase those changes on top of the compacted
+            // state before retrying setting the head state.
+            SegmentNodeState head = getHead();
+            head.compareAgainstBaseState(before, new ApplyDiff(builder));
+            before = head;
+            after = builder.getNodeState();
+        }
+    }
+
+    private void compact(SegmentNodeState state, String name, int levels,
             NodeBuilder dest) throws IOException {
         for (PropertyState ps : state.getProperties()) {
             if (Type.BINARY.tag() != ps.getType().tag()) {
@@ -384,8 +408,7 @@ public class FileStore implements Segmen
             if (cleanup || !after.equals(before)) {
                 // needs to happen outside the synchronization block below to
                 // avoid a deadlock with another thread flushing the writer
-                SegmentWriter segmentWriter = tracker.getWriter();
-                segmentWriter.flush();
+                tracker.getWriter().flush();
 
                 // needs to happen outside the synchronization block below to
                 // prevent the flush from stopping concurrent reads and writes
@@ -400,18 +423,6 @@ public class FileStore implements Segmen
                     if (cleanup) {
                         long start = System.nanoTime();
 
-                        log.debug("TarMK compaction");
-                        segmentWriter.dropCache();
-                        SegmentNodeBuilder builder =
-                                segmentWriter.writeNode(EMPTY_NODE).builder();
-                        SegmentNodeState state = new SegmentNodeState(after);
-                        compact(state, "/", 5, builder);
-                        setHead(state, builder.getNodeState());
-                        before = null;
-                        after = null;
-                        state = null;
-                        System.gc();
-
                         Set<UUID> ids = newHashSet();
                         for (SegmentId id : tracker.getReferencedSegmentIds()) {
                             ids.add(new UUID(

Modified: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java?rev=1598292&r1=1598291&r2=1598292&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java (original)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java Thu May 29 13:43:55 2014
@@ -178,31 +178,38 @@ public class Main {
     }
 
     private static void compact(String[] args) throws IOException {
-        if (args.length != 1) {
-            System.err.println("usage: compact <path>");
+        if (args.length < 1 || args.length > 2) {
+            System.err.println("usage: compact <path> [levels]");
             System.exit(1);
         } else {
+            int levels = 5;
+            if (args.length == 2) {
+                levels = Integer.parseInt(args[1]);
+            }
+
             File directory = new File(args[0]);
-            FileStore store = new FileStore(directory, 256, false);
             System.out.println("Compacting " + directory);
-
             System.out.println("    before " + Arrays.toString(directory.list()));
+
+            System.out.println("    -> compacting");
+            FileStore store = new FileStore(directory, 256, false);
             try {
-                store.gc();
-                store.flush();
+                store.compact(levels);
+            } finally {
                 store.close();
-                System.gc();
+            }
 
-                store = new FileStore(directory, 256, false);
+            System.out.println("    -> cleaning up");
+            store = new FileStore(directory, 256, false);
+            try {
                 store.gc();
                 store.flush();
-
-                System.out
-                        .println("    after  " + Arrays.toString(directory.list()));
             } finally {
                 store.close();
             }
 
+
+            System.out.println("    after  " + Arrays.toString(directory.list()));
         }
     }