Author: chetanm
Date: Tue May 19 05:16:37 2015
New Revision: 1680168

URL: http://svn.apache.org/r1680168
Log:
OAK-2814 - Refactor the optimize logic regarding path include and exclude to 
avoid duplication

Merging 1677579,1677581

Modified:
    jackrabbit/oak/branches/1.2/   (props changed)
    
jackrabbit/oak/branches/1.2/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/PathUtils.java
    
jackrabbit/oak/branches/1.2/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/PathUtilsTest.java
    
jackrabbit/oak/branches/1.2/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ObservationManagerImpl.java

Propchange: jackrabbit/oak/branches/1.2/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue May 19 05:16:37 2015
@@ -1,3 +1,3 @@
 /jackrabbit/oak/branches/1.0:1665962
-/jackrabbit/oak/trunk:1672350,1672468,1672537,1672603,1672642,1672644,1672834-1672835,1673351,1673410,1673414,1673436,1673644,1673662-1673664,1673669,1673695,1674046,1674065,1674075,1674107,1674228,1674880,1675055,1675332,1675354,1675357,1675593,1676198,1676237,1676407,1676458,1676539,1676670,1676725,1677939,1678173,1678758,1678938,1679165,1679191,1679235
+/jackrabbit/oak/trunk:1672350,1672468,1672537,1672603,1672642,1672644,1672834-1672835,1673351,1673410,1673414,1673436,1673644,1673662-1673664,1673669,1673695,1674046,1674065,1674075,1674107,1674228,1674880,1675055,1675332,1675354,1675357,1675593,1676198,1676237,1676407,1676458,1676539,1676670,1676725,1677579,1677581,1677939,1678173,1678758,1678938,1679165,1679191,1679235
 /jackrabbit/trunk:1345480

Modified: 
jackrabbit/oak/branches/1.2/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/PathUtils.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/PathUtils.java?rev=1680168&r1=1680167&r2=1680168&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.2/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/PathUtils.java
 (original)
+++ 
jackrabbit/oak/branches/1.2/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/PathUtils.java
 Tue May 19 05:16:37 2015
@@ -18,11 +18,14 @@ package org.apache.jackrabbit.oak.common
 
 import java.util.Iterator;
 import java.util.NoSuchElementException;
+import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import javax.annotation.Nonnull;
 
+import static com.google.common.collect.Sets.newHashSet;
+
 /**
  * Utility methods to parse a path.
  * <p>
@@ -436,4 +439,47 @@ public final class PathUtils {
         return true;
     }
 
+    /**
+     * Unify path inclusions and exclusions.
+     * <ul>
+     * <li>A path in {@code includePaths} is only retained if {@code 
includePaths} contains
+     * none of its ancestors and {@code excludePaths} contains neither of its 
ancestors nor
+     * that path itself.</li>
+     * <li>A path in {@code excludePaths} is only retained if {@code 
includePaths} contains
+     * an ancestor of that path.</li>
+     * </ul>
+     *
+     * When a set of paths is <em>filtered wrt.</em> {@code includePaths} and 
{@code excludePaths}
+     * by first excluding all paths that have an ancestor or are contained in 
{@code excludePaths}
+     * and then including all paths that have an ancestor or are contained in 
{@code includePaths}
+     * then the result is the same regardless whether the {@code includePaths} 
and
+     * {@code excludePaths} sets have been run through this method or not.
+     *
+     * @param includePaths set of paths to be included
+     * @param excludedPaths set of paths to be excluded
+     */
+    public static void unifyInExcludes(Set<String> includePaths, Set<String> 
excludedPaths) {
+        Set<String> retain = newHashSet();
+        Set<String> includesRemoved = newHashSet();
+        for (String include : includePaths) {
+            for (String exclude : excludedPaths) {
+                if (exclude.equals(include) || isAncestor(exclude, include)) {
+                    includesRemoved.add(include);
+                } else if (isAncestor(include, exclude)) {
+                    retain.add(exclude);
+                }
+            }
+
+            //Remove redundant includes /a, /a/b -> /a
+            for (String include2 : includePaths) {
+                if (isAncestor(include, include2)) {
+                    includesRemoved.add(include2);
+                }
+            }
+        }
+        includePaths.removeAll(includesRemoved);
+        excludedPaths.retainAll(retain);
+    }
+
+
 }

Modified: 
jackrabbit/oak/branches/1.2/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/PathUtilsTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/PathUtilsTest.java?rev=1680168&r1=1680167&r2=1680168&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.2/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/PathUtilsTest.java
 (original)
+++ 
jackrabbit/oak/branches/1.2/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/PathUtilsTest.java
 Tue May 19 05:16:37 2015
@@ -16,11 +16,16 @@
  */
 package org.apache.jackrabbit.oak.commons;
 
+import java.util.Set;
+
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 import org.junit.Assert;
 import org.junit.Test;
 
+import static com.google.common.collect.Sets.newHashSet;
+import static org.junit.Assert.assertEquals;
+
 /**
  * Test the PathUtils class.
  */
@@ -476,4 +481,30 @@ public class PathUtilsTest extends TestC
         assertEquals(3, k);
     }
 
+    public void testOptimizeForIncludes() throws Exception{
+        Set<String> includes = newHashSet("/a", "/a/b");
+        Set<String> excludes = newHashSet("/a/b");
+        PathUtils.unifyInExcludes(includes, excludes);
+        assertEquals("Excludes supercedes include", newHashSet("/a"), 
includes);
+        assertEquals(newHashSet("/a/b"), excludes);
+
+        includes = newHashSet("/a", "/a/b/c");
+        excludes = newHashSet("/a/b");
+        PathUtils.unifyInExcludes(includes, excludes);
+        assertEquals("Excludes supercedes include", newHashSet("/a"), 
includes);
+        assertEquals(newHashSet("/a/b"), excludes);
+
+        includes = newHashSet("/a", "/a/b/c");
+        excludes = newHashSet();
+        PathUtils.unifyInExcludes(includes, excludes);
+        assertEquals(newHashSet("/a"), includes);
+    }
+
+    public void testOptimizeForExcludes() throws Exception{
+        Set<String> includes = newHashSet("/a", "/b");
+        Set<String> excludes = newHashSet("/c");
+        PathUtils.unifyInExcludes(includes, excludes);
+        assertEquals(newHashSet("/a", "/b"), includes);
+        assertEquals(newHashSet(), excludes);
+    }
 }

Modified: 
jackrabbit/oak/branches/1.2/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ObservationManagerImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ObservationManagerImpl.java?rev=1680168&r1=1680167&r2=1680168&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.2/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ObservationManagerImpl.java
 (original)
+++ 
jackrabbit/oak/branches/1.2/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ObservationManagerImpl.java
 Tue May 19 05:16:37 2015
@@ -48,6 +48,7 @@ import org.apache.jackrabbit.commons.ite
 import org.apache.jackrabbit.commons.observation.ListenerTracker;
 import org.apache.jackrabbit.oak.api.ContentSession;
 import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate;
 import org.apache.jackrabbit.oak.jcr.session.SessionContext;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
@@ -222,7 +223,7 @@ public class ObservationManagerImpl impl
             includePaths.add(namePathMapper.getOakPath(absPath));
         }
         Set<String> excludedPaths = getOakPaths(namePathMapper, 
filter.getExcludedPaths());
-        optimise(includePaths, excludedPaths);
+        PathUtils.unifyInExcludes(includePaths, excludedPaths);
         if (includePaths.isEmpty()) {
             LOG.warn("The passed filter excludes all events. No event listener 
registered");
             return;
@@ -259,26 +260,6 @@ public class ObservationManagerImpl impl
         addEventListener(listener, tracker, filterBuilder.build());
     }
 
-    /**
-     * Removes paths from {@code includePaths} that are completely excluded
-     * and only retains paths in {@code excludedPaths} that are included.
-     * @param includePaths
-     * @param excludedPaths
-     */
-    private static void optimise(Set<String> includePaths, Set<String> 
excludedPaths) {
-        Set<String> retain = newHashSet();
-        for (String include : includePaths) {
-            for (String exclude : excludedPaths) {
-                if (exclude.equals(include) || isAncestor(exclude, include)) {
-                    includePaths.remove(include);
-                } else if (isAncestor(include, exclude)) {
-                    retain.add(exclude);
-                }
-            }
-        }
-        excludedPaths.retainAll(retain);
-    }
-
     private static List<Condition> createExclusions(FilterBuilder 
filterBuilder, Iterable<String> excludedPaths) {
         List<Condition> conditions = newArrayList();
         for (String path : excludedPaths) {


Reply via email to