]> source.dussan.org Git - jgit.git/commitdiff
Speed up PathFilterGroup.include for large set of paths 11/9411/5
authorRobin Rosenberg <robin.rosenberg@dewire.com>
Tue, 1 Jan 2013 14:06:07 +0000 (15:06 +0100)
committerRobin Rosenberg <robin.rosenberg@dewire.com>
Mon, 7 Jan 2013 00:08:01 +0000 (01:08 +0100)
This requires that we internally sort all paths so content of
directories follow the directory immediately.

Bug: 397185
Change-Id: I3e9735c7bdd99437929da8f9c9d4960a1273054b

org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilterGroup.java

index 51761a8126576dc939fc6c90a536d645d57a5c80..d4b0555cdbb5ff2d3fb8725c7058a4ed170c6aeb 100644 (file)
@@ -177,33 +177,73 @@ public class PathFilterGroup {
        }
 
        static class Group extends TreeFilter {
-               private static final Comparator<PathFilter> PATH_SORT = new Comparator<PathFilter>() {
+               private static int pathPrefixSortCompare(byte[] p1, byte[] p2,
+                               boolean justMatch) {
+                       int ci = 0;
+                       while (ci < p1.length && ci < p2.length) {
+                               int c1 = p1[ci];
+                               int c2 = p2[ci];
+                               if (c1 == '/')
+                                       c1 = 0;
+                               if (c2 == '/')
+                                       c2 = 0;
+                               int cmp = c1 - c2;
+                               if (cmp != 0)
+                                       return cmp;
+                               ++ci;
+                       }
+                       if (ci < p1.length) {
+                               int c1 = p1[ci];
+                               if (c1 == '/')
+                                       if (justMatch)
+                                               return 0;
+                               return 1;
+                       }
+                       if (ci < p2.length) {
+                               int c2 = p2[ci];
+                               if (c2 == '/')
+                                       return 0;
+                               return -1;
+                       }
+                       return 0;
+               }
+
+               private static final Comparator<PathFilter> PATH_PREFIX_SORT = new Comparator<PathFilter>() {
                        public int compare(final PathFilter o1, final PathFilter o2) {
-                               return o1.pathStr.compareTo(o2.pathStr);
+                               return pathPrefixSortCompare(o1.pathRaw, o2.pathRaw, false);
                        }
+
                };
 
                private final PathFilter[] paths;
 
                private Group(final PathFilter[] p) {
                        paths = p;
-                       Arrays.sort(paths, PATH_SORT);
+                       Arrays.sort(paths, PATH_PREFIX_SORT);
                }
 
                @Override
                public boolean include(final TreeWalk walker) {
-                       final int n = paths.length;
-                       for (int i = 0;;) {
-                               final byte[] r = paths[i].pathRaw;
-                               final int cmp = walker.isPathPrefix(r, r.length);
-                               if (cmp == 0)
-                                       return true;
-                               if (++i < n)
-                                       continue;
-                               if (cmp > 0)
-                                       throw StopWalkException.INSTANCE;
-                               return false;
-                       }
+                       final byte[] rawPath = walker.getRawPath();
+                       Comparator comparator = new Comparator<Object>() {
+                               public int compare(Object pf, Object raw) {
+                                       PathFilter pathFilter = (PathFilter) pf;
+                                       int ret = -pathPrefixSortCompare(walker.getRawPath(),
+                                                       pathFilter.pathRaw, true);
+                                       return ret;
+                               }
+                       };
+
+                       Object[] pathsObject = paths;
+                       Object rawObject = rawPath;
+                       @SuppressWarnings("unchecked")
+                       int position = Arrays.binarySearch(pathsObject, rawObject,
+                                       comparator);
+                       if (position >= 0)
+                               return true;
+                       if (position == -paths.length - 1)
+                               throw StopWalkException.INSTANCE;
+                       return false;
                }
 
                @Override