mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
FileUtil.isAncestor() performance
This commit is contained in:
+21
-3
@@ -20,21 +20,39 @@ import com.intellij.util.ThrowableRunnable;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class FileUtilPerformanceTest {
|
||||
private String myTestPath = "/a/b/c/./d///e/../f/g/h/i/j/";
|
||||
private String myCanonicalPath = "/a/b/c/d/f/g/h/i/j";
|
||||
|
||||
@Test
|
||||
public void toCanonicalPath() throws Exception {
|
||||
final String testPath = "/a/b/c/./d///e/../f/g/h/i/j/";
|
||||
assertEquals("/a/b/c/d/f/g/h/i/j", FileUtil.toCanonicalPath(testPath));
|
||||
assertEquals(myCanonicalPath, FileUtil.toCanonicalPath(myTestPath));
|
||||
|
||||
PlatformTestUtil.startPerformanceTest("", 1000, new ThrowableRunnable() {
|
||||
@Override
|
||||
public void run() throws Throwable {
|
||||
for (int i = 0; i < 1000000; ++i) {
|
||||
final String canonicalPath = FileUtil.toCanonicalPath(testPath, '/');
|
||||
final String canonicalPath = FileUtil.toCanonicalPath(myTestPath, '/');
|
||||
assert canonicalPath != null && canonicalPath.length() == 18 : canonicalPath;
|
||||
}
|
||||
}
|
||||
}).cpuBound().assertTiming();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAncestor() throws Exception {
|
||||
assertTrue(FileUtil.isAncestor(myTestPath, myCanonicalPath, false));
|
||||
|
||||
PlatformTestUtil.startPerformanceTest("", 4000, new ThrowableRunnable() {
|
||||
@Override
|
||||
public void run() throws Throwable {
|
||||
for (int i = 0; i < 1000000; ++i) {
|
||||
assert FileUtil.isAncestor(myTestPath, myCanonicalPath, false);
|
||||
assert !FileUtil.isAncestor(myTestPath, myCanonicalPath, true);
|
||||
}
|
||||
}
|
||||
}).cpuBound().assertTiming();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,31 +99,34 @@ public class FileUtil extends FileUtilRt {
|
||||
return new File(path).isAbsolute();
|
||||
}
|
||||
|
||||
public static boolean isAncestor(@NotNull final String ancestor, @NotNull final String descendant, final boolean strict) {
|
||||
return isAncestor(new File(toSystemDependentName(ancestor)), new File(toSystemDependentName(descendant)), strict);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the {@code ancestor} is an ancestor of {@code file}.
|
||||
*
|
||||
* @param ancestor the file
|
||||
* @param file the file
|
||||
* @param strict if {@code false} then this method returns {@code true} if {@code ancestor}
|
||||
* and {@code file} are equal
|
||||
* @return {@code true} if {@code ancestor} is parent of {@code file}; {@code false} otherwise
|
||||
* @param ancestor supposed ancestor.
|
||||
* @param file supposed descendant.
|
||||
* @param strict if {@code false} then this method returns {@code true} if {@code ancestor} equals to {@code file}.
|
||||
* @return {@code true} if {@code ancestor} is parent of {@code file}; {@code false} otherwise.
|
||||
*/
|
||||
public static boolean isAncestor(@NotNull File ancestor, @NotNull File file, boolean strict) {
|
||||
File parent = strict ? getParentFile(file) : file;
|
||||
while (true) {
|
||||
if (parent == null) {
|
||||
return false;
|
||||
}
|
||||
// Do not user file.equals as it incorrectly works on MacOS
|
||||
if (pathsEqual(parent.getPath(), ancestor.getPath())) {
|
||||
return true;
|
||||
}
|
||||
parent = getParentFile(parent);
|
||||
return isAncestor(ancestor.getPath(), file.getPath(), strict);
|
||||
}
|
||||
|
||||
public static boolean isAncestor(@NotNull String ancestor, @NotNull String descendant, boolean strict) {
|
||||
String ancestorPath = toCanonicalPath(ancestor);
|
||||
String filePath = toCanonicalPath(descendant);
|
||||
|
||||
if (ancestorPath == null || filePath == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean startsWith = SystemInfo.isFileSystemCaseSensitive ? StringUtil.startsWith(filePath, ancestorPath)
|
||||
: StringUtil.startsWithIgnoreCase(filePath, ancestorPath);
|
||||
if (!startsWith) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return filePath.length() > ancestorPath.length() && filePath.charAt(ancestorPath.length()) == '/' ||
|
||||
!strict && filePath.length() == ancestorPath.length();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,9 +15,12 @@
|
||||
*/
|
||||
package com.intellij.openapi.util.io;
|
||||
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Roman Shevchenko
|
||||
@@ -57,4 +60,20 @@ public class FileUtilTest {
|
||||
assertEquals("c:/", FileUtil.toCanonicalPath("c:\\a\\..\\..", WINDOWS_SEPARATOR));
|
||||
assertEquals("c:/b", FileUtil.toCanonicalPath("c:\\a\\..\\..\\b", WINDOWS_SEPARATOR));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAncestor() throws Exception {
|
||||
assertTrue(FileUtil.isAncestor("/a/b/c", "/a/b/c/d/e/f", true));
|
||||
assertTrue(FileUtil.isAncestor("/a/b/c/", "/a/b/c/d/e/f", true));
|
||||
assertFalse(FileUtil.isAncestor("/a/b/c/1", "/a/b/c/2", true));
|
||||
assertFalse(FileUtil.isAncestor("/a/b/c/1", "/a/b/c/2", false));
|
||||
assertTrue(FileUtil.isAncestor("/a/b/c/", "/a/b/c", false));
|
||||
assertTrue(FileUtil.isAncestor("/a///b/c", "/a/b/c/", false));
|
||||
assertFalse(FileUtil.isAncestor("/a/b/c/", "/a/./b/c", true));
|
||||
assertFalse(FileUtil.isAncestor("/a/b/c", "/a/b/c/", true));
|
||||
assertFalse(FileUtil.isAncestor("/a/b/c", "/a/b/cde", true));
|
||||
assertFalse(FileUtil.isAncestor("/a/b/c", "/a/b/cde", false));
|
||||
|
||||
assertEquals(!SystemInfo.isFileSystemCaseSensitive, FileUtil.isAncestor("/a/b/c", "/a/B/c/d", true));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user