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 fr...@apache.org on 2018/04/24 09:36:48 UTC

svn commit: r1829974 - in /jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file: CleanupStrategy.java DefaultCleanupStrategy.java DefaultGarbageCollectionStrategy.java

Author: frm
Date: Tue Apr 24 09:36:48 2018
New Revision: 1829974

URL: http://svn.apache.org/viewvc?rev=1829974&view=rev
Log:
OAK-7436 - Refactor cleanup code in its own component

Introduce CleanupStrategy and its only implementation, DefaultCleanupStrategy.
DefaultGarbageCollectionStrategy has been modified to delegate to the
CleanupStrategy every time a cleanup operation is invoked.

Added:
    jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/CleanupStrategy.java   (with props)
    jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultCleanupStrategy.java   (with props)
Modified:
    jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultGarbageCollectionStrategy.java

Added: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/CleanupStrategy.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/CleanupStrategy.java?rev=1829974&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/CleanupStrategy.java (added)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/CleanupStrategy.java Tue Apr 24 09:36:48 2018
@@ -0,0 +1,62 @@
+/*
+ * 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.segment.file;
+
+import java.io.IOException;
+import java.util.List;
+
+import com.google.common.base.Predicate;
+import org.apache.jackrabbit.oak.segment.Revisions;
+import org.apache.jackrabbit.oak.segment.SegmentCache;
+import org.apache.jackrabbit.oak.segment.SegmentTracker;
+import org.apache.jackrabbit.oak.segment.file.tar.GCGeneration;
+import org.apache.jackrabbit.oak.segment.file.tar.TarFiles;
+
+interface CleanupStrategy {
+
+    interface Context {
+
+        GCListener getGCListener();
+
+        SegmentCache getSegmentCache();
+
+        SegmentTracker getSegmentTracker();
+
+        FileStoreStats getFileStoreStats();
+
+        GCNodeWriteMonitor getCompactionMonitor();
+
+        GCJournal getGCJournal();
+
+        Predicate<GCGeneration> getReclaimer();
+
+        TarFiles getTarFiles();
+
+        Revisions getRevisions();
+
+        String getCompactedRootId();
+
+        String getSegmentEvictionReason();
+
+    }
+
+    List<String> cleanup(Context context) throws IOException;
+
+}

Propchange: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/CleanupStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultCleanupStrategy.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultCleanupStrategy.java?rev=1829974&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultCleanupStrategy.java (added)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultCleanupStrategy.java Tue Apr 24 09:36:48 2018
@@ -0,0 +1,134 @@
+/*
+ * 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.segment.file;
+
+import static com.google.common.collect.Sets.newHashSet;
+import static org.apache.jackrabbit.oak.segment.SegmentId.isDataSegmentId;
+import static org.apache.jackrabbit.oak.segment.compaction.SegmentGCStatus.CLEANUP;
+import static org.apache.jackrabbit.oak.segment.file.PrintableBytes.newPrintableBytes;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.annotation.Nonnull;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Predicate;
+import org.apache.jackrabbit.oak.segment.SegmentId;
+import org.apache.jackrabbit.oak.segment.file.tar.CleanupContext;
+import org.apache.jackrabbit.oak.segment.file.tar.GCGeneration;
+import org.apache.jackrabbit.oak.segment.file.tar.TarFiles;
+
+class DefaultCleanupStrategy implements CleanupStrategy {
+
+    @Override
+    public List<String> cleanup(Context context) throws IOException {
+        PrintableStopwatch watch = PrintableStopwatch.createStarted();
+
+        context.getGCListener().info("cleanup started using reclaimer {}", context.getReclaimer());
+        context.getGCListener().updateStatus(CLEANUP.message());
+        context.getSegmentCache().clear();
+
+        // Suggest to the JVM that now would be a good time
+        // to clear stale weak references in the SegmentTracker
+        System.gc();
+
+        TarFiles.CleanupResult cleanupResult = context.getTarFiles().cleanup(newCleanupContext(context, context.getReclaimer()));
+        if (cleanupResult.isInterrupted()) {
+            context.getGCListener().info("cleanup interrupted");
+        }
+        context.getSegmentTracker().clearSegmentIdTables(cleanupResult.getReclaimedSegmentIds(), context.getSegmentEvictionReason());
+        context.getGCListener().info("cleanup marking files for deletion: {}", toFileNames(cleanupResult.getRemovableFiles()));
+
+        long finalSize = size(context);
+        long reclaimedSize = cleanupResult.getReclaimedSize();
+        context.getFileStoreStats().reclaimed(reclaimedSize);
+        context.getGCJournal().persist(
+            reclaimedSize,
+            finalSize,
+            getGcGeneration(context),
+            context.getCompactionMonitor().getCompactedNodes(),
+            context.getCompactedRootId()
+        );
+        context.getGCListener().cleaned(reclaimedSize, finalSize);
+        context.getGCListener().info(
+            "cleanup completed in {}. Post cleanup size is {} and space reclaimed {}.",
+            watch,
+            newPrintableBytes(finalSize),
+            newPrintableBytes(reclaimedSize)
+        );
+        return cleanupResult.getRemovableFiles();
+    }
+
+    private static CleanupContext newCleanupContext(Context context, Predicate<GCGeneration> old) {
+        return new CleanupContext() {
+
+            private boolean isUnreferencedBulkSegment(UUID id, boolean referenced) {
+                return !isDataSegmentId(id.getLeastSignificantBits()) && !referenced;
+            }
+
+            private boolean isOldDataSegment(UUID id, GCGeneration generation) {
+                return isDataSegmentId(id.getLeastSignificantBits()) && old.apply(generation);
+            }
+
+            @Override
+            public Collection<UUID> initialReferences() {
+                Set<UUID> references = newHashSet();
+                for (SegmentId id : context.getSegmentTracker().getReferencedSegmentIds()) {
+                    if (id.isBulkSegmentId()) {
+                        references.add(id.asUUID());
+                    }
+                }
+                return references;
+            }
+
+            @Override
+            public boolean shouldReclaim(UUID id, GCGeneration generation, boolean referenced) {
+                return isUnreferencedBulkSegment(id, referenced) || isOldDataSegment(id, generation);
+            }
+
+            @Override
+            public boolean shouldFollow(UUID from, UUID to) {
+                return !isDataSegmentId(to.getLeastSignificantBits());
+            }
+
+        };
+    }
+
+    private static String toFileNames(@Nonnull List<String> files) {
+        if (files.isEmpty()) {
+            return "none";
+        } else {
+            return Joiner.on(",").join(files);
+        }
+    }
+
+    private static GCGeneration getGcGeneration(Context context) {
+        return context.getRevisions().getHead().getSegmentId().getGcGeneration();
+    }
+
+    private static long size(Context context) {
+        return context.getTarFiles().size();
+    }
+
+}

Propchange: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultCleanupStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultGarbageCollectionStrategy.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultGarbageCollectionStrategy.java?rev=1829974&r1=1829973&r2=1829974&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultGarbageCollectionStrategy.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultGarbageCollectionStrategy.java Tue Apr 24 09:36:48 2018
@@ -19,29 +19,19 @@
 
 package org.apache.jackrabbit.oak.segment.file;
 
-import static com.google.common.collect.Sets.newHashSet;
-import static org.apache.jackrabbit.oak.segment.SegmentId.isDataSegmentId;
-import static org.apache.jackrabbit.oak.segment.compaction.SegmentGCStatus.CLEANUP;
 import static org.apache.jackrabbit.oak.segment.compaction.SegmentGCStatus.ESTIMATION;
 import static org.apache.jackrabbit.oak.segment.compaction.SegmentGCStatus.IDLE;
-import static org.apache.jackrabbit.oak.segment.file.PrintableBytes.newPrintableBytes;
 
 import java.io.IOException;
-import java.util.Collection;
 import java.util.List;
-import java.util.Set;
-import java.util.UUID;
 
-import javax.annotation.Nonnull;
-
-import com.google.common.base.Joiner;
 import com.google.common.base.Predicate;
 import org.apache.jackrabbit.oak.segment.Revisions;
-import org.apache.jackrabbit.oak.segment.SegmentId;
+import org.apache.jackrabbit.oak.segment.SegmentCache;
 import org.apache.jackrabbit.oak.segment.SegmentReader;
 import org.apache.jackrabbit.oak.segment.SegmentTracker;
 import org.apache.jackrabbit.oak.segment.compaction.SegmentGCOptions;
-import org.apache.jackrabbit.oak.segment.file.tar.CleanupContext;
+import org.apache.jackrabbit.oak.segment.file.CleanupStrategy.Context;
 import org.apache.jackrabbit.oak.segment.file.tar.GCGeneration;
 import org.apache.jackrabbit.oak.segment.file.tar.TarFiles;
 import org.apache.jackrabbit.oak.spi.blob.BlobStore;
@@ -52,6 +42,8 @@ class DefaultGarbageCollectionStrategy i
 
     private final CompactionStrategy tailCompactionStrategy = new FallbackCompactionStrategy(new TailCompactionStrategy(), fullCompactionStrategy);
 
+    private final CleanupStrategy cleanupStrategy = new DefaultCleanupStrategy();
+
     private GCGeneration getGcGeneration(Context context) {
         return context.getRevisions().getHead().getSegmentId().getGcGeneration();
     }
@@ -235,10 +227,6 @@ class DefaultGarbageCollectionStrategy i
         ).estimate();
     }
 
-    private long size(Context context) {
-        return context.getTarFiles().size();
-    }
-
     @Override
     public synchronized List<String> cleanup(Context context) throws IOException {
         return cleanup(context, CompactionResult.skipped(
@@ -250,86 +238,65 @@ class DefaultGarbageCollectionStrategy i
         ));
     }
 
-    private List<String> cleanup(Context context, CompactionResult compactionResult)
-        throws IOException {
-        PrintableStopwatch watch = PrintableStopwatch.createStarted();
-
-        context.getGCListener().info("cleanup started using reclaimer {}", compactionResult.reclaimer());
-        context.getGCListener().updateStatus(CLEANUP.message());
-        context.getSegmentCache().clear();
-
-        // Suggest to the JVM that now would be a good time
-        // to clear stale weak references in the SegmentTracker
-        System.gc();
-
-        TarFiles.CleanupResult cleanupResult = context.getTarFiles().cleanup(newCleanupContext(context, compactionResult.reclaimer()));
-        if (cleanupResult.isInterrupted()) {
-            context.getGCListener().info("cleanup interrupted");
-        }
-        context.getSegmentTracker().clearSegmentIdTables(cleanupResult.getReclaimedSegmentIds(), compactionResult.gcInfo());
-        context.getGCListener().info("cleanup marking files for deletion: {}", toFileNames(cleanupResult.getRemovableFiles()));
+    private List<String> cleanup(Context context, CompactionResult compactionResult) throws IOException {
+        return cleanupStrategy.cleanup(new CleanupStrategy.Context() {
 
-        long finalSize = size(context);
-        long reclaimedSize = cleanupResult.getReclaimedSize();
-        context.getFileStoreStats().reclaimed(reclaimedSize);
-        context.getGCJournal().persist(
-            reclaimedSize,
-            finalSize,
-            getGcGeneration(context),
-            context.getCompactionMonitor().getCompactedNodes(),
-            compactionResult.getCompactedRootId().toString10()
-        );
-        context.getGCListener().cleaned(reclaimedSize, finalSize);
-        context.getGCListener().info(
-            "cleanup completed in {}. Post cleanup size is {} and space reclaimed {}.",
-            watch,
-            newPrintableBytes(finalSize),
-            newPrintableBytes(reclaimedSize)
-        );
-        return cleanupResult.getRemovableFiles();
-    }
+            @Override
+            public GCListener getGCListener() {
+                return context.getGCListener();
+            }
 
-    private CleanupContext newCleanupContext(Context context, Predicate<GCGeneration> old) {
-        return new CleanupContext() {
+            @Override
+            public SegmentCache getSegmentCache() {
+                return context.getSegmentCache();
+            }
 
-            private boolean isUnreferencedBulkSegment(UUID id, boolean referenced) {
-                return !isDataSegmentId(id.getLeastSignificantBits()) && !referenced;
+            @Override
+            public SegmentTracker getSegmentTracker() {
+                return context.getSegmentTracker();
             }
 
-            private boolean isOldDataSegment(UUID id, GCGeneration generation) {
-                return isDataSegmentId(id.getLeastSignificantBits()) && old.apply(generation);
+            @Override
+            public FileStoreStats getFileStoreStats() {
+                return context.getFileStoreStats();
             }
 
             @Override
-            public Collection<UUID> initialReferences() {
-                Set<UUID> references = newHashSet();
-                for (SegmentId id : context.getSegmentTracker().getReferencedSegmentIds()) {
-                    if (id.isBulkSegmentId()) {
-                        references.add(id.asUUID());
-                    }
-                }
-                return references;
+            public GCNodeWriteMonitor getCompactionMonitor() {
+                return context.getCompactionMonitor();
             }
 
             @Override
-            public boolean shouldReclaim(UUID id, GCGeneration generation, boolean referenced) {
-                return isUnreferencedBulkSegment(id, referenced) || isOldDataSegment(id, generation);
+            public GCJournal getGCJournal() {
+                return context.getGCJournal();
             }
 
             @Override
-            public boolean shouldFollow(UUID from, UUID to) {
-                return !isDataSegmentId(to.getLeastSignificantBits());
+            public Predicate<GCGeneration> getReclaimer() {
+                return compactionResult.reclaimer();
             }
 
-        };
-    }
+            @Override
+            public TarFiles getTarFiles() {
+                return context.getTarFiles();
+            }
 
-    private String toFileNames(@Nonnull List<String> files) {
-        if (files.isEmpty()) {
-            return "none";
-        } else {
-            return Joiner.on(",").join(files);
-        }
+            @Override
+            public Revisions getRevisions() {
+                return context.getRevisions();
+            }
+
+            @Override
+            public String getCompactedRootId() {
+                return compactionResult.getCompactedRootId().toString10();
+            }
+
+            @Override
+            public String getSegmentEvictionReason() {
+                return compactionResult.gcInfo();
+            }
+
+        });
     }
 
 }