Index: oak-run/src/main/java/org/apache/jackrabbit/oak/checkpoint/Checkpoints.java =================================================================== --- oak-run/src/main/java/org/apache/jackrabbit/oak/checkpoint/Checkpoints.java (revision 1761025) +++ oak-run/src/main/java/org/apache/jackrabbit/oak/checkpoint/Checkpoints.java (working copy) @@ -18,9 +18,11 @@ import java.io.File; import java.io.IOException; +import java.util.HashSet; import java.util.List; +import java.util.Set; -import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; import com.google.common.io.Closer; import org.apache.jackrabbit.oak.api.PropertyState; @@ -77,18 +79,19 @@ */ public abstract int remove(String cp); - @CheckForNull - static String getReferenceCheckpoint(NodeState root) { - String ref = null; - PropertyState refPS = root.getChildNode(":async").getProperty("async"); - if (refPS != null) { - ref = refPS.getValue(Type.STRING); + @Nonnull + static Set getReferencedCheckpoints(NodeState root) { + Set cps = new HashSet(); + for (PropertyState ps : root.getChildNode(":async").getProperties()) { + String name = ps.getName(); + if (name.endsWith("async") && ps.getType().equals(Type.STRING)) { + String ref = ps.getValue(Type.STRING); + System.out.println("Referenced checkpoint from /:async@" + name + + " is " + ref); + cps.add(ref); + } } - if (ref != null) { - System.out.println( - "Referenced checkpoint from /:async@async is " + ref); - } - return ref; + return cps; } public static final class CP { Index: oak-run/src/main/java/org/apache/jackrabbit/oak/checkpoint/DocumentCheckpoints.java =================================================================== --- oak-run/src/main/java/org/apache/jackrabbit/oak/checkpoint/DocumentCheckpoints.java (revision 1761025) +++ oak-run/src/main/java/org/apache/jackrabbit/oak/checkpoint/DocumentCheckpoints.java (working copy) @@ -18,6 +18,7 @@ package org.apache.jackrabbit.oak.checkpoint; import static org.apache.jackrabbit.oak.plugins.document.CheckpointsHelper.getCheckpoints; +import static org.apache.jackrabbit.oak.plugins.document.CheckpointsHelper.min; import static org.apache.jackrabbit.oak.plugins.document.CheckpointsHelper.removeOlderThan; import java.util.List; @@ -54,11 +55,11 @@ @Override public long removeUnreferenced() { - String ref = getReferenceCheckpoint(store.getRoot()); + Revision ref = min(getReferencedCheckpoints(store.getRoot())); if (ref == null) { return -1; } - return removeOlderThan(store, Revision.fromString(ref)); + return removeOlderThan(store, ref); } @Override Index: oak-run/src/main/java/org/apache/jackrabbit/oak/checkpoint/SegmentCheckpoints.java =================================================================== --- oak-run/src/main/java/org/apache/jackrabbit/oak/checkpoint/SegmentCheckpoints.java (revision 1761025) +++ oak-run/src/main/java/org/apache/jackrabbit/oak/checkpoint/SegmentCheckpoints.java (working copy) @@ -20,6 +20,7 @@ import java.io.File; import java.io.IOException; import java.util.List; +import java.util.Set; import com.google.common.collect.Lists; import com.google.common.io.Closer; @@ -73,13 +74,13 @@ public long removeUnreferenced() { SegmentNodeState head = store.getHead(); - String ref = getReferenceCheckpoint(head.getChildNode("root")); + Set refs = getReferencedCheckpoints(head.getChildNode("root")); NodeBuilder builder = head.builder(); NodeBuilder cps = builder.getChildNode("checkpoints"); long cnt = 0; for (String c : cps.getChildNodeNames()) { - if (c.equals(ref)) { + if (refs.contains(c)) { continue; } cps.getChildNode(c).remove(); Index: oak-run/src/main/java/org/apache/jackrabbit/oak/checkpoint/SegmentTarCheckpoints.java =================================================================== --- oak-run/src/main/java/org/apache/jackrabbit/oak/checkpoint/SegmentTarCheckpoints.java (revision 1761025) +++ oak-run/src/main/java/org/apache/jackrabbit/oak/checkpoint/SegmentTarCheckpoints.java (working copy) @@ -22,6 +22,7 @@ import java.io.File; import java.io.IOException; import java.util.List; +import java.util.Set; import com.google.common.collect.Lists; import com.google.common.io.Closer; @@ -79,13 +80,13 @@ public long removeUnreferenced() { SegmentNodeState head = store.getHead(); - String ref = getReferenceCheckpoint(head.getChildNode("root")); + Set refs = getReferencedCheckpoints(head.getChildNode("root")); NodeBuilder builder = head.builder(); NodeBuilder cps = builder.getChildNode("checkpoints"); long cnt = 0; for (String c : cps.getChildNodeNames()) { - if (c.equals(ref)) { + if (refs.contains(c)) { continue; } cps.getChildNode(c).remove(); Index: oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/document/CheckpointsHelper.java =================================================================== --- oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/document/CheckpointsHelper.java (revision 1761025) +++ oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/document/CheckpointsHelper.java (working copy) @@ -19,6 +19,7 @@ package org.apache.jackrabbit.oak.plugins.document; import java.util.Map; +import java.util.Set; import java.util.SortedMap; import com.google.common.collect.Maps; @@ -69,4 +70,20 @@ } } + public static Revision min(Set revs) { + if (revs == null || revs.isEmpty()) { + return null; + } + Revision r = null; + for (String cp : revs) { + Revision t = Revision.fromString(cp); + if (r == null) { + r = t; + } else if (t.getTimestamp() < r.getTimestamp()) { + r = t; + } + } + return r; + } + }