diff options
Diffstat (limited to 'platform/util/src/com')
19 files changed, 248 insertions, 150 deletions
diff --git a/platform/util/src/com/intellij/icons/AllIcons.java b/platform/util/src/com/intellij/icons/AllIcons.java index be3f4f212072..318895db57f1 100644 --- a/platform/util/src/com/intellij/icons/AllIcons.java +++ b/platform/util/src/com/intellij/icons/AllIcons.java @@ -76,6 +76,7 @@ public class AllIcons { public static final Icon Get = IconLoader.getIcon("/actions/get.png"); // 16x16 public static final Icon GroupByFile = IconLoader.getIcon("/actions/GroupByFile.png"); // 16x16 public static final Icon GroupByMethod = IconLoader.getIcon("/actions/groupByMethod.png"); // 16x16 + public static final Icon GroupByClass = IconLoader.getIcon("/actions/GroupByClass.png"); // 16x16 public static final Icon GroupByModule = IconLoader.getIcon("/actions/GroupByModule.png"); // 16x16 public static final Icon GroupByModuleGroup = IconLoader.getIcon("/actions/GroupByModuleGroup.png"); // 16x16 public static final Icon GroupByPackage = IconLoader.getIcon("/actions/GroupByPackage.png"); // 16x16 diff --git a/platform/util/src/com/intellij/openapi/diagnostic/Log.java b/platform/util/src/com/intellij/openapi/diagnostic/Log.java index dfc00ae9b4c6..842a8356f591 100644 --- a/platform/util/src/com/intellij/openapi/diagnostic/Log.java +++ b/platform/util/src/com/intellij/openapi/diagnostic/Log.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,13 +15,11 @@ */ package com.intellij.openapi.diagnostic; - import java.util.ArrayList; import java.util.List; -/** - * This is a very primitive fast logging class, primary for race-conditions debugging. - */ +/** @deprecated use {@link com.intellij.openapi.diagnostic.Logger} (to be removed in IDEA 15) */ +@SuppressWarnings("unused") public class Log { private static final List<String> myStrings = new ArrayList<String>(); private static final List<Throwable> myThrowables = new ArrayList<Throwable>(); diff --git a/platform/util/src/com/intellij/openapi/progress/ProcessCanceledException.java b/platform/util/src/com/intellij/openapi/progress/ProcessCanceledException.java index e3029934b2e5..e6133b255411 100644 --- a/platform/util/src/com/intellij/openapi/progress/ProcessCanceledException.java +++ b/platform/util/src/com/intellij/openapi/progress/ProcessCanceledException.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,10 +18,9 @@ package com.intellij.openapi.progress; import com.intellij.util.SystemProperties; public class ProcessCanceledException extends RuntimeException { - private static boolean ourHasStackTraces = SystemProperties.getBooleanProperty("idea.is.internal", false); + private static final boolean ourHasStackTraces = SystemProperties.getBooleanProperty("idea.is.internal", false); public ProcessCanceledException() { - int i = 0; } public ProcessCanceledException(Throwable cause) { diff --git a/platform/util/src/com/intellij/openapi/util/TextRange.java b/platform/util/src/com/intellij/openapi/util/TextRange.java index 797bc23ee747..4c09b969a570 100644 --- a/platform/util/src/com/intellij/openapi/util/TextRange.java +++ b/platform/util/src/com/intellij/openapi/util/TextRange.java @@ -99,6 +99,16 @@ public class TextRange implements Segment, Serializable { } @NotNull + public CharSequence subSequence(@NotNull CharSequence str) { + try { + return str.subSequence(myStartOffset, myEndOffset); + } + catch (IndexOutOfBoundsException e) { + throw new IndexOutOfBoundsException("Can't extract " + this + " range from " + str); + } + } + + @NotNull public TextRange cutOut(@NotNull TextRange subRange) { assert subRange.getStartOffset() <= getLength() : subRange + "; this="+this; assert subRange.getEndOffset() <= getLength() : subRange + "; this="+this; diff --git a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java index cfcbe7967d35..adec13d20412 100644 --- a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java +++ b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java @@ -1264,10 +1264,10 @@ public class FileUtil extends FileUtilRt { if (path == null) return null; if (SystemInfo.isUnix || !unixOnly) { - final File projectDir = new File(path); - final File userHomeDir = new File(SystemProperties.getUserHome()); + File projectDir = new File(path); + File userHomeDir = new File(SystemProperties.getUserHome()); if (isAncestor(userHomeDir, projectDir, true)) { - return "~/" + getRelativePath(userHomeDir, projectDir); + return '~' + File.separator + getRelativePath(userHomeDir, projectDir); } } diff --git a/platform/util/src/com/intellij/openapi/util/registry/Registry.java b/platform/util/src/com/intellij/openapi/util/registry/Registry.java index e418e553fb6b..d41ea08161b3 100644 --- a/platform/util/src/com/intellij/openapi/util/registry/Registry.java +++ b/platform/util/src/com/intellij/openapi/util/registry/Registry.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package com.intellij.openapi.util.registry; import com.intellij.util.containers.HashMap; import org.jdom.Element; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.PropertyKey; import java.awt.*; @@ -33,30 +34,29 @@ public class Registry { @NonNls private static final String REGISTRY_BUNDLE = "misc.registry"; - private final LinkedHashMap<String, String> myUserProperties = new LinkedHashMap<String, String>(); + private final Map<String, String> myUserProperties = new LinkedHashMap<String, String>(); private final Map<String, String> myLoadedUserProperties = new HashMap<String, String>(); private final Map<String, RegistryValue> myValues = new ConcurrentHashMap<String, RegistryValue>(); private static final Registry ourInstance = new Registry(); - public static RegistryValue get(@PropertyKey(resourceBundle = REGISTRY_BUNDLE) String key) { + @NotNull + public static RegistryValue get(@PropertyKey(resourceBundle = REGISTRY_BUNDLE) @NotNull String key) { final Registry registry = getInstance(); - if (registry.myValues.containsKey(key)) { - return registry.myValues.get(key); - } - else { - final RegistryValue value = new RegistryValue(registry, key); + RegistryValue value = registry.myValues.get(key); + if (value == null) { + value = new RegistryValue(registry, key); registry.myValues.put(key, value); - return value; } + return value; } - public static boolean is(@PropertyKey(resourceBundle = REGISTRY_BUNDLE) String key) { + public static boolean is(@PropertyKey(resourceBundle = REGISTRY_BUNDLE) @NotNull String key) throws MissingResourceException { return get(key).asBoolean(); } - public static boolean is(@PropertyKey(resourceBundle = REGISTRY_BUNDLE) String key, boolean defaultValue) { + public static boolean is(@PropertyKey(resourceBundle = REGISTRY_BUNDLE) @NotNull String key, boolean defaultValue) { try { return get(key).asBoolean(); } @@ -65,11 +65,11 @@ public class Registry { } } - public static int intValue(@PropertyKey(resourceBundle = REGISTRY_BUNDLE) String key) { + public static int intValue(@PropertyKey(resourceBundle = REGISTRY_BUNDLE) @NotNull String key) throws MissingResourceException { return get(key).asInteger(); } - public static int intValue(@PropertyKey(resourceBundle = REGISTRY_BUNDLE) String key, int defaultValue) { + public static int intValue(@PropertyKey(resourceBundle = REGISTRY_BUNDLE) @NotNull String key, int defaultValue) { try { return get(key).asInteger(); } @@ -78,18 +78,20 @@ public class Registry { } } - public static double doubleValue(@PropertyKey(resourceBundle = REGISTRY_BUNDLE) String key) { + public static double doubleValue(@PropertyKey(resourceBundle = REGISTRY_BUNDLE) @NotNull String key) throws MissingResourceException { return get(key).asDouble(); } - public static String stringValue(@PropertyKey(resourceBundle = REGISTRY_BUNDLE) String key) { + @NotNull + public static String stringValue(@PropertyKey(resourceBundle = REGISTRY_BUNDLE) @NotNull String key) throws MissingResourceException { return get(key).asString(); } - public static Color getColor(@PropertyKey(resourceBundle = REGISTRY_BUNDLE) String key, Color defaultValue) { + public static Color getColor(@PropertyKey(resourceBundle = REGISTRY_BUNDLE) @NotNull String key, Color defaultValue) throws MissingResourceException { return get(key).asColor(defaultValue); } + @NotNull static ResourceBundle getBundle() { ResourceBundle bundle = com.intellij.reference.SoftReference.dereference(ourBundle); if (bundle == null) { @@ -104,6 +106,7 @@ public class Registry { return ourInstance; } + @NotNull public Element getState() { final Element state = new Element("registry"); for (String eachKey : myUserProperties.keySet()) { @@ -115,7 +118,7 @@ public class Registry { return state; } - public void loadState(Element state) { + public void loadState(@NotNull Element state) { final List entries = state.getChildren("entry"); for (Object each : entries) { final Element eachEntry = (Element) each; @@ -132,15 +135,17 @@ public class Registry { } } + @NotNull Map<String, String> getUserProperties() { return myUserProperties; } + @NotNull public static List<RegistryValue> getAll() { final ResourceBundle bundle = getBundle(); final Enumeration<String> keys = bundle.getKeys(); - final ArrayList<RegistryValue> result = new ArrayList<RegistryValue>(); + List<RegistryValue> result = new ArrayList<RegistryValue>(); while (keys.hasMoreElements()) { final String each = keys.nextElement(); @@ -152,7 +157,7 @@ public class Registry { } public void restoreDefaults() { - final HashMap<String, String> old = new HashMap<String, String>(); + Map<String, String> old = new HashMap<String, String>(); old.putAll(myUserProperties); for (String each : old.keySet()) { get(each).resetToDefault(); @@ -167,7 +172,7 @@ public class Registry { return isRestartNeeded(myUserProperties) || isRestartNeeded(myLoadedUserProperties); } - private static boolean isRestartNeeded(Map<String, String> map) { + private static boolean isRestartNeeded(@NotNull Map<String, String> map) { for (String s : map.keySet()) { final RegistryValue eachValue = get(s); if (eachValue.isRestartRequired() && eachValue.isChangedSinceAppStart()) return true; diff --git a/platform/util/src/com/intellij/openapi/util/registry/RegistryValue.java b/platform/util/src/com/intellij/openapi/util/registry/RegistryValue.java index 6c89311457f4..ae3873b8744f 100644 --- a/platform/util/src/com/intellij/openapi/util/registry/RegistryValue.java +++ b/platform/util/src/com/intellij/openapi/util/registry/RegistryValue.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,16 +42,18 @@ public class RegistryValue { private Double myDoubleCachedValue; private Boolean myBooleanCachedValue; - RegistryValue(Registry registry, String key) { + RegistryValue(@NotNull Registry registry, @NotNull String key) { myRegistry = registry; myKey = key; } + @NotNull public String getKey() { return myKey; } + @NotNull public String asString() { final String value = get(myKey, null, true); assert value != null : myKey; @@ -97,6 +99,7 @@ public class RegistryValue { return defaultValue; } + @NotNull public String getDescription() { return get(myKey + ".description", "", false); } @@ -109,42 +112,36 @@ public class RegistryValue { return !asString().equals(getBundleValue(myKey, false)); } - private String get(String key, String defaultValue, boolean isValue) { + private String get(@NotNull String key, String defaultValue, boolean isValue) throws MissingResourceException { if (isValue) { if (myStringCachedValue == null) { myStringCachedValue = _get(key, defaultValue, isValue); - } - if (isBoolean()) { - myStringCachedValue = Boolean.valueOf(myStringCachedValue).toString(); + if (isBoolean()) { + myStringCachedValue = Boolean.valueOf(myStringCachedValue).toString(); + } } return myStringCachedValue; } - else { - return _get(key, defaultValue, isValue); - } + return _get(key, defaultValue, isValue); } - private String _get(String key, String defaultValue, boolean mustExistInBundle) { + private String _get(@NotNull String key, String defaultValue, boolean mustExistInBundle) throws MissingResourceException { final String userValue = myRegistry.getUserProperties().get(key); - if (userValue == null) { - String systemProperty = System.getProperty(key); - if (systemProperty != null) { - return systemProperty; - } - final String bundleValue = getBundleValue(key, mustExistInBundle); - if (bundleValue != null) { - return bundleValue; - } - else { - return defaultValue; - } - } - else { + if (userValue != null) { return userValue; } + String systemProperty = System.getProperty(key); + if (systemProperty != null) { + return systemProperty; + } + final String bundleValue = getBundleValue(key, mustExistInBundle); + if (bundleValue != null) { + return bundleValue; + } + return defaultValue; } - private String getBundleValue(String key, boolean mustExist) { + private static String getBundleValue(@NotNull String key, boolean mustExist) throws MissingResourceException { try { return Registry.getBundle().getString(key); } diff --git a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java index bc37f673bb03..e364a8568fda 100644 --- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java +++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java @@ -1331,6 +1331,7 @@ public class StringUtil extends StringUtilRt { } public static boolean isQuotedString(@NotNull String text) { + if (text.length() < 2) return false; return startsWithChar(text, '\"') && endsWithChar(text, '\"') || startsWithChar(text, '\'') && endsWithChar(text, '\''); } @@ -2678,7 +2679,7 @@ public class StringUtil extends StringUtilRt { continue; } - if (i > 0 && (ch == '/' || ch == '\\' || ch == '.' || Character.isUpperCase(ch))) { + if (i > 0 && (ch == '/' || ch == '\\' || ch == '.' || ch == '-' || Character.isUpperCase(ch))) { words.add(builder.toString()); builder.delete(0, builder.length()); } diff --git a/platform/util/src/com/intellij/util/ReflectionUtil.java b/platform/util/src/com/intellij/util/ReflectionUtil.java index df33a80d4cba..d5f6a58dc951 100644 --- a/platform/util/src/com/intellij/util/ReflectionUtil.java +++ b/platform/util/src/com/intellij/util/ReflectionUtil.java @@ -95,6 +95,7 @@ public class ReflectionUtil { + " loaded by " + ((Class)anInterface).getClassLoader(); } + @NotNull public static Class<?> getRawType(@NotNull Type type) { if (type instanceof Class) { return (Class)type; @@ -288,15 +289,18 @@ public class ReflectionUtil { }); } + @NotNull public static List<Method> getClassPublicMethods(@NotNull Class aClass) { return getClassPublicMethods(aClass, false); } - + + @NotNull public static List<Method> getClassPublicMethods(@NotNull Class aClass, boolean includeSynthetic) { Method[] methods = aClass.getMethods(); return includeSynthetic ? Arrays.asList(methods) : filterRealMethods(methods); } + @NotNull public static List<Method> getClassDeclaredMethods(@NotNull Class aClass) { return getClassDeclaredMethods(aClass, false); } @@ -306,13 +310,15 @@ public class ReflectionUtil { Method[] methods = aClass.getDeclaredMethods(); return includeSynthetic ? Arrays.asList(methods) : filterRealMethods(methods); } + @NotNull public static List<Field> getClassDeclaredFields(@NotNull Class aClass) { Field[] fields = aClass.getDeclaredFields(); return Arrays.asList(fields); } - private static List<Method> filterRealMethods(Method[] methods) { + @NotNull + private static List<Method> filterRealMethods(@NotNull Method[] methods) { List<Method> result = ContainerUtil.newArrayList(); for (Method method : methods) { if (!method.isSynthetic()) { @@ -323,8 +329,8 @@ public class ReflectionUtil { } @Nullable - public static Class getMethodDeclaringClass(@NotNull Class<?> instanceClass, @NonNls @NotNull String name, @NotNull Class... parameters) { - Method method = getMethod(instanceClass, name, parameters); + public static Class getMethodDeclaringClass(@NotNull Class<?> instanceClass, @NonNls @NotNull String methodName, @NotNull Class... parameters) { + Method method = getMethod(instanceClass, methodName, parameters); return method == null ? null : method.getDeclaringClass(); } diff --git a/platform/util/src/com/intellij/util/containers/ClassMap.java b/platform/util/src/com/intellij/util/containers/ClassMap.java index 078dfd693e63..d2d3bbb3e6dc 100644 --- a/platform/util/src/com/intellij/util/containers/ClassMap.java +++ b/platform/util/src/com/intellij/util/containers/ClassMap.java @@ -16,6 +16,7 @@ package com.intellij.util.containers; import gnu.trove.THashMap; +import org.jetbrains.annotations.NotNull; import java.util.Collection; import java.util.Map; @@ -29,18 +30,18 @@ public class ClassMap<T> { public ClassMap() { this(new THashMap<Class, T>()); } - protected ClassMap(Map<Class, T> map) { + protected ClassMap(@NotNull Map<Class, T> map) { myMap = map; } - public void put(Class aClass, T value) { + public void put(@NotNull Class aClass, T value) { myMap.put(aClass, value); } - public void remove(Class aClass) { + public void remove(@NotNull Class aClass) { myMap.remove(aClass); } - public T get(Class aClass) { + public T get(@NotNull Class aClass) { T t = myMap.get(aClass); if (t != null) { return t; @@ -63,6 +64,7 @@ public class ClassMap<T> { return null; } + @NotNull public final Collection<T> values() { return myMap.values(); } diff --git a/platform/util/src/com/intellij/util/containers/ContainerUtil.java b/platform/util/src/com/intellij/util/containers/ContainerUtil.java index 171cfababfa9..dca7a0e6b30d 100644 --- a/platform/util/src/com/intellij/util/containers/ContainerUtil.java +++ b/platform/util/src/com/intellij/util/containers/ContainerUtil.java @@ -1113,6 +1113,10 @@ public class ContainerUtil extends ContainerUtilRt { */ @NotNull public static <T> List<T> concat(@NotNull final List<? extends T> list1, @NotNull final List<? extends T> list2) { + if (list1.isEmpty() && list2.isEmpty()) { + return Collections.emptyList(); + } + final int size1 = list1.size(); final int size = size1 + list2.size(); diff --git a/platform/util/src/com/intellij/util/containers/TransferToEDTQueue.java b/platform/util/src/com/intellij/util/containers/TransferToEDTQueue.java index 787ebc320490..5db4de22b401 100644 --- a/platform/util/src/com/intellij/util/containers/TransferToEDTQueue.java +++ b/platform/util/src/com/intellij/util/containers/TransferToEDTQueue.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -147,6 +147,12 @@ public class TransferToEDTQueue<T> { } } + public int size() { + synchronized (myQueue) { + return myQueue.size(); + } + } + // process all queue in current thread public void drain() { int processed = 0; diff --git a/platform/util/src/com/intellij/util/containers/WeakStringInterner.java b/platform/util/src/com/intellij/util/containers/WeakStringInterner.java index ec223a8c6880..eb1c7b329f76 100644 --- a/platform/util/src/com/intellij/util/containers/WeakStringInterner.java +++ b/platform/util/src/com/intellij/util/containers/WeakStringInterner.java @@ -16,26 +16,27 @@ package com.intellij.util.containers; import com.intellij.reference.SoftReference; +import com.intellij.util.ConcurrencyUtil; import org.jetbrains.annotations.NotNull; import java.lang.ref.WeakReference; -import java.util.*; import java.util.HashSet; +import java.util.Set; /** * @author peter */ public class WeakStringInterner extends StringInterner { - private final WeakHashMap<String, WeakReference<String>> myMap = new WeakHashMap<String, WeakReference<String>>(); + private final ConcurrentWeakHashMap<String, WeakReference<String>> myMap = new ConcurrentWeakHashMap<String, WeakReference<String>>(); @NotNull @Override public String intern(@NotNull String name) { - String interned = SoftReference.dereference(myMap.get(name)); - if (interned != null) { - return interned; - } - myMap.put(name, new WeakReference<String>(name)); + WeakReference<String> key = new WeakReference<String>(name); + String interned = SoftReference.dereference(ConcurrencyUtil.cacheOrGet(myMap, name, key)); + if (interned != null) return interned; + + myMap.put(name, key); return name; } diff --git a/platform/util/src/com/intellij/util/io/IntToIntBtree.java b/platform/util/src/com/intellij/util/io/IntToIntBtree.java index b17fc6cc5c6c..475f3cb67a94 100644 --- a/platform/util/src/com/intellij/util/io/IntToIntBtree.java +++ b/platform/util/src/com/intellij/util/io/IntToIntBtree.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,7 @@ import java.util.Arrays; * Date: 7/12/11 * Time: 1:34 PM */ -class IntToIntBtree { +public class IntToIntBtree { public static int version() { return 4 + (IOUtil.ourByteBuffersUseNativeByteOrder ? 0xFF : 0); } @@ -55,10 +55,10 @@ class IntToIntBtree { private boolean hasZeroKey; private int zeroKeyValue; - private boolean isLarge = true; + private final boolean isLarge = true; private final ResizeableMappedFile storage; private final boolean offloadToSiblingsBeforeSplit = false; - private boolean indexNodeIsHashTable = true; + private final boolean indexNodeIsHashTable = true; final int metaDataLeafPageLength; final int hashPageCapacity; @@ -66,8 +66,8 @@ class IntToIntBtree { private TIntIntHashMap myCachedMappings; private final int myCachedMappingsSize; - public IntToIntBtree(int _pageSize, File file, PagedFileStorage.StorageLockContext storageLockContext, boolean initial) throws IOException { - pageSize = _pageSize; + public IntToIntBtree(int pageSize, @NotNull File file, @NotNull PagedFileStorage.StorageLockContext storageLockContext, boolean initial) throws IOException { + this.pageSize = pageSize; if (initial) { FileUtil.delete(file); @@ -82,13 +82,12 @@ class IntToIntBtree { root.setIndexLeaf(true); } - int i = (pageSize - BtreePage.RESERVED_META_PAGE_LEN) / BtreeIndexNodeView.INTERIOR_SIZE - 1; + int i = (this.pageSize - BtreePage.RESERVED_META_PAGE_LEN) / BtreeIndexNodeView.INTERIOR_SIZE - 1; assert i < Short.MAX_VALUE && i % 2 == 0; maxInteriorNodes = (short)i; maxLeafNodes = (short)i; - int metaPageLen = BtreePage.RESERVED_META_PAGE_LEN; - + int metaPageLen; if (indexNodeIsHashTable) { ++i; while(!isPrime(i)) i -= 2; @@ -97,8 +96,10 @@ class IntToIntBtree { metaPageLen = BtreePage.RESERVED_META_PAGE_LEN; i = (int)(hashPageCapacity * 0.9); if ((i & 1) == 1) ++i; - } else { + } + else { hashPageCapacity = -1; + metaPageLen = BtreePage.RESERVED_META_PAGE_LEN; } metaDataLeafPageLength = metaPageLen; @@ -108,20 +109,18 @@ class IntToIntBtree { if (hasCachedMappings) { myCachedMappings = new TIntIntHashMap(myCachedMappingsSize = 4 * maxLeafNodes); - } else { + } + else { myCachedMappings = null; myCachedMappingsSize = -1; } } - public void persistVars(BtreeDataStorage storage, boolean toDisk) { - if (toDisk) { - storage.persistInt(0, height | (hasZeroKey ? HAS_ZERO_KEY_MASK :0), true); - } else { - int i = storage.persistInt(0, 0, false); - hasZeroKey = (i & HAS_ZERO_KEY_MASK) != 0; - height = i & ~HAS_ZERO_KEY_MASK; - } + // return total number of bytes needed for storing information + public int persistVars(@NotNull BtreeDataStorage storage, boolean toDisk) { + int i = storage.persistInt(0, height | (hasZeroKey ? HAS_ZERO_KEY_MASK :0), toDisk); + hasZeroKey = (i & HAS_ZERO_KEY_MASK) != 0; + height = i & ~HAS_ZERO_KEY_MASK; pagesCount = storage.persistInt(4, pagesCount, toDisk); movedMembersCount = storage.persistInt(8, movedMembersCount, toDisk); @@ -132,9 +131,10 @@ class IntToIntBtree { hashedPagesCount = storage.persistInt(28, hashedPagesCount, toDisk); root.setAddress(storage.persistInt(32, root.address, toDisk)); zeroKeyValue = storage.persistInt(36, zeroKeyValue, toDisk); + return 40; } - interface BtreeDataStorage { + public interface BtreeDataStorage { int persistInt(int offset, int value, boolean toDisk); } @@ -155,10 +155,11 @@ class IntToIntBtree { } private BtreeIndexNodeView myAccessNodeView; - private int myLastGetKey, myOptimizedInserts; + private int myLastGetKey; + private int myOptimizedInserts; private boolean myCanUseLastKey; - public boolean get(int key, int[] result) { + public boolean get(int key, @NotNull int[] result) { if (key == 0) { if (hasZeroKey) { result[0] = zeroKeyValue; @@ -199,7 +200,8 @@ class IntToIntBtree { if (hasCachedMappings) { myCachedMappings.put(key, value); if (myCachedMappings.size() == myCachedMappingsSize) flushCachedMappings(); - } else { + } + else { boolean canUseLastKey = myCanUseLastKey; if (canUseLastKey) { myCanUseLastKey = false; @@ -256,12 +258,12 @@ class IntToIntBtree { } } - void doClose() throws IOException { + public void doClose() throws IOException { myCachedMappings = null; storage.close(); } - void doFlush() { + public void doFlush() { flushCachedMappings(); storage.force(); } @@ -445,11 +447,11 @@ class IntToIntBtree { putInt(offset, value); } - private final int indexToOffset(int i) { + private int indexToOffset(int i) { return i * INTERIOR_SIZE + (isHashedLeaf() ? btree.metaDataLeafPageLength:RESERVED_META_PAGE_LEN); } - private final int keyAt(int i) { + private int keyAt(int i) { if (doSanityCheck) { if (isHashedLeaf()) myAssert(i < btree.hashPageCapacity); else myAssert(i < getChildrenCount()); @@ -495,7 +497,7 @@ class IntToIntBtree { setFlag(INDEX_LEAF_MASK, value); } - private final boolean isHashedLeaf() { + private boolean isHashedLeaf() { return isHashedLeaf; } @@ -608,7 +610,8 @@ class IntToIntBtree { if (hashedLeaf) { hashLeafData = new HashLeafData(this, recordCount); if (doOffloadToSiblingsWhenHashed(parent, hashLeafData)) return parentAddress; - } else { + } + else { if (doOffloadToSiblingsSorted(parent)) return parentAddress; } } @@ -1074,16 +1077,14 @@ class IntToIntBtree { private static final boolean useDoubleHash = true; private int hashIndex(int value) { - int hash, index; - final int length = btree.hashPageCapacity; - hash = value & 0x7fffffff; - index = hash % length; + int hash = value & 0x7fffffff; + int index = hash % length; int keyAtIndex = keyAt(index); - int total = 0; btree.hashSearchRequests++; + int total = 0; if (useDoubleHash) { if (keyAtIndex != value && keyAtIndex != HASH_FREE) { // see Knuth, p. 529 @@ -1148,11 +1149,21 @@ class IntToIntBtree { if (childrenAddresses.length > 0) { BtreeIndexNodeView child = new BtreeIndexNodeView(this); - for(int i = 0; i < childrenAddresses.length; ++i) { - child.setAddress(childrenAddresses[i]); - if (!processLeafPages(child, processor)) return false; + for (int childrenAddress : childrenAddresses) { + child.setAddress(childrenAddress); + if (!processLeafPages(child, processor)) return false; } } return true; } + + public void withStorageLock(@NotNull Runnable runnable) { + storage.getPagedFileStorage().lock(); + try { + runnable.run(); + } + finally { + storage.getPagedFileStorage().unlock(); + } + } } diff --git a/platform/util/src/com/intellij/util/io/PagedFileStorage.java b/platform/util/src/com/intellij/util/io/PagedFileStorage.java index 69315f1b3764..1fca8e063394 100644 --- a/platform/util/src/com/intellij/util/io/PagedFileStorage.java +++ b/platform/util/src/com/intellij/util/io/PagedFileStorage.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -88,11 +88,11 @@ public class PagedFileStorage implements Forceable { private static final ByteOrder ourNativeByteOrder = ByteOrder.nativeOrder(); public void lock() { - myStorageLockContext.myLock.lock(); + myStorageLockContext.lock(); } public void unlock() { - myStorageLockContext.myLock.unlock(); + myStorageLockContext.unlock(); } public StorageLockContext getStorageLockContext() { @@ -510,11 +510,11 @@ public class PagedFileStorage implements Forceable { } public void lock() { - myDefaultStorageLockContext.myLock.lock(); + myDefaultStorageLockContext.lock(); } public void unlock() { - myDefaultStorageLockContext.myLock.unlock(); + myDefaultStorageLockContext.unlock(); } private int registerPagedFileStorage(@NotNull PagedFileStorage storage) { @@ -658,7 +658,9 @@ public class PagedFileStorage implements Forceable { LOG.info("Max memory:"+maxMemory.get(null) + ", reserved memory:" + reservedMemory.get(null)); } } - catch (Throwable t) {} + catch (Throwable t) { + + } throw new MappingFailedException( "Cannot recover from OOME in memory mapping: -Xmx=" + Runtime.getRuntime().maxMemory() / MB + "MB " + "new size limit: " + mySizeLimit / MB + "MB " + @@ -669,7 +671,7 @@ public class PagedFileStorage implements Forceable { } } - private void checkThreadAccess(StorageLockContext storageLockContext) { + private static void checkThreadAccess(StorageLockContext storageLockContext) { if (storageLockContext.myCheckThreadAccess && !storageLockContext.myLock.isHeldByCurrentThread()) { throw new IllegalStateException("Must hold StorageLock lock to access PagedFileStorage"); } @@ -776,5 +778,12 @@ public class PagedFileStorage implements Forceable { public StorageLockContext(boolean checkAccess) { this(ourLock, checkAccess); } + + public void lock() { + myLock.lock(); + } + public void unlock() { + myLock.unlock(); + } } } diff --git a/platform/util/src/com/intellij/util/io/RandomAccessDataFile.java b/platform/util/src/com/intellij/util/io/RandomAccessDataFile.java index 9a297bcef6d1..d4383a55d03e 100644 --- a/platform/util/src/com/intellij/util/io/RandomAccessDataFile.java +++ b/platform/util/src/com/intellij/util/io/RandomAccessDataFile.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,11 +47,11 @@ public class RandomAccessDataFile implements Forceable, Closeable { private static final boolean DEBUG = false; - public RandomAccessDataFile(final File file) throws IOException { + public RandomAccessDataFile(@NotNull File file) throws IOException { this(file, PagePool.SHARED); } - public RandomAccessDataFile(final File file, final PagePool pool) throws IOException { + public RandomAccessDataFile(@NotNull File file, @NotNull PagePool pool) throws IOException { myPool = pool; myFile = file; if (!file.exists()) { @@ -201,6 +201,9 @@ public class RandomAccessDataFile implements Forceable, Closeable { dispose(); } + /** + * Flushes dirty pages to underlying buffers + */ @Override public void force() { assertNotDisposed(); @@ -210,6 +213,23 @@ public class RandomAccessDataFile implements Forceable, Closeable { } } + /** + * Flushes dirty pages to buffers and saves them to disk + */ + public void sync() { + force(); + try { + RandomAccessFile file = getRandomAccessFile(); + file.getChannel().force(true); + } + catch (IOException ignored) { + + } + finally { + releaseFile(); + } + } + public void flushSomePages(int maxPagesToFlush) { assertNotDisposed(); if (isDirty()) { @@ -229,7 +249,7 @@ public class RandomAccessDataFile implements Forceable, Closeable { private void assertNotDisposed() { if (myIsDisposed) { - LOG.assertTrue(false, "storage file is disposed: " + myFile); + LOG.error("storage file is disposed: " + myFile); } } @@ -316,6 +336,7 @@ public class RandomAccessDataFile implements Forceable, Closeable { file.seek(fileOffset); } + @Override public int hashCode() { return myCount; } diff --git a/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java b/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java index e0d349c0c7ad..663cd215cfbe 100644 --- a/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java +++ b/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,19 +19,47 @@ */ package com.intellij.util.io.storage; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.util.Disposer; +import com.intellij.util.EventDispatcher; +import org.jetbrains.annotations.NotNull; + +import java.util.EventListener; +import java.util.concurrent.atomic.AtomicInteger; + public class HeavyProcessLatch { public static final HeavyProcessLatch INSTANCE = new HeavyProcessLatch(); - private int myHeavyProcessCounter = 0; - - public synchronized void processStarted() { - myHeavyProcessCounter++; + + private final AtomicInteger myHeavyProcessCounter = new AtomicInteger(); + private final EventDispatcher<HeavyProcessListener> myEventDispatcher = EventDispatcher.create(HeavyProcessListener.class); + + private HeavyProcessLatch() { + } + + public void processStarted() { + myHeavyProcessCounter.incrementAndGet(); + myEventDispatcher.getMulticaster().processStarted(); } - public synchronized void processFinished() { - myHeavyProcessCounter--; + public void processFinished() { + myHeavyProcessCounter.decrementAndGet(); + myEventDispatcher.getMulticaster().processFinished(); + } + + public boolean isRunning() { + return myHeavyProcessCounter.get() != 0; + } + + public interface HeavyProcessListener extends EventListener { + public void processStarted(); + + public void processFinished(); } - public synchronized boolean isRunning() { - return myHeavyProcessCounter != 0; + @NotNull + public Disposable addListener(@NotNull HeavyProcessListener listener) { + Disposable disposable = Disposer.newDisposable(); + myEventDispatcher.addListener(listener, disposable); + return disposable; } }
\ No newline at end of file diff --git a/platform/util/src/com/intellij/util/text/StringSearcher.java b/platform/util/src/com/intellij/util/text/StringSearcher.java index d5bc95f99cef..f9517ad09ade 100644 --- a/platform/util/src/com/intellij/util/text/StringSearcher.java +++ b/platform/util/src/com/intellij/util/text/StringSearcher.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -123,7 +123,7 @@ public class StringSearcher { } } - int step = 0 <= lastChar && lastChar < 128 ? mySearchTable[lastChar] : 1; + int step = lastChar < 128 ? mySearchTable[lastChar] : 1; if (step <= 0) { int index; @@ -160,7 +160,7 @@ public class StringSearcher { if (i < 0) return end - start - myPatternLength + 1; } - int step = 0 <= lastChar && lastChar < 128 ? mySearchTable[lastChar] : 1; + int step = lastChar < 128 ? mySearchTable[lastChar] : 1; if (step <= 0) { int index; diff --git a/platform/util/src/com/intellij/util/xmlb/MapBinding.java b/platform/util/src/com/intellij/util/xmlb/MapBinding.java index 6a8423d2ed4b..dbc3c0e082c3 100644 --- a/platform/util/src/com/intellij/util/xmlb/MapBinding.java +++ b/platform/util/src/com/intellij/util/xmlb/MapBinding.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.util.xmlb; import com.intellij.openapi.util.JDOMUtil; @@ -35,22 +34,22 @@ import java.util.Set; import static com.intellij.util.xmlb.Constants.*; class MapBinding implements Binding { - private final Binding myKeyBinding; - private final Binding myValueBinding; - private final MapAnnotation myMapAnnotation; private static final Comparator<Object> KEY_COMPARATOR = new Comparator<Object>() { + @SuppressWarnings("unchecked") @Override - public int compare(final Object o1, final Object o2) { + public int compare(Object o1, Object o2) { if (o1 instanceof Comparable && o2 instanceof Comparable) { Comparable c1 = (Comparable)o1; Comparable c2 = (Comparable)o2; return c1.compareTo(c2); } - return 0; } }; + private final Binding myKeyBinding; + private final Binding myValueBinding; + private final MapAnnotation myMapAnnotation; public MapBinding(ParameterizedType type, Accessor accessor) { Type[] arguments = type.getActualTypeArguments(); @@ -69,7 +68,7 @@ class MapBinding implements Binding { Element m; if (myMapAnnotation == null || myMapAnnotation.surroundWithTag()) { - m = new Element(Constants.MAP); + m = new Element(MAP); } else { m = (Element)context; @@ -92,14 +91,14 @@ class MapBinding implements Binding { if (kNode instanceof Text) { Text text = (Text)kNode; - entry.setAttribute(getKeyAttributeValue(), text.getText()); + entry.setAttribute(getKeyAttributeName(), text.getText()); } else { if (myMapAnnotation != null && !myMapAnnotation.surroundKeyWithTag()) { entry.addContent((Content)kNode); } else { - Element key = new Element(getKeyAttributeValue()); + Element key = new Element(getKeyAttributeName()); entry.addContent(key); key.addContent((Content)kNode); } @@ -129,12 +128,12 @@ class MapBinding implements Binding { return myMapAnnotation == null ? ENTRY : myMapAnnotation.entryTagName(); } - private String getValueAttributeName() { - return myMapAnnotation == null ? VALUE : myMapAnnotation.valueAttributeName(); + private String getKeyAttributeName() { + return myMapAnnotation == null ? KEY : myMapAnnotation.keyAttributeName(); } - private String getKeyAttributeValue() { - return myMapAnnotation == null ? KEY : myMapAnnotation.keyAttributeName(); + private String getValueAttributeName() { + return myMapAnnotation == null ? VALUE : myMapAnnotation.valueAttributeName(); } @Override @@ -164,7 +163,7 @@ class MapBinding implements Binding { assert entry.getName().equals(getEntryAttributeName()); - Attribute keyAttr = entry.getAttribute(getKeyAttributeValue()); + Attribute keyAttr = entry.getAttribute(getKeyAttributeName()); if (keyAttr != null) { k = myKeyBinding.deserialize(o, keyAttr); } @@ -181,7 +180,7 @@ class MapBinding implements Binding { assert k != null : "no key found"; } else { - final Object keyNode = entry.getChildren(getKeyAttributeValue()).get(0); + final Object keyNode = entry.getChildren(getKeyAttributeName()).get(0); k = myKeyBinding.deserialize(o, JDOMUtil.getContent((Element)keyNode)); } } @@ -223,7 +222,7 @@ class MapBinding implements Binding { return myMapAnnotation.entryTagName().equals(((Element)node).getName()); } - return ((Element)node).getName().equals(Constants.MAP); + return ((Element)node).getName().equals(MAP); } @Override |