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 md...@apache.org on 2017/08/11 12:13:25 UTC

svn commit: r1804781 - in /jackrabbit/oak/trunk/oak-segment-tar/src: main/java/org/apache/jackrabbit/oak/segment/ main/java/org/apache/jackrabbit/oak/segment/compaction/ main/java/org/apache/jackrabbit/oak/segment/file/ test/java/org/apache/jackrabbit/...

Author: mduerig
Date: Fri Aug 11 12:13:24 2017
New Revision: 1804781

URL: http://svn.apache.org/viewvc?rev=1804781&view=rev
Log:
OAK-6399: Re-establish full offline compaction functionality
Re-establish full progress logging functionality found in (offline) Compactor in OnlineCompactor

Modified:
    jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/OnlineCompactor.java
    jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreService.java
    jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/compaction/SegmentGCOptions.java
    jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/compaction/SegmentRevisionGCMBean.java
    jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
    jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStoreBuilder.java
    jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/GCListener.java
    jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/GCNodeWriteMonitor.java
    jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/OnlineCompactorTest.java

Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/OnlineCompactor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/OnlineCompactor.java?rev=1804781&r1=1804780&r2=1804781&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/OnlineCompactor.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/OnlineCompactor.java Fri Aug 11 12:13:24 2017
@@ -40,6 +40,7 @@ import org.apache.jackrabbit.oak.api.Blo
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeBuilder;
+import org.apache.jackrabbit.oak.segment.file.GCNodeWriteMonitor;
 import org.apache.jackrabbit.oak.spi.blob.BlobStore;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
@@ -75,7 +76,7 @@ public class OnlineCompactor {
     private final Supplier<Boolean> cancel;
 
     @Nonnull
-    private final Runnable onNode;
+    private final GCNodeWriteMonitor compactionMonitor;
 
     /**
      * Create a new instance based on the passed arguments.
@@ -83,19 +84,20 @@ public class OnlineCompactor {
      * @param writer     segment writer used to serialise to segments
      * @param blobStore  the blob store or {@code null} if none
      * @param cancel     a flag that can be used to cancel the compaction process
-     * @param onNode     notification call back for each compacted node
+     * @param compactionMonitor   notification call back for each compacted nodes,
+     *                            properties, and binaries
      */
     public OnlineCompactor(
             @Nonnull SegmentReader reader,
             @Nonnull SegmentWriter writer,
             @Nullable BlobStore blobStore,
             @Nonnull Supplier<Boolean> cancel,
-            @Nonnull Runnable onNode) {
+            @Nonnull GCNodeWriteMonitor compactionMonitor) {
         this.writer = checkNotNull(writer);
         this.reader = checkNotNull(reader);
         this.blobStore = blobStore;
         this.cancel = checkNotNull(cancel);
-        this.onNode = checkNotNull(onNode);
+        this.compactionMonitor = checkNotNull(compactionMonitor);
     }
 
     /**
@@ -172,7 +174,7 @@ public class OnlineCompactor {
                 NodeState nodeState = builder.getNodeState();
                 checkState(modCount == 0 || !(nodeState instanceof SegmentNodeState));
                 RecordId nodeId = writer.writeNode(nodeState, getStableIdBytes(after));
-                onNode.run();
+                compactionMonitor.onNode();
                 return new SegmentNodeState(reader, writer, blobStore, nodeId);
             } else {
                 return null;
@@ -245,14 +247,17 @@ public class OnlineCompactor {
     }
 
     @Nonnull
-    private static PropertyState compact(@Nonnull PropertyState property) {
+    private  PropertyState compact(@Nonnull PropertyState property) {
+        compactionMonitor.onProperty();
         String name = property.getName();
         Type<?> type = property.getType();
         if (type == BINARY) {
+            compactionMonitor.onBinary();
             return binaryProperty(name, property.getValue(Type.BINARY));
         } else if (type == BINARIES) {
             List<Blob> blobs = newArrayList();
             for (Blob blob : property.getValue(BINARIES)) {
+                compactionMonitor.onBinary();
                 blobs.add(blob);
             }
             return binaryPropertyFromBlob(name, blobs);

Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreService.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreService.java?rev=1804781&r1=1804780&r2=1804781&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreService.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreService.java Fri Aug 11 12:13:24 2017
@@ -437,7 +437,7 @@ public class SegmentNodeStoreService {
                 .setGcSizeDeltaEstimation(configuration.getSizeDeltaEstimation())
                 .setMemoryThreshold(configuration.getMemoryThreshold())
                 .setEstimationDisabled(configuration.getDisableEstimation())
-                .withGCNodeWriteMonitor(configuration.getGCProcessLog());
+                .setGCLogInterval(configuration.getGCProcessLog());
 
         // Build the FileStore
         FileStoreBuilder builder = fileStoreBuilder(configuration.getSegmentDirectory())

Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/compaction/SegmentGCOptions.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/compaction/SegmentGCOptions.java?rev=1804781&r1=1804780&r2=1804781&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/compaction/SegmentGCOptions.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/compaction/SegmentGCOptions.java Fri Aug 11 12:13:24 2017
@@ -23,8 +23,6 @@ import static com.google.common.base.Pre
 
 import javax.annotation.Nonnull;
 
-import org.apache.jackrabbit.oak.segment.file.GCNodeWriteMonitor;
-
 /**
  * This class holds configuration options for segment store revision gc.
  */
@@ -119,10 +117,10 @@ public class SegmentGCOptions {
             SIZE_DELTA_ESTIMATION_DEFAULT);
 
     /**
-     * Responsible for monitoring progress of the online compaction, and
-     * providing progress tracking.
+     * Number of nodes after which an update about the compaction process is logged.
+     * -1 for never.
      */
-    private GCNodeWriteMonitor gcNodeWriteMonitor = GCNodeWriteMonitor.EMPTY;
+    private long gcLogInterval = -1;
 
     public SegmentGCOptions(boolean paused, int retryCount, int forceTimeout) {
         this.paused = paused;
@@ -370,19 +368,22 @@ public class SegmentGCOptions {
     }
 
     /**
-     * Enables the GcWriteMonitor with the given params.
-     * @param gcProgressLog
-     *            Enables compaction progress logging at each set of compacted nodes, disabled if set to
-     *            {@code -1}
+     * Set the number of nodes after which an update about the compaction process is logged.
+     * -1 for never.
+     * @param gcLogInterval  update interval
      * @return this instance
      */
-    public SegmentGCOptions withGCNodeWriteMonitor(long gcProgressLog) {
-        this.gcNodeWriteMonitor = new GCNodeWriteMonitor(gcProgressLog);
+    public SegmentGCOptions setGCLogInterval(long gcLogInterval) {
+        this.gcLogInterval = gcLogInterval;
         return this;
     }
 
-    public GCNodeWriteMonitor getGCNodeWriteMonitor() {
-        return gcNodeWriteMonitor;
+    /**
+     * @return Number of nodes after which an update about the compaction process is logged.
+     * -1 for never.
+     */
+    public long getGcLogInterval() {
+        return gcLogInterval;
     }
 
 }

Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/compaction/SegmentRevisionGCMBean.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/compaction/SegmentRevisionGCMBean.java?rev=1804781&r1=1804780&r2=1804781&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/compaction/SegmentRevisionGCMBean.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/compaction/SegmentRevisionGCMBean.java Fri Aug 11 12:13:24 2017
@@ -184,31 +184,31 @@ public class SegmentRevisionGCMBean
 
     @Override
     public boolean isRevisionGCRunning() {
-        return gcOptions.getGCNodeWriteMonitor().isCompactionRunning();
+        return fileStore.getGCNodeWriteMonitor().isCompactionRunning();
     }
 
     @Override
     public long getCompactedNodes() {
-        return gcOptions.getGCNodeWriteMonitor().getCompactedNodes();
+        return fileStore.getGCNodeWriteMonitor().getCompactedNodes();
     }
 
     @Override
     public long getEstimatedCompactableNodes() {
-        return gcOptions.getGCNodeWriteMonitor().getEstimatedTotal();
+        return fileStore.getGCNodeWriteMonitor().getEstimatedTotal();
     }
 
     @Override
     public int getEstimatedRevisionGCCompletion() {
-        return gcOptions.getGCNodeWriteMonitor().getEstimatedPercentage();
+        return fileStore.getGCNodeWriteMonitor().getEstimatedPercentage();
     }
 
     @Override
     public long getRevisionGCProgressLog() {
-        return gcOptions.getGCNodeWriteMonitor().getGcProgressLog();
+        return fileStore.getGCNodeWriteMonitor().getGcProgressLog();
     }
 
     @Override
     public void setRevisionGCProgressLog(long gcProgressLog) {
-        gcOptions.getGCNodeWriteMonitor().setGcProgressLog(gcProgressLog);
+        gcOptions.setGCLogInterval(gcProgressLog);
     }
 }

Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java?rev=1804781&r1=1804780&r2=1804781&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java Fri Aug 11 12:13:24 2017
@@ -72,7 +72,6 @@ import com.google.common.base.Joiner;
 import com.google.common.base.Predicate;
 import com.google.common.base.Stopwatch;
 import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
 import com.google.common.io.Closer;
 import org.apache.jackrabbit.oak.segment.OnlineCompactor;
 import org.apache.jackrabbit.oak.segment.RecordId;
@@ -291,6 +290,13 @@ public class FileStore extends AbstractF
     }
 
     /**
+     * @return the currently active gc write monitor
+     */
+    public GCNodeWriteMonitor getGCNodeWriteMonitor() {
+        return garbageCollector.getGCNodeWriteMonitor();
+    }
+
+    /**
      * @return the size of this store.
      */
     private long size() {
@@ -339,7 +345,7 @@ public class FileStore extends AbstractF
      * @return
      */
     public GCEstimation estimateCompactionGain() {
-        return garbageCollector.estimateCompactionGain(Suppliers.ofInstance(false));
+        return garbageCollector.estimateCompactionGain();
     }
 
     /**
@@ -543,10 +549,10 @@ public class FileStore extends AbstractF
         private final WriterCacheManager cacheManager;
 
         @Nonnull
-        private final GCNodeWriteMonitor compactionMonitor;
+        private final StatisticsProvider statisticsProvider;
 
         @Nonnull
-        private final StatisticsProvider statisticsProvider;
+        private GCNodeWriteMonitor compactionMonitor = GCNodeWriteMonitor.EMPTY;
 
         private volatile boolean cancelled;
 
@@ -566,10 +572,13 @@ public class FileStore extends AbstractF
             this.gcListener = gcListener;
             this.gcJournal = gcJournal;
             this.cacheManager = cacheManager;
-            this.compactionMonitor = gcOptions.getGCNodeWriteMonitor();
             this.statisticsProvider = statisticsProvider;
         }
 
+        GCNodeWriteMonitor getGCNodeWriteMonitor() {
+            return compactionMonitor;
+        }
+
         synchronized void run() throws IOException {
             switch (gcOptions.getGCType()) {
                 case FULL:
@@ -594,6 +603,7 @@ public class FileStore extends AbstractF
         private void run(Supplier<CompactionResult> compact) throws IOException {
             try {
                 gcListener.info("TarMK GC #{}: started", GC_COUNT.incrementAndGet());
+                compactionMonitor = new GCNodeWriteMonitor(gcOptions.getGcLogInterval(), gcListener);
 
                 long dt = System.currentTimeMillis() - lastSuccessfullGC;
                 if (dt < GC_BACKOFF) {
@@ -615,14 +625,7 @@ public class FileStore extends AbstractF
                     gcListener.updateStatus(ESTIMATION.message());
                     
                     Stopwatch watch = Stopwatch.createStarted();
-                    Supplier<Boolean> cancel = new CancelCompactionSupplier(FileStore.this);
-                    GCEstimation estimate = estimateCompactionGain(cancel);
-                    if (cancel.get()) {
-                        gcListener.warn("TarMK GC #{}: estimation interrupted: {}. Skipping garbage collection.", GC_COUNT, cancel);
-                        gcMemoryBarrier.close();
-                        return;
-                    }
-    
+                    GCEstimation estimate = estimateCompactionGain();
                     sufficientEstimatedGain = estimate.gcNeeded();
                     String gcLog = estimate.gcLog();
                     if (sufficientEstimatedGain) {
@@ -659,10 +662,9 @@ public class FileStore extends AbstractF
         /**
          * Estimated compaction gain. The result will be undefined if stopped through
          * the passed {@code stop} signal.
-         * @param stop  signal for stopping the estimation process.
          * @return compaction gain estimate
          */
-        synchronized GCEstimation estimateCompactionGain(Supplier<Boolean> stop) {
+        synchronized GCEstimation estimateCompactionGain() {
             return new SizeDeltaGcEstimation(gcOptions, gcJournal,
                     stats.getApproximateSize());
         }
@@ -730,7 +732,7 @@ public class FileStore extends AbstractF
                         .withoutWriterPool()
                         .build(FileStore.this);
                 OnlineCompactor compactor = new OnlineCompactor(
-                        segmentReader, writer, getBlobStore(), cancel, compactionMonitor::onNode);
+                        segmentReader, writer, getBlobStore(), cancel, compactionMonitor);
 
                 SegmentNodeState after = compact(base, before, compactor, writer);
                 if (after == null) {

Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStoreBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStoreBuilder.java?rev=1804781&r1=1804780&r2=1804781&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStoreBuilder.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStoreBuilder.java Fri Aug 11 12:13:24 2017
@@ -48,6 +48,7 @@ import org.apache.jackrabbit.oak.segment
 import org.apache.jackrabbit.oak.segment.file.tar.IOMonitor;
 import org.apache.jackrabbit.oak.segment.file.tar.IOMonitorAdapter;
 import org.apache.jackrabbit.oak.spi.blob.BlobStore;
+import org.apache.jackrabbit.oak.spi.gc.DelegatingGCMonitor;
 import org.apache.jackrabbit.oak.spi.gc.GCMonitor;
 import org.apache.jackrabbit.oak.spi.gc.LoggingGCMonitor;
 import org.apache.jackrabbit.oak.stats.StatisticsProvider;
@@ -96,8 +97,7 @@ public class FileStoreBuilder {
     @CheckForNull
     private EvictingWriteCacheManager cacheManager;
 
-    @Nonnull
-    private final GCListener gcListener = new GCListener(){
+    private class FileStoreGCListener extends DelegatingGCMonitor implements GCListener {
         @Override
         public void compactionSucceeded(@Nonnull GCGeneration newGeneration) {
             compacted();
@@ -112,7 +112,10 @@ public class FileStoreBuilder {
                 cacheManager.evictGeneration(failedGeneration.getGeneration());
             }
         }
-    };
+    }
+
+    @Nonnull
+    private final FileStoreGCListener gcListener = new FileStoreGCListener();
 
     @Nonnull
     private SegmentNotFoundExceptionListener snfeListener = LOG_SNFE;

Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/GCListener.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/GCListener.java?rev=1804781&r1=1804780&r2=1804781&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/GCListener.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/GCListener.java Fri Aug 11 12:13:24 2017
@@ -22,24 +22,24 @@ package org.apache.jackrabbit.oak.segmen
 import javax.annotation.Nonnull;
 
 import org.apache.jackrabbit.oak.segment.file.tar.GCGeneration;
-import org.apache.jackrabbit.oak.spi.gc.DelegatingGCMonitor;
+import org.apache.jackrabbit.oak.spi.gc.GCMonitor;
 
 /**
  * Listener receiving notifications about the garbage collection process
  */
-abstract class GCListener extends DelegatingGCMonitor {
+interface GCListener extends GCMonitor {
 
     /**
      * Notification of a successfully completed compaction resulting in
      * a new generation of segments
      * @param newGeneration  the new generation number
      */
-    public abstract void compactionSucceeded(@Nonnull GCGeneration newGeneration);
+    void compactionSucceeded(@Nonnull GCGeneration newGeneration);
 
     /**
      * Notification of a failed compaction. A new generation of
      * segments could not be created.
      * @param failedGeneration  the generation number that could not be created
      */
-    public abstract void compactionFailed(@Nonnull GCGeneration failedGeneration);
+    void compactionFailed(@Nonnull GCGeneration failedGeneration);
 }

Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/GCNodeWriteMonitor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/GCNodeWriteMonitor.java?rev=1804781&r1=1804780&r2=1804781&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/GCNodeWriteMonitor.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/GCNodeWriteMonitor.java Fri Aug 11 12:13:24 2017
@@ -18,8 +18,9 @@
  */
 package org.apache.jackrabbit.oak.segment.file;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import javax.annotation.Nonnull;
+
+import org.apache.jackrabbit.oak.spi.gc.GCMonitor;
 
 /**
  * Monitors the compaction cycle and keeps a compacted nodes counter, in order
@@ -27,15 +28,15 @@ import org.slf4j.LoggerFactory;
  * size and node count and current size to deduce current node count.
  */
 public class GCNodeWriteMonitor {
-
-    private static final Logger log = LoggerFactory.getLogger(GCNodeWriteMonitor.class);
-
-    public static final GCNodeWriteMonitor EMPTY = new GCNodeWriteMonitor(-1);
+    public static final GCNodeWriteMonitor EMPTY = new GCNodeWriteMonitor(
+            -1, GCMonitor.EMPTY);
 
     /**
      * Number of nodes the monitor will log a message, -1 to disable
      */
-    private long gcProgressLog;
+    private final long gcProgressLog;
+
+    private final GCMonitor gcMonitor;
 
     /**
      * Start timestamp of compaction (reset at each {@code init()} call).
@@ -48,25 +49,27 @@ public class GCNodeWriteMonitor {
     private long estimated = -1;
 
     /**
-     * Compacted nodes per cycle (reset at each {@code init()} call).
+     * Number of compacted nodes
      */
     private long nodes;
 
+    /**
+     * Number of compacted properties
+     */
+    private long properties;
+
+    /**
+     * Number of compacted binaries
+     */
+    private long binaries;
+
     private boolean running = false;
 
     private long gcCount;
 
-    public GCNodeWriteMonitor(long gcProgressLog) {
+    public GCNodeWriteMonitor(long gcProgressLog, @Nonnull GCMonitor gcMonitor) {
         this.gcProgressLog = gcProgressLog;
-    }
-
-    public synchronized void onNode() {
-        nodes++;
-        if (gcProgressLog > 0 && nodes % gcProgressLog == 0) {
-            long ms = System.currentTimeMillis() - start;
-            log.info("TarMK GC #{}: compacted {} nodes in {} ms.", gcCount, nodes, ms);
-            start = System.currentTimeMillis();
-        }
+        this.gcMonitor = gcMonitor;
     }
 
     /**
@@ -83,18 +86,34 @@ public class GCNodeWriteMonitor {
         this.gcCount = gcCount;
         if (prevCompactedNodes > 0) {
             estimated = (long) (((double) currentSize / prevSize) * prevCompactedNodes);
-            log.info(
+            gcMonitor.info(
                     "TarMK GC #{}: estimated number of nodes to compact is {}, based on {} nodes compacted to {} bytes "
                             + "on disk in previous compaction and current size of {} bytes on disk.",
                     this.gcCount, estimated, prevCompactedNodes, prevSize, currentSize);
         } else {
-            log.info("TarMK GC #{}: unable to estimate number of nodes for compaction, missing gc history.", gcCount);
+            gcMonitor.info("TarMK GC #{}: unable to estimate number of nodes for compaction, missing gc history.", gcCount);
         }
         nodes = 0;
         start = System.currentTimeMillis();
         running = true;
     }
 
+    public synchronized void onNode() {
+        nodes++;
+        if (gcProgressLog > 0 && nodes % gcProgressLog == 0) {
+            gcMonitor.info("TarMK GC #{}: compacted {} nodes, {} properties, {} binaries in {} ms.",
+                    gcCount, nodes, properties, binaries, System.currentTimeMillis() - start);
+        }
+    }
+
+    public synchronized void onProperty() {
+        properties++;
+    }
+
+    public synchronized void onBinary() {
+        binaries++;
+    }
+
     public synchronized void finished() {
         running = false;
     }
@@ -136,8 +155,4 @@ public class GCNodeWriteMonitor {
     public long getGcProgressLog() {
         return gcProgressLog;
     }
-
-    public void setGcProgressLog(long gcProgressLog) {
-        this.gcProgressLog = gcProgressLog;
-    }
 }

Modified: jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/OnlineCompactorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/OnlineCompactorTest.java?rev=1804781&r1=1804780&r2=1804781&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/OnlineCompactorTest.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/OnlineCompactorTest.java Fri Aug 11 12:13:24 2017
@@ -46,6 +46,7 @@ import org.apache.jackrabbit.oak.api.Blo
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.segment.file.FileStore;
+import org.apache.jackrabbit.oak.segment.file.GCNodeWriteMonitor;
 import org.apache.jackrabbit.oak.segment.file.InvalidFileStoreVersionException;
 import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
 import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
@@ -138,7 +139,8 @@ public class OnlineCompactorTest {
         if (failOnName != null) {
             writer = new FailingSegmentWriter(writer, failOnName);
         }
-        return new OnlineCompactor(fileStore.getReader(), writer, fileStore.getBlobStore(), cancel, () -> {}); }
+        return new OnlineCompactor(fileStore.getReader(), writer, fileStore.getBlobStore(), cancel, GCNodeWriteMonitor.EMPTY);
+    }
 
     private static void addNodes(SegmentNodeStore nodeStore, int count)
     throws CommitFailedException {