Index: src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/TarWriter.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/TarWriter.java (revision 1676729) +++ src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/TarWriter.java (working copy) @@ -31,16 +31,19 @@ import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; +import java.util.ArrayDeque; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Queue; import java.util.Set; import java.util.SortedMap; import java.util.UUID; import java.util.zip.CRC32; import com.google.common.collect.Lists; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -442,20 +445,28 @@ * Add all segment ids that are reachable from {@code referencedIds} via * this writer's segment graph and subsequently remove those segment ids * from {@code referencedIds} that are in this {{TarWriter}} as those can't - * be cleaned up anyway. + * be cleaned up anyway, because they will not be present in subsequent + * readers. * @param referencedIds * @throws IOException */ - synchronized void collectReferences(Set referencedIds) throws IOException { - Set referenced = newHashSet(); - for (UUID id : referencedIds) { - List refs = graph.get(id); - if (refs != null) { - referenced.addAll(refs); + synchronized void collectReferences(Set referencedIds) + throws IOException { + + Set processed = newHashSet(); + Queue ids = new ArrayDeque(referencedIds); + while (!ids.isEmpty()) { + UUID id = ids.poll(); + if (id != null && processed.add(id)) { + if (graph.containsKey(id)) { + Set refs = newHashSet(graph.get(id)); + refs.removeAll(processed); + referencedIds.addAll(refs); + referencedIds.remove(id); + ids.addAll(refs); + } } } - referencedIds.addAll(referenced); - referencedIds.removeAll(index.keySet()); } //------------------------------------------------------------< Object >--