Author: chetanm
Date: Fri Nov 25 14:19:53 2016
New Revision: 1771320

URL: http://svn.apache.org/viewvc?rev=1771320&view=rev
Log:
OAK-5126 - Support ChangeSet merging and serialization

Handle the case where maxDepth of ChangeSet being added and ChangeSetBuilder 
differs. In such a case resulting builder state should have maxDepth as 
min(current depth, changeSet max depth)

Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeSetBuilder.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/observation/ChangeSetBuilderTest.java

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeSetBuilder.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeSetBuilder.java?rev=1771320&r1=1771319&r2=1771320&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeSetBuilder.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeSetBuilder.java
 Fri Nov 25 14:19:53 2016
@@ -29,7 +29,7 @@ import org.apache.jackrabbit.oak.commons
 public class ChangeSetBuilder {
 
     private final int maxItems;
-    private final int maxPathDepth;
+    private int maxPathDepth;
     private final Set<String> parentPaths = Sets.newHashSet();
     private final Set<String> parentNodeNames = Sets.newHashSet();
     private final Set<String> parentNodeTypes = Sets.newHashSet();
@@ -123,9 +123,7 @@ public class ChangeSetBuilder {
         if (cs.getParentPaths() == null){
             parentPathOverflow = true;
         } else {
-            for (String parentPath : cs.getParentPaths()){
-                addParentPath(parentPath);
-            }
+            addPathFromChangeSet(cs);
         }
 
         if (cs.getParentNodeNames() == null){
@@ -171,6 +169,34 @@ public class ChangeSetBuilder {
                 allNodeTypeOverflow ? null : allNodeTypes);
     }
 
+    private void addPathFromChangeSet(ChangeSet cs) {
+        int maxDepthInChangeSet = cs.getMaxPrefilterPathDepth();
+
+        //If maxDepth of ChangeSet being added is less than current
+        //then truncate path in current set to that depth and change
+        //maxPathDepth to one from ChangeSet
+        if (maxDepthInChangeSet < maxPathDepth){
+            Set<String> existingPathSet = Sets.newHashSet(parentPaths);
+            parentPaths.clear();
+            for (String existingPath : existingPathSet){
+               parentPaths.add(getPathWithMaxDepth(existingPath, 
maxDepthInChangeSet));
+            }
+            maxPathDepth = maxDepthInChangeSet;
+        }
+
+        for (String pathFromChangeSet : cs.getParentPaths()){
+            addParentPath(getPathWithMaxDepth(pathFromChangeSet, 
maxPathDepth));
+        }
+    }
+
+    private static String getPathWithMaxDepth(String path, int maxDepth){
+        int depth = PathUtils.getDepth(path);
+        if (depth <= maxDepth){
+            return path;
+        }
+        return PathUtils.getAncestorPath(path, depth - maxDepth);
+    }
+
     /**
      * Add data to dataSet if dataSet size is less than maxSize.
      *

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/observation/ChangeSetBuilderTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/observation/ChangeSetBuilderTest.java?rev=1771320&r1=1771319&r2=1771320&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/observation/ChangeSetBuilderTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/observation/ChangeSetBuilderTest.java
 Fri Nov 25 14:19:53 2016
@@ -23,6 +23,7 @@ import org.junit.Test;
 
 import static com.google.common.collect.ImmutableSet.of;
 import static 
org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThat;
 
@@ -135,7 +136,7 @@ public class ChangeSetBuilderTest {
 
     @Test
     public void pathDepth() throws Exception{
-        ChangeSetBuilder cb = new ChangeSetBuilder(2, 2);
+        ChangeSetBuilder cb = new ChangeSetBuilder(10, 2);
         cb.addParentPath("/a/b");
         cb.addParentPath("/x");
         cb.addParentPath("/p/q/r");
@@ -144,6 +145,57 @@ public class ChangeSetBuilderTest {
         assertThat(cs.getParentPaths(), containsInAnyOrder("/a/b", "/x"));
     }
 
+    @Test
+    public void changeSetDepthMoreThanBuilder() throws Exception{
+        ChangeSetBuilder cb1 = new ChangeSetBuilder(10, 3);
+        cb1.addParentPath("/x");
+        cb1.addParentPath("/x/y");
+        cb1.addParentPath("/x/y/z");
+
+        ChangeSetBuilder cb2 = new ChangeSetBuilder(10, 8);
+        cb2.addParentPath("/p");
+        cb2.addParentPath("/p/q");
+        cb2.addParentPath("/p/q/r");
+        cb2.addParentPath("/a/b/c/d");
+        cb2.addParentPath("/a/b/x/y/z");
+
+        cb1.add(cb2.build());
+
+        ChangeSet cs = cb1.build();
+        assertThat(cs.getParentPaths(), containsInAnyOrder(
+                "/x", "/x/y", "/x/y/z",
+                "/p", "/p/q", "/p/q/r",
+                "/a/b/c", "/a/b/x" //Chopped paths
+        ));
+
+        assertEquals(cb1.getMaxPrefilterPathDepth(), 
cs.getMaxPrefilterPathDepth());
+    }
+
+    @Test
+    public void builderDepthMoreThanChangeSet() throws Exception{
+        ChangeSetBuilder cb1 = new ChangeSetBuilder(10, 8);
+        cb1.addParentPath("/p");
+        cb1.addParentPath("/p/q");
+        cb1.addParentPath("/p/q/r");
+        cb1.addParentPath("/a/b/c/d");
+        cb1.addParentPath("/a/b/x/y/z");
+
+        ChangeSetBuilder cb2 = new ChangeSetBuilder(10, 2);
+        cb2.addParentPath("/x");
+        cb2.addParentPath("/x/y");
+
+        cb1.add(cb2.build());
+
+        ChangeSet cs = cb1.build();
+        assertThat(cs.getParentPaths(), containsInAnyOrder(
+                "/x", "/x/y",
+                "/p", "/p/q",
+                "/a/b" //Chopped paths
+        ));
+
+        assertEquals(cb2.getMaxPrefilterPathDepth(), 
cs.getMaxPrefilterPathDepth());
+    }
+
     private static void add(ChangeSetBuilder cb, String suffix){
         cb.addNodeType("nt-"+suffix)
                 .addParentPath("p-"+suffix)


Reply via email to