parsing version string millions times a second is ecologically incorrect

This commit is contained in:
Alexey Kudravtsev
2017-05-25 17:52:20 +03:00
parent b2f3dd449b
commit 557b56b398
6 changed files with 27 additions and 24 deletions
@@ -372,13 +372,14 @@ public class DebuggerManagerImpl extends DebuggerManagerEx implements Persistent
throw new ExecutionException(DebuggerBundle.message("error.jdk.not.specified"));
}
final JavaSdkVersion version = JavaSdk.getInstance().getVersion(jdk);
String versionString = jdk.getVersionString();
if (version == JavaSdkVersion.JDK_1_0 || version == JavaSdkVersion.JDK_1_1) {
String versionString = jdk.getVersionString();
throw new ExecutionException(DebuggerBundle.message("error.unsupported.jdk.version", versionString));
}
if (SystemInfo.isWindows && version == JavaSdkVersion.JDK_1_2) {
final VirtualFile homeDirectory = jdk.getHomeDirectory();
if (homeDirectory == null || !homeDirectory.isValid()) {
String versionString = jdk.getVersionString();
throw new ExecutionException(DebuggerBundle.message("error.invalid.jdk.home", versionString));
}
//noinspection HardCodedStringLiteral
@@ -70,8 +70,7 @@ public class JavaSdkUtil {
private static boolean isJdkSupportsLevel(@Nullable final Sdk jdk, @NotNull LanguageLevel level) {
if (jdk == null) return true;
String versionString = jdk.getVersionString();
JavaSdkVersion version = versionString == null ? null : JavaSdkVersion.fromVersionString(versionString);
JavaSdkVersion version = JavaSdkVersionUtil.getJavaSdkVersion(jdk);
return version != null && version.getMaxLanguageLevel().isAtLeast(level);
}
@@ -87,10 +87,11 @@ public class JavaSdkImpl extends JavaSdk {
final VirtualFile file = event.getFile();
if (FileTypes.ARCHIVE.equals(fileTypeManager.getFileTypeByFileName(event.getFileName()))) {
final String filePath = file.getPath();
synchronized (myCachedVersionStrings) {
for (String sdkHome : myCachedVersionStrings.keySet()) {
synchronized (myCachedSdkHomeToVersionString) {
for (String sdkHome : myCachedSdkHomeToVersionString.keySet()) {
if (FileUtil.isAncestor(sdkHome, filePath, false)) {
myCachedVersionStrings.remove(sdkHome);
myCachedSdkHomeToVersionString.remove(sdkHome);
myCachedVersionStringToJavaVersion.clear();
break;
}
}
@@ -324,15 +325,16 @@ public class JavaSdkImpl extends JavaSdk {
modificator.addRoot(root, annoType);
}
private final Map<String, String> myCachedVersionStrings = Collections.synchronizedMap(new HashMap<String, String>());
private final Map<String, String> myCachedSdkHomeToVersionString = Collections.synchronizedMap(new HashMap<>());
private final Map<String, JavaSdkVersion> myCachedVersionStringToJavaVersion = Collections.synchronizedMap(new HashMap<>());
@Override
public final String getVersionString(String sdkHome) {
String versionString = myCachedVersionStrings.get(sdkHome);
String versionString = myCachedSdkHomeToVersionString.get(sdkHome);
if (versionString == null) {
versionString = SdkVersionUtil.detectJdkVersion(sdkHome);
if (!StringUtil.isEmpty(versionString)) {
myCachedVersionStrings.put(sdkHome, versionString);
myCachedSdkHomeToVersionString.put(sdkHome, versionString);
}
}
return versionString;
@@ -340,9 +342,9 @@ public class JavaSdkImpl extends JavaSdk {
@Override
public JavaSdkVersion getVersion(@NotNull Sdk sdk) {
String version = sdk.getVersionString();
if (version == null) return null;
return JavaSdkVersion.fromVersionString(version);
String versionString = sdk.getVersionString();
return versionString == null ? null :
myCachedVersionStringToJavaVersion.computeIfAbsent(versionString, JavaSdkVersion::fromVersionString);
}
@Override
@@ -17,7 +17,7 @@ package com.intellij.openapi.projectRoots;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings("unused")
@Deprecated
public class JdkVersionUtil {
/** @deprecated use {@link JavaSdkVersion#fromVersionString(String)} (to be removed in IDEA 2018) */
public static JavaSdkVersion getVersion(@NotNull String versionString) {
@@ -20,6 +20,7 @@ import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class JavaSdkVersionUtil {
public static boolean isAtLeast(@NotNull PsiElement element, @NotNull JavaSdkVersion minVersion) {
@@ -29,13 +30,15 @@ public class JavaSdkVersionUtil {
public static JavaSdkVersion getJavaSdkVersion(@NotNull PsiElement element) {
final Module module = ModuleUtilCore.findModuleForPsiElement(element);
JavaSdkVersion version = null;
if (module != null) {
final Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
if (sdk != null && sdk.getSdkType() instanceof JavaSdk) {
String version = sdk.getVersionString();
return version == null ? null : JavaSdkVersion.fromVersionString(version);
}
version = getJavaSdkVersion(sdk);
}
return null;
return version;
}
public static JavaSdkVersion getJavaSdkVersion(@Nullable Sdk sdk) {
return sdk != null && sdk.getSdkType() instanceof JavaSdk ? ((JavaSdk)sdk.getSdkType()).getVersion(sdk) : null;
}
}
@@ -7,6 +7,7 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.JavaSdkVersionUtil;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.libraries.LibraryUtil;
@@ -221,12 +222,9 @@ public class SceneBuilderImpl implements SceneBuilder {
jdk = ProjectRootManager.getInstance(project).getProjectSdk();
}
if (jdk == null) return true;
final String versionString = jdk.getVersionString();
if (versionString != null) {
final JavaSdkVersion jdkVersion = JavaSdkVersion.fromVersionString(versionString);
if (jdkVersion != null) {
return targetLevel.isAtLeast(jdkVersion.getMaxLanguageLevel());
}
final JavaSdkVersion jdkVersion = JavaSdkVersionUtil.getJavaSdkVersion(jdk);
if (jdkVersion != null) {
return targetLevel.isAtLeast(jdkVersion.getMaxLanguageLevel());
}
return true;
}