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) {