This is an automated email from the ASF dual-hosted git repository. miroslav pushed a commit to branch revert-1880-OAK-11287 in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git
commit 7a98eb33a21c65dbadb0a2140e86d73f958eefeb Author: Miroslav Smiljanic <smmiros...@gmail.com> AuthorDate: Fri Mar 7 16:40:39 2025 +0100 Revert "OAK-11287: Cleanup May Delete Referenced Segments (#1880)" This reverts commit bc67ca7fca774fbe00771d099da2d8abdb1c79e2. --- .../oak/segment/azure/tool/AzureCompact.java | 9 +- ...java => AbstractGarbageCollectionStrategy.java} | 53 ++-- .../file/CleanupFirstCompactionStrategy.java | 20 +- .../CleanupFirstGarbageCollectionStrategy.java | 33 ++- .../oak/segment/file/CleanupStrategy.java | 3 +- .../oak/segment/file/CompactionResult.java | 8 + .../oak/segment/file/DefaultCleanupContext.java | 7 +- .../oak/segment/file/DefaultCleanupStrategy.java | 15 +- .../file/DefaultGarbageCollectionStrategy.java | 303 +-------------------- .../jackrabbit/oak/segment/file/GCJournal.java | 22 +- .../oak/segment/file/GarbageCollector.java | 6 +- .../SynchronizedGarbageCollectionStrategy.java | 38 ++- .../jackrabbit/oak/segment/file/tar/TarReader.java | 4 +- .../file/DefaultGarbageCollectionStrategyTest.java | 65 ++--- .../file/FullSizeDeltaEstimationStrategyTest.java | 42 ++- .../jackrabbit/oak/segment/file/GcJournalTest.java | 35 +-- .../file/TailSizeDeltaEstimationStrategyTest.java | 14 +- 17 files changed, 195 insertions(+), 482 deletions(-) diff --git a/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/tool/AzureCompact.java b/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/tool/AzureCompact.java index 0c081e1742..d150be0936 100644 --- a/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/tool/AzureCompact.java +++ b/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/tool/AzureCompact.java @@ -33,7 +33,6 @@ import com.microsoft.azure.storage.blob.CloudBlobContainer; import com.microsoft.azure.storage.blob.CloudBlobDirectory; import com.microsoft.azure.storage.blob.ListBlobItem; -import org.apache.jackrabbit.oak.segment.RecordId; import org.apache.jackrabbit.oak.segment.SegmentCache; import org.apache.jackrabbit.oak.segment.azure.v8.AzurePersistenceV8; import org.apache.jackrabbit.oak.segment.azure.v8.AzureStorageCredentialManagerV8; @@ -369,8 +368,8 @@ public class AzureCompact { targetContainer = destinationCloudBlobDirectory.getContainer(); } - GCGeneration gcGeneration; - RecordId root; + GCGeneration gcGeneration = null; + String root = null; try (FileStore store =newFileStore(splitPersistence, Files.createTempDirectory(getClass().getSimpleName() + "-").toFile(), @@ -403,7 +402,7 @@ public class AzureCompact { System.out.printf(" -> [skipping] cleaning up\n"); gcGeneration = store.getHead().getGcGeneration(); - root = store.getHead().getRecordId(); + root = store.getHead().getRecordId().toString10(); } catch (Exception e) { watch.stop(); e.printStackTrace(System.err); @@ -430,7 +429,7 @@ public class AzureCompact { return 0; } - private void persistGCJournal(SegmentNodeStorePersistence rwPersistence, long newSize, GCGeneration gcGeneration, RecordId root) throws IOException { + private void persistGCJournal(SegmentNodeStorePersistence rwPersistence, long newSize, GCGeneration gcGeneration, String root) throws IOException { GCJournalFile gcJournalFile = rwPersistence.getGCJournalFile(); if (gcJournalFile != null) { GCJournal gcJournal = new GCJournal(gcJournalFile); diff --git a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultGarbageCollectionStrategy.java b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/AbstractGarbageCollectionStrategy.java similarity index 88% copy from oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultGarbageCollectionStrategy.java copy to oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/AbstractGarbageCollectionStrategy.java index aa0b6d946f..df8da28c5f 100644 --- a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultGarbageCollectionStrategy.java +++ b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/AbstractGarbageCollectionStrategy.java @@ -26,7 +26,6 @@ import java.util.List; import java.util.function.Predicate; import java.util.function.Supplier; -import org.apache.jackrabbit.oak.segment.RecordId; import org.apache.jackrabbit.oak.segment.Revisions; import org.apache.jackrabbit.oak.segment.SegmentCache; import org.apache.jackrabbit.oak.segment.SegmentReader; @@ -38,27 +37,17 @@ 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; -class DefaultGarbageCollectionStrategy implements GarbageCollectionStrategy { +abstract class AbstractGarbageCollectionStrategy implements GarbageCollectionStrategy { - EstimationStrategy getFullEstimationStrategy() { - return new FullSizeDeltaEstimationStrategy(); - } + abstract EstimationStrategy getFullEstimationStrategy(); - EstimationStrategy getTailEstimationStrategy() { - return new TailSizeDeltaEstimationStrategy(); - } + abstract EstimationStrategy getTailEstimationStrategy(); - CompactionStrategy getFullCompactionStrategy(Context context) { - return new FullCompactionStrategy(); - } + abstract CompactionStrategy getFullCompactionStrategy(); - CompactionStrategy getTailCompactionStrategy(Context context) { - return new FallbackCompactionStrategy(new TailCompactionStrategy(), new FullCompactionStrategy()); - } + abstract CompactionStrategy getTailCompactionStrategy(); - CleanupStrategy getCleanupStrategy() { - return new DefaultCleanupStrategy(); - } + abstract CleanupStrategy getCleanupStrategy(); @Override public void collectGarbage(Context context) throws IOException { @@ -76,40 +65,36 @@ class DefaultGarbageCollectionStrategy implements GarbageCollectionStrategy { @Override public void collectFullGarbage(Context context) throws IOException { - run(context, getFullEstimationStrategy(), getFullCompactionStrategy(context)); + run(context, getFullEstimationStrategy(), getFullCompactionStrategy()); } @Override public void collectTailGarbage(Context context) throws IOException { - run(context, getTailEstimationStrategy(), getTailCompactionStrategy(context)); + run(context, getTailEstimationStrategy(), getTailCompactionStrategy()); } @Override public CompactionResult compactFull(Context context) throws IOException { - return getFullCompactionStrategy(context).compact(newCompactionStrategyContext(context)); + return getFullCompactionStrategy().compact(newCompactionStrategyContext(context)); } @Override public CompactionResult compactTail(Context context) throws IOException { - return getTailCompactionStrategy(context).compact(newCompactionStrategyContext(context)); + return getTailCompactionStrategy().compact(newCompactionStrategyContext(context)); } @Override public List<String> cleanup(Context context) throws IOException { return cleanup(context, CompactionResult.skipped( context.getLastCompactionType(), - context.getRevisions().getHead().getSegmentId().getGcGeneration(), + getGcGeneration(context), context.getGCOptions(), context.getRevisions().getHead(), context.getGCCount() )); } - public List<String> cleanup(Context context, CompactionResult compactionResult) throws IOException { - return getCleanupStrategy().cleanup(newCleanupStrategyContext(context, compactionResult)); - } - - private void run(Context context, EstimationStrategy estimationStrategy, CompactionStrategy compactionStrategy) throws IOException { + void run(Context context, EstimationStrategy estimationStrategy, CompactionStrategy compactionStrategy) throws IOException { try { context.getGCListener().info("started"); @@ -163,6 +148,14 @@ class DefaultGarbageCollectionStrategy implements GarbageCollectionStrategy { } } + private GCGeneration getGcGeneration(Context context) { + return context.getRevisions().getHead().getSegmentId().getGcGeneration(); + } + + public List<String> cleanup(Context context, CompactionResult compactionResult) throws IOException { + return getCleanupStrategy().cleanup(newCleanupStrategyContext(context, compactionResult)); + } + private EstimationStrategy.Context newEstimationStrategyContext(Context context) { return new EstimationStrategy.Context() { @@ -300,7 +293,7 @@ class DefaultGarbageCollectionStrategy implements GarbageCollectionStrategy { @Override public GCJournal getGCJournal() { - return context.getGCJournal(); + return compactionResult.requiresGCJournalEntry() ? context.getGCJournal() : null; } @Override @@ -319,8 +312,8 @@ class DefaultGarbageCollectionStrategy implements GarbageCollectionStrategy { } @Override - public RecordId getCompactedRootId() { - return compactionResult.getCompactedRootId(); + public String getCompactedRootId() { + return compactionResult.getCompactedRootId().toString10(); } @Override diff --git a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/CleanupFirstCompactionStrategy.java b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/CleanupFirstCompactionStrategy.java index cd058b4399..f06655015c 100644 --- a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/CleanupFirstCompactionStrategy.java +++ b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/CleanupFirstCompactionStrategy.java @@ -24,8 +24,6 @@ import static org.apache.jackrabbit.oak.segment.file.PrintableBytes.newPrintable import java.io.IOException; import java.util.List; -import org.apache.jackrabbit.oak.segment.RecordId; -import org.apache.jackrabbit.oak.segment.SegmentTracker; 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; @@ -104,23 +102,11 @@ class CleanupFirstCompactionStrategy implements CompactionStrategy { private static CleanupContext newCleanupContext(Context context) { GCGeneration currentGeneration = context.getRevisions().getHead().getSegmentId().getGcGeneration(); - SegmentTracker segmentTracker = context.getSegmentTracker(); - - RecordId compactedRoot; - GCJournal.GCJournalEntry lastGCJournalEntry = context.getGCJournal().read(); - if (lastGCJournalEntry.getGcGeneration().compareWith(currentGeneration) == 0) { - // if the generation doesn't match, there must be a missing entry in the GC journal - // this may still fail to detect a missing entry if partial compaction is used as - // the generation is not updated until the full repository is compacted - compactedRoot = RecordId.fromString(segmentTracker, lastGCJournalEntry.getRoot()); - } else { - context.getGCListener().warn("gc journal entry does not match generation of repository head, skipping root-based reclamation"); - compactedRoot = RecordId.NULL; - } + String compactedRoot = context.getGCJournal().read().getRoot(); switch (context.getGCOptions().getGCType()) { case FULL: - return new DefaultCleanupContext(segmentTracker, generation -> { + return new DefaultCleanupContext(context.getSegmentTracker(), generation -> { if (generation == null) { return false; } @@ -130,7 +116,7 @@ class CleanupFirstCompactionStrategy implements CompactionStrategy { return generation.getGeneration() < currentGeneration.getGeneration() && !generation.isCompacted(); }, compactedRoot); case TAIL: - return new DefaultCleanupContext(segmentTracker, generation -> { + return new DefaultCleanupContext(context.getSegmentTracker(), generation -> { if (generation == null) { return false; } diff --git a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/CleanupFirstGarbageCollectionStrategy.java b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/CleanupFirstGarbageCollectionStrategy.java index 5820c989b9..ff83c7b8db 100644 --- a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/CleanupFirstGarbageCollectionStrategy.java +++ b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/CleanupFirstGarbageCollectionStrategy.java @@ -19,17 +19,38 @@ package org.apache.jackrabbit.oak.segment.file; +import java.io.IOException; -class CleanupFirstGarbageCollectionStrategy extends DefaultGarbageCollectionStrategy { +class CleanupFirstGarbageCollectionStrategy extends AbstractGarbageCollectionStrategy { - @Override - CompactionStrategy getFullCompactionStrategy(Context context) { - return new CleanupFirstCompactionStrategy(context, super.getFullCompactionStrategy(context)); + @Override + EstimationStrategy getFullEstimationStrategy() { + return new FullSizeDeltaEstimationStrategy(); + } + + @Override + EstimationStrategy getTailEstimationStrategy() { + return new TailSizeDeltaEstimationStrategy(); + } + + @Override + CompactionStrategy getFullCompactionStrategy() { + return new FullCompactionStrategy(); + } + + @Override + CompactionStrategy getTailCompactionStrategy() { + return new FallbackCompactionStrategy(new TailCompactionStrategy(), new FullCompactionStrategy()); + } + + @Override + CleanupStrategy getCleanupStrategy() { + return new DefaultCleanupStrategy(); } @Override - CompactionStrategy getTailCompactionStrategy(Context context) { - return new CleanupFirstCompactionStrategy(context, super.getTailCompactionStrategy(context)); + void run(Context context, EstimationStrategy estimationStrategy, CompactionStrategy compactionStrategy) throws IOException { + super.run(context, estimationStrategy, new CleanupFirstCompactionStrategy(context, compactionStrategy)); } } diff --git a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/CleanupStrategy.java b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/CleanupStrategy.java index b4cf622d9e..149075ba3b 100644 --- a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/CleanupStrategy.java +++ b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/CleanupStrategy.java @@ -22,7 +22,6 @@ import java.io.IOException; import java.util.List; import java.util.function.Predicate; -import org.apache.jackrabbit.oak.segment.RecordId; import org.apache.jackrabbit.oak.segment.Revisions; import org.apache.jackrabbit.oak.segment.SegmentCache; import org.apache.jackrabbit.oak.segment.SegmentTracker; @@ -51,7 +50,7 @@ interface CleanupStrategy { Revisions getRevisions(); - RecordId getCompactedRootId(); + String getCompactedRootId(); String getSegmentEvictionReason(); diff --git a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/CompactionResult.java b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/CompactionResult.java index 0dee9588aa..78bf29f896 100644 --- a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/CompactionResult.java +++ b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/CompactionResult.java @@ -75,6 +75,10 @@ abstract class CompactionResult { return compactedRootId; } + @Override + boolean requiresGCJournalEntry() { + return true; + } }; } @@ -209,6 +213,10 @@ abstract class CompactionResult { return false; } + boolean requiresGCJournalEntry() { + return false; + } + /** * @return a diagnostic message describing the outcome of this compaction. */ diff --git a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultCleanupContext.java b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultCleanupContext.java index d12e50c55a..388247d903 100644 --- a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultCleanupContext.java +++ b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultCleanupContext.java @@ -40,15 +40,16 @@ class DefaultCleanupContext implements CleanupContext { private final @Nullable UUID rootSegmentUUID; private boolean aheadOfRoot; - DefaultCleanupContext(@NotNull SegmentTracker tracker, @NotNull Predicate<GCGeneration> old, @NotNull RecordId compactedRoot) { + DefaultCleanupContext(@NotNull SegmentTracker tracker, @NotNull Predicate<GCGeneration> old, @NotNull String compactedRoot) { this.segmentTracker = tracker; this.old = old; - if (compactedRoot.equals(RecordId.NULL)) { + RecordId rootId = RecordId.fromString(tracker, compactedRoot); + if (rootId.equals(RecordId.NULL)) { rootSegmentUUID = null; aheadOfRoot = false; } else { - rootSegmentUUID = compactedRoot.getSegmentId().asUUID(); + rootSegmentUUID = rootId.getSegmentId().asUUID(); aheadOfRoot = true; } } diff --git a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultCleanupStrategy.java b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultCleanupStrategy.java index 7c71559ec5..3aa8b178db 100644 --- a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultCleanupStrategy.java +++ b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultCleanupStrategy.java @@ -51,7 +51,7 @@ class DefaultCleanupStrategy implements CleanupStrategy { context.getSegmentTracker().clearSegmentIdTables(cleanupResult.getReclaimedSegmentIds(), context.getSegmentEvictionReason()); context.getGCListener().info("cleanup marking files for deletion: {}", toFileNames(cleanupResult.getRemovableFiles())); - long finalSize = context.getTarFiles().size(); + long finalSize = size(context); long reclaimedSize = cleanupResult.getReclaimedSize(); context.getFileStoreStats().reclaimed(reclaimedSize); @@ -64,8 +64,6 @@ class DefaultCleanupStrategy implements CleanupStrategy { context.getCompactionMonitor().getCompactedNodes(), context.getCompactedRootId() ); - } else { - context.getGCListener().warn("gc journal not available, unable to persist new entry."); } context.getGCListener().cleaned(reclaimedSize, finalSize); context.getGCListener().info( @@ -78,11 +76,8 @@ class DefaultCleanupStrategy implements CleanupStrategy { } private static CleanupContext newCleanupContext(Context context) { - return new DefaultCleanupContext( - context.getSegmentTracker(), - context.getReclaimer(), - context.getCompactedRootId() - ); + return new DefaultCleanupContext(context.getSegmentTracker(), context.getReclaimer(), + context.getCompactedRootId()); } private static String toFileNames(@NotNull List<String> files) { @@ -97,4 +92,8 @@ class DefaultCleanupStrategy implements CleanupStrategy { return context.getRevisions().getHead().getSegmentId().getGcGeneration(); } + private static long size(Context context) { + return context.getTarFiles().size(); + } + } diff --git a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultGarbageCollectionStrategy.java b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultGarbageCollectionStrategy.java index aa0b6d946f..ccf058f0d4 100644 --- a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultGarbageCollectionStrategy.java +++ b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/DefaultGarbageCollectionStrategy.java @@ -16,319 +16,34 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.jackrabbit.oak.segment.file; - -import static org.apache.jackrabbit.oak.segment.compaction.SegmentGCStatus.ESTIMATION; -import static org.apache.jackrabbit.oak.segment.compaction.SegmentGCStatus.IDLE; - -import java.io.IOException; -import java.util.List; -import java.util.function.Predicate; -import java.util.function.Supplier; -import org.apache.jackrabbit.oak.segment.RecordId; -import org.apache.jackrabbit.oak.segment.Revisions; -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.SegmentWriterFactory; -import org.apache.jackrabbit.oak.segment.compaction.SegmentGCOptions; -import org.apache.jackrabbit.oak.segment.file.cancel.Canceller; -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; +package org.apache.jackrabbit.oak.segment.file; -class DefaultGarbageCollectionStrategy implements GarbageCollectionStrategy { +class DefaultGarbageCollectionStrategy extends AbstractGarbageCollectionStrategy { + @Override EstimationStrategy getFullEstimationStrategy() { return new FullSizeDeltaEstimationStrategy(); } + @Override EstimationStrategy getTailEstimationStrategy() { return new TailSizeDeltaEstimationStrategy(); } - CompactionStrategy getFullCompactionStrategy(Context context) { + @Override + CompactionStrategy getFullCompactionStrategy() { return new FullCompactionStrategy(); } - CompactionStrategy getTailCompactionStrategy(Context context) { + @Override + CompactionStrategy getTailCompactionStrategy() { return new FallbackCompactionStrategy(new TailCompactionStrategy(), new FullCompactionStrategy()); } + @Override CleanupStrategy getCleanupStrategy() { return new DefaultCleanupStrategy(); } - @Override - public void collectGarbage(Context context) throws IOException { - switch (context.getGCOptions().getGCType()) { - case FULL: - collectFullGarbage(context); - break; - case TAIL: - collectTailGarbage(context); - break; - default: - throw new IllegalStateException("Invalid GC type"); - } - } - - @Override - public void collectFullGarbage(Context context) throws IOException { - run(context, getFullEstimationStrategy(), getFullCompactionStrategy(context)); - } - - @Override - public void collectTailGarbage(Context context) throws IOException { - run(context, getTailEstimationStrategy(), getTailCompactionStrategy(context)); - } - - @Override - public CompactionResult compactFull(Context context) throws IOException { - return getFullCompactionStrategy(context).compact(newCompactionStrategyContext(context)); - } - - @Override - public CompactionResult compactTail(Context context) throws IOException { - return getTailCompactionStrategy(context).compact(newCompactionStrategyContext(context)); - } - - @Override - public List<String> cleanup(Context context) throws IOException { - return cleanup(context, CompactionResult.skipped( - context.getLastCompactionType(), - context.getRevisions().getHead().getSegmentId().getGcGeneration(), - context.getGCOptions(), - context.getRevisions().getHead(), - context.getGCCount() - )); - } - - public List<String> cleanup(Context context, CompactionResult compactionResult) throws IOException { - return getCleanupStrategy().cleanup(newCleanupStrategyContext(context, compactionResult)); - } - - private void run(Context context, EstimationStrategy estimationStrategy, CompactionStrategy compactionStrategy) throws IOException { - try { - context.getGCListener().info("started"); - - long dt = System.currentTimeMillis() - context.getLastSuccessfulGC(); - - if (dt < context.getGCBackOff()) { - context.getGCListener().skipped("skipping garbage collection as it already ran less than {} hours ago ({} s).", context.getGCBackOff() / 3600000, dt / 1000); - return; - } - - boolean sufficientEstimatedGain = true; - if (context.getGCOptions().isEstimationDisabled()) { - context.getGCListener().info("estimation skipped because it was explicitly disabled"); - } else if (context.getGCOptions().isPaused()) { - context.getGCListener().info("estimation skipped because compaction is paused"); - } else { - context.getGCListener().info("estimation started"); - context.getGCListener().updateStatus(ESTIMATION.message()); - - PrintableStopwatch watch = PrintableStopwatch.createStarted(); - EstimationResult estimation = estimationStrategy.estimate(newEstimationStrategyContext(context)); - sufficientEstimatedGain = estimation.isGcNeeded(); - String gcLog = estimation.getGcLog(); - if (sufficientEstimatedGain) { - context.getGCListener().info("estimation completed in {}. {}", watch, gcLog); - } else { - context.getGCListener().skipped("estimation completed in {}. {}", watch, gcLog); - } - } - - if (sufficientEstimatedGain) { - try (GCMemoryBarrier ignored = new GCMemoryBarrier(context.getSufficientMemory(), context.getGCListener(), context.getGCOptions())) { - if (context.getGCOptions().isPaused()) { - context.getGCListener().skipped("compaction paused"); - } else if (!context.getSufficientMemory().get()) { - context.getGCListener().skipped("compaction skipped. Not enough memory"); - } else { - CompactionResult compactionResult = compactionStrategy.compact(newCompactionStrategyContext(context)); - if (compactionResult.isSuccess()) { - context.getSuccessfulGarbageCollectionListener().onSuccessfulGarbageCollection(); - } else { - context.getGCListener().info("cleaning up after failed compaction"); - } - context.getFileReaper().add(cleanup(context, compactionResult)); - } - } - } - } finally { - context.getCompactionMonitor().finished(); - context.getGCListener().updateStatus(IDLE.message()); - } - } - - private EstimationStrategy.Context newEstimationStrategyContext(Context context) { - return new EstimationStrategy.Context() { - - @Override - public long getSizeDelta() { - return context.getGCOptions().getGcSizeDeltaEstimation(); - } - - @Override - public long getCurrentSize() { - return context.getTarFiles().size(); - } - - @Override - public GCJournal getGCJournal() { - return context.getGCJournal(); - } - - }; - } - - private static CompactionStrategy.Context newCompactionStrategyContext(Context context) { - return new CompactionStrategy.Context() { - - @Override - public SegmentTracker getSegmentTracker() { - return context.getSegmentTracker(); - } - - @Override - public GCListener getGCListener() { - return context.getGCListener(); - } - - @Override - public GCJournal getGCJournal() { - return context.getGCJournal(); - } - - @Override - public SegmentGCOptions getGCOptions() { - return context.getGCOptions(); - } - - @Override - public GCNodeWriteMonitor getCompactionMonitor() { - return context.getCompactionMonitor(); - } - - @Override - public SegmentReader getSegmentReader() { - return context.getSegmentReader(); - } - - @Override - public SegmentWriterFactory getSegmentWriterFactory() { - return context.getSegmentWriterFactory(); - } - - @Override - public Revisions getRevisions() { - return context.getRevisions(); - } - - @Override - public TarFiles getTarFiles() { - return context.getTarFiles(); - } - - @Override - public BlobStore getBlobStore() { - return context.getBlobStore(); - } - - @Override - public Canceller getHardCanceller() { - return context.getCanceller(); - } - - @Override - public Canceller getSoftCanceller() { - return Canceller.newCanceller(); - } - - @Override - public Supplier<Canceller> getStateSaveTriggerSupplier() { - return Canceller::newCanceller; - } - - @Override - public int getGCCount() { - return context.getGCCount(); - } - - @Override - public SuccessfulCompactionListener getSuccessfulCompactionListener() { - return context.getSuccessfulCompactionListener(); - } - - @Override - public Flusher getFlusher() { - return context.getFlusher(); - } - - }; - } - - private CleanupStrategy.Context newCleanupStrategyContext(Context context, CompactionResult compactionResult) { - return new CleanupStrategy.Context() { - - @Override - public GCListener getGCListener() { - return context.getGCListener(); - } - - @Override - public SegmentCache getSegmentCache() { - return context.getSegmentCache(); - } - - @Override - public SegmentTracker getSegmentTracker() { - return context.getSegmentTracker(); - } - - @Override - public FileStoreStats getFileStoreStats() { - return context.getFileStoreStats(); - } - - @Override - public GCNodeWriteMonitor getCompactionMonitor() { - return context.getCompactionMonitor(); - } - - @Override - public GCJournal getGCJournal() { - return context.getGCJournal(); - } - - @Override - public Predicate<GCGeneration> getReclaimer() { - return compactionResult.reclaimer(); - } - - @Override - public TarFiles getTarFiles() { - return context.getTarFiles(); - } - - @Override - public Revisions getRevisions() { - return context.getRevisions(); - } - - @Override - public RecordId getCompactedRootId() { - return compactionResult.getCompactedRootId(); - } - - @Override - public String getSegmentEvictionReason() { - return compactionResult.gcInfo(); - } - - }; - } - } diff --git a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/GCJournal.java b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/GCJournal.java index 530889f85b..5d0a520a29 100644 --- a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/GCJournal.java +++ b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/GCJournal.java @@ -18,6 +18,7 @@ */ package org.apache.jackrabbit.oak.segment.file; +import static java.util.Objects.requireNonNull; import static org.apache.jackrabbit.oak.segment.file.tar.GCGeneration.newGCGeneration; import java.io.IOException; @@ -64,15 +65,16 @@ public class GCJournal { * @param root record id of the compacted root node */ public synchronized void persist(long reclaimedSize, long repoSize, - @NotNull GCGeneration gcGeneration, long nodes, @NotNull RecordId root + @NotNull GCGeneration gcGeneration, long nodes, @NotNull String root ) { GCJournalEntry current = read(); - if (root.equals(RecordId.NULL) || root.toString10().equals(current.root)) { - // only update the journal if the root has changed + if (current.getGcGeneration().equals(gcGeneration)) { + // failed compaction, only update the journal if the generation + // increases return; } latest = new GCJournalEntry(repoSize, reclaimedSize, - System.currentTimeMillis(), gcGeneration, nodes, root.toString10()); + System.currentTimeMillis(), gcGeneration, nodes, requireNonNull(root)); try { journalFile.writeLine(latest.toString()); } catch (IOException e) { @@ -100,7 +102,7 @@ public class GCJournal { * Returns all available entries from the journal */ public synchronized Collection<GCJournalEntry> readAll() { - List<GCJournalEntry> all = new ArrayList<>(); + List<GCJournalEntry> all = new ArrayList<GCJournalEntry>(); for (String l : readLines()) { all.add(GCJournalEntry.fromString(l)); } @@ -113,7 +115,7 @@ public class GCJournal { } catch (IOException e) { LOG.error("Error reading gc journal", e); } - return new ArrayList<>(); + return new ArrayList<String>(); } public static class GCJournalEntry { @@ -265,10 +267,10 @@ public class GCJournal { int result = 1; result = prime * result + gcGeneration.hashCode(); result = prime * result + root.hashCode(); - result = prime * result + Long.hashCode(nodes); - result = prime * result + Long.hashCode(reclaimedSize); - result = prime * result + Long.hashCode(repoSize); - result = prime * result + Long.hashCode(ts); + result = prime * result + (int) (nodes ^ (nodes >>> 32)); + result = prime * result + (int) (reclaimedSize ^ (reclaimedSize >>> 32)); + result = prime * result + (int) (repoSize ^ (repoSize >>> 32)); + result = prime * result + (int) (ts ^ (ts >>> 32)); return result; } diff --git a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/GarbageCollector.java b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/GarbageCollector.java index 025ffaf2a3..1b278a7894 100644 --- a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/GarbageCollector.java +++ b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/GarbageCollector.java @@ -102,7 +102,7 @@ class GarbageCollector { * Timestamp of the last time full or tail compaction was successfully * invoked. 0 if never. */ - private long lastSuccessfulGC; + private long lastSuccessfullGC; /** * Last compaction type used to determine which predicate to use during @@ -209,7 +209,7 @@ class GarbageCollector { @Override public long getLastSuccessfulGC() { - return lastSuccessfulGC; + return lastSuccessfullGC; } @Override @@ -229,7 +229,7 @@ class GarbageCollector { @Override public SuccessfulGarbageCollectionListener getSuccessfulGarbageCollectionListener() { - return () -> lastSuccessfulGC = System.currentTimeMillis(); + return () -> lastSuccessfullGC = System.currentTimeMillis(); } @Override diff --git a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/SynchronizedGarbageCollectionStrategy.java b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/SynchronizedGarbageCollectionStrategy.java index 6129da02c6..f301b40c04 100644 --- a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/SynchronizedGarbageCollectionStrategy.java +++ b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/SynchronizedGarbageCollectionStrategy.java @@ -24,6 +24,8 @@ import java.util.List; class SynchronizedGarbageCollectionStrategy implements GarbageCollectionStrategy { + private final Object lock = new Object(); + private final GarbageCollectionStrategy strategy; SynchronizedGarbageCollectionStrategy(GarbageCollectionStrategy strategy) { @@ -31,33 +33,45 @@ class SynchronizedGarbageCollectionStrategy implements GarbageCollectionStrategy } @Override - public synchronized void collectGarbage(Context context) throws IOException { - strategy.collectGarbage(context); + public void collectGarbage(Context context) throws IOException { + synchronized (lock) { + strategy.collectGarbage(context); + } } @Override - public synchronized void collectFullGarbage(Context context) throws IOException { - strategy.collectFullGarbage(context); + public void collectFullGarbage(Context context) throws IOException { + synchronized (lock) { + strategy.collectFullGarbage(context); + } } @Override - public synchronized void collectTailGarbage(Context context) throws IOException { - strategy.collectTailGarbage(context); + public void collectTailGarbage(Context context) throws IOException { + synchronized (lock) { + strategy.collectTailGarbage(context); + } } @Override - public synchronized CompactionResult compactFull(Context context) throws IOException { - return strategy.compactFull(context); + public CompactionResult compactFull(Context context) throws IOException { + synchronized (lock) { + return strategy.compactFull(context); + } } @Override - public synchronized CompactionResult compactTail(Context context) throws IOException { - return strategy.compactTail(context); + public CompactionResult compactTail(Context context) throws IOException { + synchronized (lock) { + return strategy.compactTail(context); + } } @Override - public synchronized List<String> cleanup(Context context) throws IOException { - return strategy.cleanup(context); + public List<String> cleanup(Context context) throws IOException { + synchronized (lock) { + return strategy.cleanup(context); + } } } diff --git a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tar/TarReader.java b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tar/TarReader.java index 2428956b7e..c1cd30e4cd 100644 --- a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tar/TarReader.java +++ b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tar/TarReader.java @@ -429,9 +429,9 @@ public class TarReader implements Closeable { Map<UUID, List<UUID>> graph = getGraph(); SegmentArchiveEntry[] entries = getEntries(); for (int i = entries.length - 1; i >= 0; i--) { - // A bulk segment is *always* written before any data segment referencing it. + // A bulk segments is *always* written before any data segment referencing it. // Backward iteration ensures we see all references to bulk segments before - // we see the bulk segment itself. Therefore, we can remove a bulk reference + // we see the bulk segment itself. Therefore we can remove a bulk reference // from the bulkRefs set once we encounter it, which save us some memory and // CPU on subsequent look-ups. SegmentArchiveEntry entry = entries[i]; diff --git a/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/DefaultGarbageCollectionStrategyTest.java b/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/DefaultGarbageCollectionStrategyTest.java index d543d5641b..953271cde8 100644 --- a/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/DefaultGarbageCollectionStrategyTest.java +++ b/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/DefaultGarbageCollectionStrategyTest.java @@ -26,15 +26,14 @@ 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; import org.apache.jackrabbit.oak.segment.memory.MemoryStore; -import org.apache.jackrabbit.oak.segment.spi.persistence.GCJournalFile; import org.junit.Test; import org.mockito.Mockito; import org.mockito.verification.VerificationMode; -import java.io.File; import java.io.IOException; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -43,11 +42,10 @@ import static org.mockito.Mockito.when; public class DefaultGarbageCollectionStrategyTest { private final GCJournal journal; - private final GCJournalFile journalFile; - public DefaultGarbageCollectionStrategyTest() throws IOException { - journalFile = Mockito.spy(new LocalGCJournalFile(File.createTempFile("gctest", "log"))); - journal = new GCJournal(journalFile); + public DefaultGarbageCollectionStrategyTest() { + journal = Mockito.mock(GCJournal.class); + when(journal.read()).thenReturn(Mockito.mock(GCJournal.GCJournalEntry.class)); } private GarbageCollectionStrategy.Context getMockedGCContext(MemoryStore store) throws IOException { @@ -78,8 +76,13 @@ public class DefaultGarbageCollectionStrategyTest { strategy.cleanup(getMockedGCContext(store), result); } - private void verifyGCJournalPersistence(VerificationMode mode) throws IOException { - verify(journalFile, mode).writeLine(anyString()); + private void verifyGCJournalPersistence(VerificationMode mode) { + verify(journal, mode).persist( + anyLong(), + anyLong(), + any(GCGeneration.class), + anyLong(), + anyString()); } @Test @@ -88,47 +91,29 @@ public class DefaultGarbageCollectionStrategyTest { SegmentGCOptions.GCType.FULL, GCGeneration.NULL, SegmentGCOptions.defaultGCOptions(), - new RecordId(SegmentId.NULL, 1), - 0 - ); + RecordId.NULL, + 0); runCleanup(result); verifyGCJournalPersistence(times(1)); } @Test - public void partialCompactionPersistsToJournal() throws Exception { - CompactionResult result = CompactionResult.partiallySucceeded( - GCGeneration.NULL, - new RecordId(SegmentId.NULL, 1), - 0 - ); + public void partialCompactionDoesNotPersistToJournal() throws Exception { + CompactionResult result = CompactionResult.partiallySucceeded(GCGeneration.NULL, RecordId.NULL, 0); runCleanup(result); - verifyGCJournalPersistence(times(1)); + verifyGCJournalPersistence(never()); } @Test - public void skippedCompactionMayPersistToJournal() throws Exception { - SegmentGCOptions.GCType gcType = SegmentGCOptions.GCType.FULL; - GCGeneration gcGeneration = GCGeneration.NULL; - SegmentGCOptions gcOptions = SegmentGCOptions.defaultGCOptions(); - RecordId rootOne = new RecordId(SegmentId.NULL, 1); - RecordId rootTwo = new RecordId(SegmentId.NULL, 2); - - // persist when there is no previous entry - runCleanup(CompactionResult.skipped(gcType, gcGeneration, gcOptions, rootOne, 0)); - verifyGCJournalPersistence(times(1)); - - // don't persist when root is identical - runCleanup(CompactionResult.skipped(gcType, gcGeneration, gcOptions, rootOne, 0)); - verifyGCJournalPersistence(times(1)); - - // persist when there is a new root - runCleanup(CompactionResult.skipped(gcType, gcGeneration, gcOptions, rootTwo, 0)); - verifyGCJournalPersistence(times(2)); - - // don't persist when the root is null - runCleanup(CompactionResult.skipped(gcType, gcGeneration, gcOptions, RecordId.NULL, 0)); - verifyGCJournalPersistence(times(2)); + public void skippedCompactionDoesNotPersistToJournal() throws Exception { + CompactionResult result = CompactionResult.skipped( + SegmentGCOptions.GCType.FULL, + GCGeneration.NULL, + SegmentGCOptions.defaultGCOptions(), + RecordId.NULL, + 0); + runCleanup(result); + verifyGCJournalPersistence(never()); } @Test diff --git a/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/FullSizeDeltaEstimationStrategyTest.java b/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/FullSizeDeltaEstimationStrategyTest.java index 94885721f5..621d220b25 100644 --- a/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/FullSizeDeltaEstimationStrategyTest.java +++ b/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/FullSizeDeltaEstimationStrategyTest.java @@ -25,8 +25,6 @@ import static org.junit.Assert.assertTrue; import java.io.File; -import org.apache.jackrabbit.oak.segment.RecordId; -import org.apache.jackrabbit.oak.segment.SegmentId; import org.apache.jackrabbit.oak.segment.file.EstimationStrategy.Context; import org.apache.jackrabbit.oak.segment.file.tar.TarPersistence; import org.junit.Before; @@ -58,46 +56,46 @@ public class FullSizeDeltaEstimationStrategyTest { @Test public void testFullGCNeededBecauseOfSize1() { - journal.persist(100, 1000, newGCGeneration(1, 1, true), 1000, new RecordId(SegmentId.NULL, 1)); - journal.persist(110, 1100, newGCGeneration(2, 2, true), 1000, new RecordId(SegmentId.NULL, 2)); - journal.persist(120, 1200, newGCGeneration(3, 3, true), 1000, new RecordId(SegmentId.NULL, 3)); - journal.persist(130, 1000, newGCGeneration(4, 4, true), 1000, new RecordId(SegmentId.NULL, 4)); - journal.persist(100, 1010, newGCGeneration(5, 5, true), 1000, new RecordId(SegmentId.NULL, 5)); - journal.persist(110, 1020, newGCGeneration(6, 6, true), 1000, new RecordId(SegmentId.NULL, 6)); + journal.persist(100, 1000, newGCGeneration(1, 1, true), 1000, "id"); + journal.persist(110, 1100, newGCGeneration(2, 2, true), 1000, "id"); + journal.persist(120, 1200, newGCGeneration(3, 3, true), 1000, "id"); + journal.persist(130, 1000, newGCGeneration(4, 4, true), 1000, "id"); + journal.persist(100, 1010, newGCGeneration(5, 5, true), 1000, "id"); + journal.persist(110, 1020, newGCGeneration(6, 6, true), 1000, "id"); assertTrue(isGarbageCollectionNeeded(100, 1300)); } @Test public void testFullGCNeededBecauseOfSize2() { - journal.persist(100, 1000, newGCGeneration(1, 1, true), 1000, new RecordId(SegmentId.NULL, 1)); + journal.persist(100, 1000, newGCGeneration(1, 1, true), 1000, "id"); assertTrue(isGarbageCollectionNeeded(10, 1030)); } @Test public void testFullGCSkippedBecauseOfSize1() { - journal.persist(100, 1000, newGCGeneration(1, 1, true), 1000, new RecordId(SegmentId.NULL, 1)); - journal.persist(110, 1100, newGCGeneration(2, 2, true), 1000, new RecordId(SegmentId.NULL, 2)); - journal.persist(120, 1200, newGCGeneration(3, 3, true), 1000, new RecordId(SegmentId.NULL, 3)); - journal.persist(130, 1000, newGCGeneration(4, 4, true), 1000, new RecordId(SegmentId.NULL, 4)); - journal.persist(100, 1010, newGCGeneration(5, 5, true), 1000, new RecordId(SegmentId.NULL, 5)); - journal.persist(110, 1020, newGCGeneration(6, 6, true), 1000, new RecordId(SegmentId.NULL, 6)); + journal.persist(100, 1000, newGCGeneration(1, 1, true), 1000, "id"); + journal.persist(110, 1100, newGCGeneration(2, 2, true), 1000, "id"); + journal.persist(120, 1200, newGCGeneration(3, 3, true), 1000, "id"); + journal.persist(130, 1000, newGCGeneration(4, 4, true), 1000, "id"); + journal.persist(100, 1010, newGCGeneration(5, 5, true), 1000, "id"); + journal.persist(110, 1020, newGCGeneration(6, 6, true), 1000, "id"); assertFalse(isGarbageCollectionNeeded(100, 1030)); } @Test public void testFullGCSkippedBecauseOfSize2() { - journal.persist(100, 1000, newGCGeneration(1, 1, true), 1000, new RecordId(SegmentId.NULL, 1)); + journal.persist(100, 1000, newGCGeneration(1, 1, true), 1000, "id"); assertFalse(isGarbageCollectionNeeded(100, 1030)); } @Test public void testFullGCNeededBecauseOfPreviousTail() { - journal.persist(100, 1000, newGCGeneration(1, 1, true), 1000, new RecordId(SegmentId.NULL, 1)); - journal.persist(110, 1100, newGCGeneration(2, 1, true), 1000, new RecordId(SegmentId.NULL, 2)); - journal.persist(120, 1200, newGCGeneration(3, 1, true), 1000, new RecordId(SegmentId.NULL, 3)); - journal.persist(130, 1000, newGCGeneration(4, 2, true), 1000, new RecordId(SegmentId.NULL, 4)); - journal.persist(100, 1010, newGCGeneration(5, 2, true), 1000, new RecordId(SegmentId.NULL, 5)); - journal.persist(110, 1020, newGCGeneration(6, 2, true), 1000, new RecordId(SegmentId.NULL, 6)); + journal.persist(100, 1000, newGCGeneration(1, 1, true), 1000, "id"); + journal.persist(110, 1100, newGCGeneration(2, 1, true), 1000, "id"); + journal.persist(120, 1200, newGCGeneration(3, 1, true), 1000, "id"); + journal.persist(130, 1000, newGCGeneration(4, 2, true), 1000, "id"); + journal.persist(100, 1010, newGCGeneration(5, 2, true), 1000, "id"); + journal.persist(110, 1020, newGCGeneration(6, 2, true), 1000, "id"); assertTrue(isGarbageCollectionNeeded(100, 1030)); } diff --git a/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/GcJournalTest.java b/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/GcJournalTest.java index 17c3c6dc60..58163a008b 100644 --- a/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/GcJournalTest.java +++ b/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/GcJournalTest.java @@ -31,7 +31,6 @@ import java.util.List; import org.apache.jackrabbit.oak.commons.IOUtils; import org.apache.jackrabbit.oak.segment.RecordId; -import org.apache.jackrabbit.oak.segment.SegmentId; import org.apache.jackrabbit.oak.segment.spi.persistence.GCJournalFile; import org.apache.jackrabbit.oak.segment.spi.persistence.SegmentNodeStorePersistence; import org.apache.jackrabbit.oak.segment.file.GCJournal.GCJournalEntry; @@ -53,50 +52,47 @@ public class GcJournalTest { public void tarGcJournal() throws Exception { GCJournal gc = new GCJournal(getPersistence().getGCJournalFile()); - RecordId root = new RecordId(SegmentId.NULL, 1); - gc.persist(0, 100, newGCGeneration(1, 0, false), 50, root); + gc.persist(0, 100, newGCGeneration(1, 0, false), 50, RecordId.NULL.toString10()); GCJournalEntry e0 = gc.read(); assertEquals(100, e0.getRepoSize()); assertEquals(0, e0.getReclaimedSize()); assertEquals(50, e0.getNodes()); - assertEquals(root.toString10(), e0.getRoot()); + assertEquals(RecordId.NULL.toString10(), e0.getRoot()); - root = new RecordId(SegmentId.NULL, 2); - gc.persist(0, 250, newGCGeneration(2, 0, false), 75, root); + gc.persist(0, 250, newGCGeneration(2, 0, false), 75, RecordId.NULL.toString()); GCJournalEntry e1 = gc.read(); assertEquals(250, e1.getRepoSize()); assertEquals(0, e1.getReclaimedSize()); assertEquals(75, e1.getNodes()); - assertEquals(root.toString10(), e1.getRoot()); + assertEquals(RecordId.NULL.toString(), e1.getRoot()); - root = new RecordId(SegmentId.NULL, 3); - gc.persist(50, 200, newGCGeneration(3, 0, false), 90, root); + gc.persist(50, 200, newGCGeneration(3, 0, false), 90, "foo"); GCJournalEntry e2 = gc.read(); assertEquals(200, e2.getRepoSize()); assertEquals(50, e2.getReclaimedSize()); assertEquals(90, e2.getNodes()); - assertEquals(root.toString10(), e2.getRoot()); + assertEquals("foo", e2.getRoot()); - // same root - gc.persist(75, 300, newGCGeneration(3, 0, false), 125, root); + // same gen + gc.persist(75, 300, newGCGeneration(3, 0, false), 125, "bar"); GCJournalEntry e3 = gc.read(); assertEquals(200, e3.getRepoSize()); assertEquals(50, e3.getReclaimedSize()); assertEquals(90, e3.getNodes()); - assertEquals(root.toString10(), e2.getRoot()); + assertEquals("foo", e2.getRoot()); Collection<GCJournalEntry> all = gc.readAll(); - assertEquals(3, all.size()); + assertEquals(all.size(), 3); GCJournalFile gcFile = getPersistence().getGCJournalFile(); List<String> allLines = gcFile.readLines(); - assertEquals(3, allLines.size()); + assertEquals(allLines.size(), 3); } @Test public void testGCGeneration() throws Exception { GCJournal out = new GCJournal(getPersistence().getGCJournalFile()); - out.persist(1, 100, newGCGeneration(1, 2, false), 50, new RecordId(SegmentId.NULL, 1)); + out.persist(1, 100, newGCGeneration(1, 2, false), 50, RecordId.NULL.toString()); GCJournal in = new GCJournal(getPersistence().getGCJournalFile()); assertEquals(newGCGeneration(1, 2, false), in.read().getGcGeneration()); } @@ -104,7 +100,7 @@ public class GcJournalTest { @Test public void testGCGenerationCompactedFlagCleared() throws Exception { GCJournal out = new GCJournal(getPersistence().getGCJournalFile()); - out.persist(1, 100, newGCGeneration(1, 2, true), 50, new RecordId(SegmentId.NULL, 1)); + out.persist(1, 100, newGCGeneration(1, 2, true), 50, RecordId.NULL.toString()); GCJournal in = new GCJournal(getPersistence().getGCJournalFile()); assertEquals(newGCGeneration(1, 2, false), in.read().getGcGeneration()); } @@ -126,8 +122,7 @@ public class GcJournalTest { public void testUpdateOak16GCLog() throws Exception { createOak16GCLog(); GCJournal gcJournal = new GCJournal(getPersistence().getGCJournalFile()); - RecordId root = new RecordId(SegmentId.NULL, 1); - gcJournal.persist(75, 300, newGCGeneration(3, 0, false), 125, root); + gcJournal.persist(75, 300, newGCGeneration(3, 0, false), 125, "bar"); List<GCJournalEntry> entries = new ArrayList<>(gcJournal.readAll()); assertEquals(2, entries.size()); @@ -145,7 +140,7 @@ public class GcJournalTest { assertEquals(75, entry.getReclaimedSize()); assertEquals(newGCGeneration(3, 0, false), entry.getGcGeneration()); assertEquals(125, entry.getNodes()); - assertEquals(root.toString10(), entry.getRoot()); + assertEquals("bar", entry.getRoot()); } private void createOak16GCLog() throws IOException { diff --git a/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/TailSizeDeltaEstimationStrategyTest.java b/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/TailSizeDeltaEstimationStrategyTest.java index 9e83dc5ff9..0aaf9d3f9f 100644 --- a/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/TailSizeDeltaEstimationStrategyTest.java +++ b/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/TailSizeDeltaEstimationStrategyTest.java @@ -25,8 +25,6 @@ import static org.junit.Assert.assertTrue; import java.io.File; -import org.apache.jackrabbit.oak.segment.RecordId; -import org.apache.jackrabbit.oak.segment.SegmentId; import org.apache.jackrabbit.oak.segment.file.EstimationStrategy.Context; import org.apache.jackrabbit.oak.segment.file.tar.TarPersistence; import org.junit.Before; @@ -58,17 +56,17 @@ public class TailSizeDeltaEstimationStrategyTest { @Test public void testTailGCNeeded() { - journal.persist(100, 1000, newGCGeneration(1, 1, true), 1000, new RecordId(SegmentId.NULL, 1)); - journal.persist(110, 1100, newGCGeneration(2, 1, true), 1000, new RecordId(SegmentId.NULL, 2)); - journal.persist(120, 1200, newGCGeneration(3, 1, true), 1000, new RecordId(SegmentId.NULL, 3)); + journal.persist(100, 1000, newGCGeneration(1, 1, true), 1000, "id"); + journal.persist(110, 1100, newGCGeneration(2, 1, true), 1000, "id"); + journal.persist(120, 1200, newGCGeneration(3, 1, true), 1000, "id"); assertTrue(isGarbageCollectionNeeded(50, 1300)); } @Test public void testTailGCSkipped() { - journal.persist(100, 1000, newGCGeneration(1, 1, true), 1000, new RecordId(SegmentId.NULL, 1)); - journal.persist(110, 1100, newGCGeneration(2, 1, true), 1000, new RecordId(SegmentId.NULL, 2)); - journal.persist(120, 1200, newGCGeneration(3, 1, true), 1000, new RecordId(SegmentId.NULL, 3)); + journal.persist(100, 1000, newGCGeneration(1, 1, true), 1000, "id"); + journal.persist(110, 1100, newGCGeneration(2, 1, true), 1000, "id"); + journal.persist(120, 1200, newGCGeneration(3, 1, true), 1000, "id"); assertFalse(isGarbageCollectionNeeded(200, 1300)); }