Bug 570896: Optimize comparePathUri for normal URIs
If URI is already normal u.normalize() will just return u.
i.e. no memory allocation.
Change-Id: I379d3b3460b3444f1a99b938c5f4c6ee433d69ea
Signed-off-by: Joerg Kubitz <jkubitz-eclipse@gmx.de>
diff --git a/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/FileStoreUtil.java b/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/FileStoreUtil.java
index cb1881c..ae3c31f 100644
--- a/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/FileStoreUtil.java
+++ b/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/FileStoreUtil.java
@@ -15,8 +15,6 @@
import java.net.URI;
import org.eclipse.core.filesystem.IFileStore;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
/**
* Provides internal utility functions for comparing FileStores and paths
@@ -28,8 +26,9 @@
}
/**
- * Compares URIs by normalized IPath
- * This is the old slow implementation and has a memory hotspot see bug 570896. Prefer to use compareNormalisedUri!
+ * Compares URIs by their normalized values.
+ * This implementation has a memory hotspot when uri is not normalized.
+ * see bug 570896!
* @since org.eclipse.core.filesystem 1.9
*/
private static int comparePathUri(URI uri1, URI uri2) {
@@ -40,40 +39,22 @@
// in case of Exceptions:
if ((compare = nullsLast(uri1, uri2)) != 0)
return compare;
- // compare hosts
- compare = compareStringOrNull(uri1.getHost(), uri2.getHost());
- if (compare != 0)
- return compare;
- // compare user infos
- compare = compareStringOrNull(uri1.getUserInfo(), uri2.getUserInfo());
- if (compare != 0)
- return compare;
- // compare ports
- int port1 = uri1.getPort();
- int port2 = uri2.getPort();
- if (port1 != port2)
- return port1 - port2;
+ // note: If uri is already normal u.normalize() will just return u:
+ return compareNormalisedUri(uri1.normalize(), uri2.normalize());
+ }
- IPath path1 = new Path(uri1.getPath());
- IPath path2 = new Path(uri2.getPath());
- // compare devices
- compare = compareStringOrNull(path1.getDevice(), path2.getDevice());
- if (compare != 0)
- return compare;
- // compare segments
- int segmentCount1 = path1.segmentCount();
- int segmentCount2 = path2.segmentCount();
- for (int i = 0; (i < segmentCount1) && (i < segmentCount2); i++) {
- compare = path1.segment(i).compareTo(path2.segment(i));
- if (compare != 0)
- return compare;
- }
- //all segments are equal, so compare based on number of segments
- compare = segmentCount1 - segmentCount2;
- if (compare != 0)
- return compare;
- //same number of segments, so compare query
- return compareStringOrNull(uri1.getQuery(), uri2.getQuery());
+ private static int compareNormalisedUri(URI uri1, URI uri2) {
+ int c;
+ // avoid to use IPath here due to high ephemeral memory allocation (Bug 570896)
+ if ((c = compareStringOrNull(uri1.getAuthority(), uri2.getAuthority())) != 0)
+ return c;
+ if ((c = compareStringOrNull(uri1.getScheme(), uri2.getScheme())) != 0)
+ return c;
+ if ((c = comparePathSegments(uri1.getPath(), uri2.getPath())) != 0)
+ return c;
+ if ((c = compareStringOrNull(uri1.getQuery(), uri2.getQuery())) != 0)
+ return c;
+ return c;
}
static int nullsLast(Object c1, Object c2) {