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 fr...@apache.org on 2016/10/03 15:59:19 UTC

svn commit: r1763180 - /jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyClientSyncExecution.java

Author: frm
Date: Mon Oct  3 15:59:19 2016
New Revision: 1763180

URL: http://svn.apache.org/viewvc?rev=1763180&view=rev
Log:
OAK-4878 - Don't queue segments that are already queued for synchronization

Modified:
    jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyClientSyncExecution.java

Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyClientSyncExecution.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyClientSyncExecution.java?rev=1763180&r1=1763179&r2=1763180&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyClientSyncExecution.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyClientSyncExecution.java Mon Oct  3 15:59:19 2016
@@ -56,6 +56,8 @@ class StandbyClientSyncExecution {
 
     private final Set<UUID> visited = newHashSet();
 
+    private final Set<UUID> queued = newHashSet();
+
     private final Map<UUID, Segment> cache = newHashMap();
 
     StandbyClientSyncExecution(FileStore store, StandbyClient client, Supplier<Boolean> running) {
@@ -125,16 +127,34 @@ class StandbyClientSyncExecution {
             for (int i = 0; i < segment.getReferencedSegmentIdCount(); i++) {
                 UUID referenced = segment.getReferencedSegmentId(i);
 
+                // Short circuit for the "back reference problem". The segment
+                // graph might or might not be acyclic. The following check
+                // prevents processing segment that were already traversed.
+
                 if (visited.contains(referenced)) {
                     continue;
                 }
 
+                // Short circuit for the "diamond problem". Imagine that segment S1
+                // references S2 and S3 and both S2 and S3 reference S4. These
+                // references form the shape of a diamond. If the segments are
+                // processed in the order S1, S2, S3, then S4 is added twice to the
+                // 'batch' queue. The following check prevents processing S4 twice
+                // or more.
+
+                if (queued.contains(referenced)) {
+                    continue;
+                }
+
                 log.info("Found reference from {} to {}", current, referenced);
+
                 if (SegmentId.isDataSegmentId(referenced.getLeastSignificantBits())) {
                     batch.add(referenced);
                 } else {
                     batch.addFirst(referenced);
                 }
+
+                queued.add(referenced);
             }
         }
     }