Author: mreutegg
Date: Tue Feb 14 14:20:07 2017
New Revision: 1782968
URL: http://svn.apache.org/viewvc?rev=1782968&view=rev
Log:
OAK-5605: Speed up time to cancel revision GC
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollectorIT.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java?rev=1782968&r1=1782967&r2=1782968&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java
Tue Feb 14 14:20:07 2017
@@ -159,8 +159,9 @@ public class VersionGarbageCollector {
final Stopwatch elapsed;
private final List<GCPhase> phases = Lists.newArrayList();
private final Map<GCPhase, Stopwatch> watches = Maps.newHashMap();
+ private final AtomicBoolean canceled;
- GCPhases() {
+ GCPhases(AtomicBoolean canceled) {
this.stats = new VersionGCStats();
this.elapsed = Stopwatch.createStarted();
this.watches.put(GCPhase.NONE, Stopwatch.createStarted());
@@ -168,12 +169,25 @@ public class VersionGarbageCollector {
this.watches.put(GCPhase.DELETING, stats.deleteDeletedDocs);
this.watches.put(GCPhase.SORTING, stats.sortDocIds);
this.watches.put(GCPhase.SPLITS_CLEANUP,
stats.collectAndDeleteSplitDocs);
+ this.canceled = canceled;
}
- public void start(GCPhase started) {
+ /**
+ * Attempts to start a GC phase and tracks the time spent in this phase
+ * until {@link #stop(GCPhase)} is called.
+ *
+ * @param started the GC phase.
+ * @return {@code true} if the phase was started or {@code false} if
the
+ * revision GC was canceled and the phase should not start.
+ */
+ public boolean start(GCPhase started) {
+ if (canceled.get()) {
+ return false;
+ }
suspend(currentWatch());
this.phases.add(started);
resume(currentWatch());
+ return true;
}
public void stop(GCPhase phase) {
@@ -231,7 +245,7 @@ public class VersionGarbageCollector {
}
private VersionGCStats gc(long maxRevisionAgeInMillis) throws
IOException {
- GCPhases phases = new GCPhases();
+ GCPhases phases = new GCPhases(cancel);
final long oldestRevTimeStamp = nodeStore.getClock().getTime() -
maxRevisionAgeInMillis;
final RevisionVector headRevision = nodeStore.getHeadRevision();
@@ -260,9 +274,10 @@ public class VersionGarbageCollector {
}
private void collectSplitDocuments(GCPhases phases, long
oldestRevTimeStamp) {
- phases.start(GCPhase.SPLITS_CLEANUP);
- versionStore.deleteSplitDocuments(GC_TYPES, oldestRevTimeStamp,
phases.stats);
- phases.stop(GCPhase.SPLITS_CLEANUP);
+ if (phases.start(GCPhase.SPLITS_CLEANUP)) {
+ versionStore.deleteSplitDocuments(GC_TYPES,
oldestRevTimeStamp, phases.stats);
+ phases.stop(GCPhase.SPLITS_CLEANUP);
+ }
}
private void collectDeletedDocuments(GCPhases phases,
@@ -272,50 +287,55 @@ public class VersionGarbageCollector {
int docsTraversed = 0;
DeletedDocsGC gc = new DeletedDocsGC(headRevision, cancel);
try {
- phases.start(GCPhase.COLLECTING);
- Iterable<NodeDocument> itr =
versionStore.getPossiblyDeletedDocs(oldestRevTimeStamp);
- try {
- for (NodeDocument doc : itr) {
- // continue with GC?
- if (cancel.get()) {
- break;
- }
- // Check if node is actually deleted at current
revision
- // As node is not modified since oldestRevTimeStamp
then
- // this node has not be revived again in past
maxRevisionAge
- // So deleting it is safe
- docsTraversed++;
- if (docsTraversed % PROGRESS_BATCH_SIZE == 0){
- log.info("Iterated through {} documents so far. {}
found to be deleted",
- docsTraversed, gc.getNumDocuments());
- }
- gc.possiblyDeleted(doc);
- if (gc.hasLeafBatch()) {
- phases.start(GCPhase.DELETING);
- gc.removeLeafDocuments(phases.stats);
- phases.stop(GCPhase.DELETING);
+ if (phases.start(GCPhase.COLLECTING)) {
+ Iterable<NodeDocument> itr =
versionStore.getPossiblyDeletedDocs(oldestRevTimeStamp);
+ try {
+ for (NodeDocument doc : itr) {
+ // continue with GC?
+ if (cancel.get()) {
+ break;
+ }
+ // Check if node is actually deleted at current
revision
+ // As node is not modified since
oldestRevTimeStamp then
+ // this node has not be revived again in past
maxRevisionAge
+ // So deleting it is safe
+ docsTraversed++;
+ if (docsTraversed % PROGRESS_BATCH_SIZE == 0){
+ log.info("Iterated through {} documents so
far. {} found to be deleted",
+ docsTraversed, gc.getNumDocuments());
+ }
+ gc.possiblyDeleted(doc);
+ if (gc.hasLeafBatch()) {
+ if (phases.start(GCPhase.DELETING)) {
+ gc.removeLeafDocuments(phases.stats);
+ phases.stop(GCPhase.DELETING);
+ }
+ }
}
+ } finally {
+ Utils.closeIfCloseable(itr);
}
- } finally {
- Utils.closeIfCloseable(itr);
+ phases.stop(GCPhase.COLLECTING);
}
- phases.stop(GCPhase.COLLECTING);
if (gc.getNumDocuments() == 0){
return;
}
- phases.start(GCPhase.DELETING);
- gc.removeLeafDocuments(phases.stats);
- phases.stop(GCPhase.DELETING);
-
- phases.start(GCPhase.SORTING);
- gc.ensureSorted();
- phases.stop(GCPhase.SORTING);
-
- phases.start(GCPhase.DELETING);
- gc.removeDocuments(phases.stats);
- phases.stop(GCPhase.DELETING);
+ if (phases.start(GCPhase.DELETING)) {
+ gc.removeLeafDocuments(phases.stats);
+ phases.stop(GCPhase.DELETING);
+ }
+
+ if (phases.start(GCPhase.SORTING)) {
+ gc.ensureSorted();
+ phases.stop(GCPhase.SORTING);
+ }
+
+ if (phases.start(GCPhase.DELETING)) {
+ gc.removeDocuments(phases.stats);
+ phases.stop(GCPhase.DELETING);
+ }
} finally {
gc.close();
}
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollectorIT.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollectorIT.java?rev=1782968&r1=1782967&r2=1782968&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollectorIT.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollectorIT.java
Tue Feb 14 14:20:07 2017
@@ -75,7 +75,6 @@ import org.apache.jackrabbit.oak.spi.sta
import org.apache.jackrabbit.oak.stats.Clock;
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -605,7 +604,6 @@ public class VersionGarbageCollectorIT {
assertNotEquals(modCount, foo.getModCount());
}
- @Ignore("OAK-5605")
@Test
public void cancelGCBeforeFirstPhase() throws Exception {
createTestNode("foo");
@@ -639,7 +637,6 @@ public class VersionGarbageCollectorIT {
assertEquals(0, stats.splitDocGCCount);
}
- @Ignore("OAK-5605")
@Test
public void cancelGCAfterFirstPhase() throws Exception {
createTestNode("foo");