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 mr...@apache.org on 2016/12/14 16:53:25 UTC
svn commit: r1774292 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/plugins/observation/filter/ChangeSetFilterImpl.java
test/java/org/apache/jackrabbit/oak/plugins/observation/filter/ChangeSetFilterImplTest.java
Author: mreutegg
Date: Wed Dec 14 16:53:25 2016
New Revision: 1774292
URL: http://svn.apache.org/viewvc?rev=1774292&view=rev
Log:
OAK-5186: ChangeSetFilterImpl: support many includePaths by filtering for 1st path name
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/ChangeSetFilterImpl.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/observation/filter/ChangeSetFilterImplTest.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/ChangeSetFilterImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/ChangeSetFilterImpl.java?rev=1774292&r1=1774291&r2=1774292&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/ChangeSetFilterImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/ChangeSetFilterImpl.java Wed Dec 14 16:53:25 2016
@@ -42,6 +42,7 @@ public class ChangeSetFilterImpl impleme
private static final int MAX_EXCLUDE_PATH_CUTOFF_LEVEL = 6;
private final Set<String> rootIncludePaths;
+ private final Set<String> firstLevelIncludeNames;
private final Set<Pattern> includePathPatterns;
private final Set<Pattern> excludePathPatterns;
private final Set<Pattern> unpreciseExcludePathPatterns;
@@ -69,6 +70,7 @@ public class ChangeSetFilterImpl impleme
int maxExcludedPaths) {
this.rootIncludePaths = new HashSet<String>();
this.includePathPatterns = new HashSet<Pattern>();
+ Set<String> firstLevelIncludePaths = new HashSet<String>();
for (String aRawIncludePath : includedParentPaths) {
final String aGlobbingIncludePath;
if (aRawIncludePath.contains("*")) {
@@ -79,13 +81,31 @@ public class ChangeSetFilterImpl impleme
}
this.rootIncludePaths.add(aRawIncludePath);
this.includePathPatterns.add(asPattern(aGlobbingIncludePath));
+ if (firstLevelIncludePaths != null) {
+ final String firstLevelName = firstLevelName(aRawIncludePath);
+ if (firstLevelName != null && !firstLevelName.contains("*")) {
+ firstLevelIncludePaths.add(firstLevelName);
+ } else {
+ firstLevelIncludePaths = null;
+ }
+ }
}
if (additionalIncludedParentPaths != null) {
for (String path : additionalIncludedParentPaths) {
this.rootIncludePaths.add(path);
this.includePathPatterns.add(asPattern(path));
+ if (firstLevelIncludePaths != null) {
+ final String firstLevelName = firstLevelName(path);
+ if (firstLevelName != null && !firstLevelName.contains("*")) {
+ firstLevelIncludePaths.add(firstLevelName);
+ } else {
+ firstLevelIncludePaths = null;
+ }
+ }
}
}
+ this.firstLevelIncludeNames = firstLevelIncludePaths;
+
// OAK-5169:
// excludedParentPaths could in theory be a large list, in which case
// the excludes() algorithm becomes non-performing. Reason is, that it
@@ -119,6 +139,18 @@ public class ChangeSetFilterImpl impleme
this.parentNodeNames = parentNodeNames == null ? null : new HashSet<String>(parentNodeNames);
}
+ private String firstLevelName(String path) {
+ if (path.isEmpty() || path.equals("/")) {
+ return null;
+ }
+ int secondSlash = path.indexOf("/", 1);
+ if (secondSlash != -1) {
+ return path.substring(1, secondSlash);
+ } else {
+ return path.substring(1);
+ }
+ }
+
private Set<String> unprecisePaths(Set<String> paths, int maxExcludedPaths, int maxExcludePathCutOffLevel) {
int level = maxExcludePathCutOffLevel;
while(level > 1) {
@@ -228,6 +260,15 @@ public class ChangeSetFilterImpl impleme
included = true;
break;
}
+ if (firstLevelIncludeNames != null) {
+ final String firstLevelName = firstLevelName(aPath);
+ if (firstLevelName != null && !firstLevelIncludeNames.contains(firstLevelName)) {
+ // then the 'first level name check' concluded that
+ // it's not in any include path - hence we can skip
+ // the (more expensive) pattern check
+ continue;
+ }
+ }
if (patternsMatch(this.includePathPatterns, aPath)) {
included = true;
break;
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/observation/filter/ChangeSetFilterImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/observation/filter/ChangeSetFilterImplTest.java?rev=1774292&r1=1774291&r2=1774292&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/observation/filter/ChangeSetFilterImplTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/observation/filter/ChangeSetFilterImplTest.java Wed Dec 14 16:53:25 2016
@@ -25,13 +25,20 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
+import com.google.common.base.Stopwatch;
+import com.google.common.collect.Sets;
+
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.plugins.observation.ChangeSet;
import org.apache.jackrabbit.oak.plugins.observation.ChangeSetBuilder;
import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class ChangeSetFilterImplTest {
+ private static final Logger LOG = LoggerFactory.getLogger(ChangeSetFilterImplTest.class);
+
/** shortcut for creating a set of strings */
private Set<String> s(String... entries) {
return new HashSet<String>(Arrays.asList(entries));
@@ -332,4 +339,36 @@ public class ChangeSetFilterImplTest {
assertFalse(prefilter.excludes(builder.build()));
}
}
+
+ @Test
+ public void manyIncludePaths() throws Exception {
+ int numPaths = 50;
+ ChangeSetBuilder builder = newBuilder(50, 9);
+ for (int i = 0; i < numPaths; i++) {
+ builder.addParentPath("/a/b/c/d/e/n" + i);
+ }
+ ChangeSet cs = builder.build();
+
+ Set<String> includes = Sets.newHashSet();
+ for (int i = 0; i < 100; i++) {
+ includes.add("/foo/bar/n-" + i + "/*.jsp");
+ }
+ ChangeSetFilter filter = new ChangeSetFilterImpl(s(),true,
+ includes, s(), s(), s(), s());
+
+ // warm up
+ doManyIncludePaths(filter, cs);
+
+ // and measure
+ Stopwatch sw = Stopwatch.createStarted();
+ doManyIncludePaths(filter, cs);
+ LOG.info("manyIncludePaths() took {}", sw.stop());
+ }
+
+ private void doManyIncludePaths(ChangeSetFilter filter, ChangeSet cs)
+ throws Exception {
+ for (int i = 0; i < 20000; i++) {
+ assertTrue(filter.excludes(cs));
+ }
+ }
}