summaryrefslogtreecommitdiff
path: root/platform/util
diff options
context:
space:
mode:
Diffstat (limited to 'platform/util')
-rw-r--r--platform/util/src/com/intellij/icons/AllIcons.java1
-rw-r--r--platform/util/src/com/intellij/openapi/ui/VerticalFlowLayout.java4
-rw-r--r--platform/util/src/com/intellij/openapi/util/BuildNumber.java35
-rw-r--r--platform/util/src/com/intellij/openapi/util/IconLoader.java4
-rw-r--r--platform/util/src/com/intellij/openapi/util/io/FileUtil.java13
-rw-r--r--platform/util/src/com/intellij/openapi/util/registry/ui/RegistryCheckBox.java7
-rw-r--r--platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java20
-rw-r--r--platform/util/src/com/intellij/ui/Graphics2DDelegate.java4
-rw-r--r--platform/util/src/com/intellij/util/containers/ContainerUtil.java18
-rw-r--r--platform/util/src/com/intellij/util/containers/OrderedSet.java6
-rw-r--r--platform/util/src/com/intellij/util/io/AbstractStringEnumerator.java8
-rw-r--r--platform/util/src/com/intellij/util/io/AppendableStorageBackedByResizableMappedFile.java4
-rw-r--r--platform/util/src/com/intellij/util/io/CachingEnumerator.java149
-rw-r--r--platform/util/src/com/intellij/util/io/DataEnumerator.java30
-rw-r--r--platform/util/src/com/intellij/util/io/EnumeratorStringDescriptor.java1
-rw-r--r--platform/util/src/com/intellij/util/io/IntToIntBtree.java10
-rw-r--r--platform/util/src/com/intellij/util/io/PagedFileStorage.java30
-rw-r--r--platform/util/src/com/intellij/util/io/PersistentHashMap.java2
-rw-r--r--platform/util/src/com/intellij/util/io/PersistentStringEnumerator.java131
-rw-r--r--platform/util/src/com/intellij/util/ui/ColumnInfo.java14
-rw-r--r--platform/util/src/com/intellij/util/ui/UIUtil.java22
-rw-r--r--platform/util/testSrc/com/intellij/util/containers/ConcurrentMapsTest.java2
22 files changed, 322 insertions, 193 deletions
diff --git a/platform/util/src/com/intellij/icons/AllIcons.java b/platform/util/src/com/intellij/icons/AllIcons.java
index 9d10f4136383..db897fd8c52d 100644
--- a/platform/util/src/com/intellij/icons/AllIcons.java
+++ b/platform/util/src/com/intellij/icons/AllIcons.java
@@ -458,6 +458,7 @@ public class AllIcons {
public static final Icon Pin_tab = IconLoader.getIcon("/general/pin_tab.png"); // 16x16
public static final Icon PluginManager = IconLoader.getIcon("/general/pluginManager.png"); // 32x32
public static final Icon Progress = IconLoader.getIcon("/general/progress.png"); // 8x10
+ public static final Icon ProjectConfigurable = IconLoader.getIcon("/general/projectConfigurable.png"); // 9x9
public static final Icon ProjectSettings = IconLoader.getIcon("/general/projectSettings.png"); // 16x16
public static final Icon ProjectStructure = IconLoader.getIcon("/general/projectStructure.png"); // 16x16
public static final Icon ProjectTab = IconLoader.getIcon("/general/projectTab.png"); // 16x16
diff --git a/platform/util/src/com/intellij/openapi/ui/VerticalFlowLayout.java b/platform/util/src/com/intellij/openapi/ui/VerticalFlowLayout.java
index 884a11711992..43aa9b37b510 100644
--- a/platform/util/src/com/intellij/openapi/ui/VerticalFlowLayout.java
+++ b/platform/util/src/com/intellij/openapi/ui/VerticalFlowLayout.java
@@ -48,6 +48,10 @@ public class VerticalFlowLayout extends FlowLayout implements Serializable {
this(alignment, 5, 5, fillHorizontally, fillVertically);
}
+ public VerticalFlowLayout(int hGap, int vGap) {
+ this(TOP, hGap, vGap, true, false);
+ }
+
public VerticalFlowLayout(@VerticalFlowAlignment int alignment, int hGap, int vGap, boolean fillHorizontally, boolean fillVertically) {
setAlignment(alignment);
this.hGap = hGap;
diff --git a/platform/util/src/com/intellij/openapi/util/BuildNumber.java b/platform/util/src/com/intellij/openapi/util/BuildNumber.java
index a888db7becf9..22cf77504a63 100644
--- a/platform/util/src/com/intellij/openapi/util/BuildNumber.java
+++ b/platform/util/src/com/intellij/openapi/util/BuildNumber.java
@@ -38,22 +38,28 @@ public class BuildNumber implements Comparable<BuildNumber> {
private final String myProductCode;
private final int myBaselineVersion;
private final int myBuildNumber;
+ private final String myAttemptInfo;
public BuildNumber(String productCode, int baselineVersion, int buildNumber) {
+ this(productCode, baselineVersion, buildNumber, null);
+ }
+
+ public BuildNumber(String productCode, int baselineVersion, int buildNumber, String attemptInfo) {
myProductCode = productCode;
myBaselineVersion = baselineVersion;
myBuildNumber = buildNumber;
+ myAttemptInfo = StringUtil.isEmpty(attemptInfo) ? null : attemptInfo;
}
public String asString() {
- return asString(true);
+ return asString(true, false);
}
public String asStringWithoutProductCode() {
- return asString(false);
+ return asString(false, false);
}
- private String asString(boolean includeProductCode) {
+ private String asString(boolean includeProductCode, boolean withBuildAttempt) {
StringBuilder builder = new StringBuilder();
if (includeProductCode && !StringUtil.isEmpty(myProductCode)) {
@@ -69,6 +75,10 @@ public class BuildNumber implements Comparable<BuildNumber> {
builder.append(SNAPSHOT);
}
+ if (withBuildAttempt && myAttemptInfo != null) {
+ builder.append('.').append(myAttemptInfo);
+ }
+
return builder.toString();
}
@@ -98,9 +108,11 @@ public class BuildNumber implements Comparable<BuildNumber> {
int baselineVersionSeparator = code.indexOf('.');
int baselineVersion;
int buildNumber;
+ String attemptInfo = null;
+
if (baselineVersionSeparator > 0) {
try {
- final String baselineVersionString = code.substring(0, baselineVersionSeparator);
+ String baselineVersionString = code.substring(0, baselineVersionSeparator);
if (baselineVersionString.trim().isEmpty()) return null;
baselineVersion = Integer.parseInt(baselineVersionString);
code = code.substring(baselineVersionSeparator + 1);
@@ -109,6 +121,11 @@ public class BuildNumber implements Comparable<BuildNumber> {
throw new RuntimeException("Invalid version number: " + version + "; plugin name: " + name);
}
+ int minorBuildSeparator = code.indexOf('.'); // allow <BuildNumber>.<BuildAttemptNumber> skipping BuildAttemptNumber
+ if (minorBuildSeparator > 0) {
+ attemptInfo = code.substring(minorBuildSeparator + 1);
+ code = code.substring(0, minorBuildSeparator);
+ }
buildNumber = parseBuildNumber(version, code, name);
}
else {
@@ -116,13 +133,13 @@ public class BuildNumber implements Comparable<BuildNumber> {
if (buildNumber <= 2000) {
// it's probably a baseline, not a build number
- return new BuildNumber(productCode, buildNumber, 0);
+ return new BuildNumber(productCode, buildNumber, 0, null);
}
baselineVersion = getBaseLineForHistoricBuilds(buildNumber);
}
- return new BuildNumber(productCode, baselineVersion, buildNumber);
+ return new BuildNumber(productCode, baselineVersion, buildNumber, attemptInfo);
}
private static int parseBuildNumber(String version, String code, String name) {
@@ -188,6 +205,7 @@ public class BuildNumber implements Comparable<BuildNumber> {
if (myBaselineVersion != that.myBaselineVersion) return false;
if (myBuildNumber != that.myBuildNumber) return false;
if (!myProductCode.equals(that.myProductCode)) return false;
+ if (!Comparing.equal(myAttemptInfo, that.myAttemptInfo)) return false;
return true;
}
@@ -197,6 +215,7 @@ public class BuildNumber implements Comparable<BuildNumber> {
int result = myProductCode.hashCode();
result = 31 * result + myBaselineVersion;
result = 31 * result + myBuildNumber;
+ if (myAttemptInfo != null) result = 31 * result + myAttemptInfo.hashCode();
return result;
}
@@ -256,4 +275,8 @@ public class BuildNumber implements Comparable<BuildNumber> {
public boolean isSnapshot() {
return myBuildNumber == Integer.MAX_VALUE;
}
+
+ public String asStringWithAllDetails() {
+ return asString(true, true);
+ }
}
diff --git a/platform/util/src/com/intellij/openapi/util/IconLoader.java b/platform/util/src/com/intellij/openapi/util/IconLoader.java
index 37948dfd49d8..cc87d0dcfc43 100644
--- a/platform/util/src/com/intellij/openapi/util/IconLoader.java
+++ b/platform/util/src/com/intellij/openapi/util/IconLoader.java
@@ -159,10 +159,6 @@ public final class IconLoader {
ourIsActivated = true;
}
- public static void deactivate() {
- ourIsActivated = false;
- }
-
private static boolean isLoaderDisabled() {
return !ourIsActivated;
}
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 fa67b7462bec..0f95577cf2b5 100644
--- a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java
+++ b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java
@@ -415,6 +415,17 @@ public class FileUtil extends FileUtilRt {
}
public static boolean delete(@NotNull File file) {
+ if (SystemInfo.isWindows) {
+ File tempFile = findSequentNonexistentFile(file.getParentFile(), file.getName(), "");
+ if (file.renameTo(tempFile)) {
+ file = tempFile;
+ }
+ }
+
+ return doDelete(file);
+ }
+
+ private static boolean doDelete(File file) {
FileAttributes attributes = FileSystemUtil.getAttributes(file);
if (attributes == null) return true;
@@ -422,7 +433,7 @@ public class FileUtil extends FileUtilRt {
File[] files = file.listFiles();
if (files != null) {
for (File child : files) {
- if (!delete(child)) return false;
+ if (!doDelete(child)) return false;
}
}
}
diff --git a/platform/util/src/com/intellij/openapi/util/registry/ui/RegistryCheckBox.java b/platform/util/src/com/intellij/openapi/util/registry/ui/RegistryCheckBox.java
index 657f8dd85a38..ffc664eacab1 100644
--- a/platform/util/src/com/intellij/openapi/util/registry/ui/RegistryCheckBox.java
+++ b/platform/util/src/com/intellij/openapi/util/registry/ui/RegistryCheckBox.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.
@@ -22,8 +22,7 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
public class RegistryCheckBox extends CheckBoxWithDescription {
-
- private RegistryValue myValue;
+ private final RegistryValue myValue;
public RegistryCheckBox(RegistryValue value) {
this(value, value.getDescription(), null);
@@ -31,6 +30,7 @@ public class RegistryCheckBox extends CheckBoxWithDescription {
public RegistryCheckBox(RegistryValue value, String text, @Nullable String longDescription) {
super(new JCheckBox(text), longDescription);
+
myValue = value;
getCheckBox().setSelected(myValue.asBoolean());
}
@@ -42,5 +42,4 @@ public class RegistryCheckBox extends CheckBoxWithDescription {
public void save() {
myValue.setValue(Boolean.valueOf(getCheckBox().isSelected()).toString());
}
-
} \ No newline at end of file
diff --git a/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java b/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java
index 23afc188dfbd..559b6d0d1092 100644
--- a/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java
+++ b/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java
@@ -15,7 +15,6 @@
*/
package com.intellij.psi.codeStyle;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.FList;
@@ -32,7 +31,6 @@ import java.util.Iterator;
* @author peter
*/
public class MinusculeMatcher implements Matcher {
- private static final Logger LOG = Logger.getInstance("#com.intellij.psi.codeStyle.MinusculeMatcher");
/**
* Lowercase humps don't work for parts separated by these characters
* Need either an explicit uppercase letter or the same separator character in prefix
@@ -220,7 +218,7 @@ public class MinusculeMatcher implements Matcher {
}
@Nullable
- private FList<TextRange> calcMatchingFragments(@NotNull String name) {
+ public FList<TextRange> matchingFragments(@NotNull String name) {
MatchingState state = myMatchingState.get();
state.initializeState(name);
try {
@@ -231,22 +229,6 @@ public class MinusculeMatcher implements Matcher {
}
}
- @Nullable
- public FList<TextRange> matchingFragments(@NotNull String name) {
- long start = System.currentTimeMillis();
- FList<TextRange> result = calcMatchingFragments(name);
- if (System.currentTimeMillis() - start > 1000 &&
- // if there's little free memory, it might have been the gc affecting the performance
- Runtime.getRuntime().freeMemory() > Runtime.getRuntime().totalMemory() * 3 / 10) {
- start = System.currentTimeMillis();
- calcMatchingFragments(name);
- if (System.currentTimeMillis() - start > 1000) {
- LOG.error("Too long name matching: name=" + name + "; prefix=" + new String(myPattern));
- }
- }
- return result;
- }
-
/**
* After a wildcard (* or space), search for the first non-wildcard pattern character in the name starting from nameIndex
* and try to {@link #matchFragment(String, int, int, com.intellij.psi.codeStyle.MinusculeMatcher.MatchingState)} for it.
diff --git a/platform/util/src/com/intellij/ui/Graphics2DDelegate.java b/platform/util/src/com/intellij/ui/Graphics2DDelegate.java
index 0bc765eb625c..1d13b77b367c 100644
--- a/platform/util/src/com/intellij/ui/Graphics2DDelegate.java
+++ b/platform/util/src/com/intellij/ui/Graphics2DDelegate.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.
@@ -16,6 +16,7 @@
package com.intellij.ui;
import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
import java.awt.*;
import java.awt.font.FontRenderContext;
@@ -61,6 +62,7 @@ public class Graphics2DDelegate extends Graphics2D{
myDelegate.copyArea(x, y, width, height, dx, dy);
}
+ @NotNull
@Override
public Graphics create() {
return new Graphics2DDelegate((Graphics2D)myDelegate.create());
diff --git a/platform/util/src/com/intellij/util/containers/ContainerUtil.java b/platform/util/src/com/intellij/util/containers/ContainerUtil.java
index 4a9c7bde5614..6052df2b701e 100644
--- a/platform/util/src/com/intellij/util/containers/ContainerUtil.java
+++ b/platform/util/src/com/intellij/util/containers/ContainerUtil.java
@@ -1417,6 +1417,13 @@ public class ContainerUtil extends ContainerUtilRt {
}
}
+ @NotNull
+ public static <T> List<T> sorted(@NotNull Collection<T> list, @NotNull Comparator<T> comparator) {
+ List<T> sorted = newArrayList(list);
+ sort(sorted, comparator);
+ return sorted;
+ }
+
public static <T> void sort(@NotNull T[] a, @NotNull Comparator<T> comparator) {
int size = a.length;
@@ -2065,6 +2072,17 @@ public class ContainerUtil extends ContainerUtilRt {
return collection == null || collection.isEmpty();
}
+ @NotNull
+ public static <T, C extends Collection<T>> C notNullize(@Nullable C collection) {
+ //noinspection unchecked
+ return collection == null ? (C)ContainerUtilRt.emptyList() : collection;
+ }
+
+ @Nullable
+ public static <T, C extends Collection<T>> C nullize(@Nullable C collection) {
+ return isEmpty(collection) ? null : collection;
+ }
+
private interface ConcurrentMapFactory {
@NotNull <T, V> ConcurrentMap<T, V> createMap();
@NotNull <T, V> ConcurrentMap<T, V> createMap(int initialCapacity);
diff --git a/platform/util/src/com/intellij/util/containers/OrderedSet.java b/platform/util/src/com/intellij/util/containers/OrderedSet.java
index 9900eb92e800..0ff04acbe345 100644
--- a/platform/util/src/com/intellij/util/containers/OrderedSet.java
+++ b/platform/util/src/com/intellij/util/containers/OrderedSet.java
@@ -104,19 +104,19 @@ public class OrderedSet<T> extends ArrayList<T> implements Set<T>, RandomAccess
}
@Override
- public boolean addAll(final int index, final Collection<? extends T> c) {
+ public boolean addAll(final int index, @NotNull final Collection<? extends T> c) {
throw new UnsupportedOperationException();
}
@Override
- public T set(final int index, final T element) {
+ public T set(final int index, @NotNull final T element) {
final T removed = remove(index);
add(index, element);
return removed;
}
@Override
- public void add(final int index, final T element) {
+ public void add(final int index, @NotNull final T element) {
if (myHashSet.add(element)){
super.add(index, element);
}
diff --git a/platform/util/src/com/intellij/util/io/AbstractStringEnumerator.java b/platform/util/src/com/intellij/util/io/AbstractStringEnumerator.java
index 589fa0add6fe..a8145d5351dd 100644
--- a/platform/util/src/com/intellij/util/io/AbstractStringEnumerator.java
+++ b/platform/util/src/com/intellij/util/io/AbstractStringEnumerator.java
@@ -16,19 +16,13 @@
package com.intellij.util.io;
import com.intellij.openapi.Forceable;
-import org.jetbrains.annotations.Nullable;
import java.io.Closeable;
-import java.io.IOException;
/**
* Author: dmitrylomov
*/
-public interface AbstractStringEnumerator extends Closeable, Forceable {
- int enumerate(@Nullable String value) throws IOException;
-
- @Nullable
- String valueOf(int idx) throws IOException;
+public interface AbstractStringEnumerator extends Closeable, Forceable, DataEnumerator<String> {
void markCorrupted();
}
diff --git a/platform/util/src/com/intellij/util/io/AppendableStorageBackedByResizableMappedFile.java b/platform/util/src/com/intellij/util/io/AppendableStorageBackedByResizableMappedFile.java
index 6f936d75849a..c4381da1a406 100644
--- a/platform/util/src/com/intellij/util/io/AppendableStorageBackedByResizableMappedFile.java
+++ b/platform/util/src/com/intellij/util/io/AppendableStorageBackedByResizableMappedFile.java
@@ -158,7 +158,7 @@ public class AppendableStorageBackedByResizableMappedFile extends ResizeableMapp
int base = addr;
int address = storage.getOffsetInPage(addr);
boolean same = true;
- ByteBuffer buffer = storage.getByteBuffer(addr, false);
+ ByteBuffer buffer = storage.getByteBuffer(addr, false).getCachedBuffer();
final int myPageSize = storage.myPageSize;
@Override
@@ -166,7 +166,7 @@ public class AppendableStorageBackedByResizableMappedFile extends ResizeableMapp
if (same) {
if (myPageSize == address && address < myFileLength) { // reached end of current byte buffer
base += address;
- buffer = storage.getByteBuffer(base, false);
+ buffer = storage.getByteBuffer(base, false).getCachedBuffer();
address = 0;
}
same = address < myFileLength && buffer.get(address++) == (byte)b;
diff --git a/platform/util/src/com/intellij/util/io/CachingEnumerator.java b/platform/util/src/com/intellij/util/io/CachingEnumerator.java
new file mode 100644
index 000000000000..94ce68c981ca
--- /dev/null
+++ b/platform/util/src/com/intellij/util/io/CachingEnumerator.java
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.io;
+
+import com.intellij.util.containers.SLRUMap;
+import jsr166e.extra.SequenceLock;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.IOException;
+import java.util.concurrent.locks.Lock;
+
+/**
+ * @author peter
+ */
+public class CachingEnumerator<Data> implements DataEnumerator<Data> {
+ private static final int STRIPE_POWER = 4;
+ private static final int STRIPE_COUNT = 1 << STRIPE_POWER;
+ private static final int STRIPE_MASK = STRIPE_COUNT - 1;
+ @SuppressWarnings("unchecked") private final SLRUMap<Integer, Integer>[] myHashcodeToIdCache = new SLRUMap[STRIPE_COUNT];
+ @SuppressWarnings("unchecked") private final SLRUMap<Integer, Data>[] myIdToStringCache = new SLRUMap[STRIPE_COUNT];
+ private final Lock[] myStripeLocks = new Lock[STRIPE_COUNT];
+ private final DataEnumerator<Data> myBase;
+ private final KeyDescriptor<Data> myDataDescriptor;
+
+ public CachingEnumerator(DataEnumerator<Data> base, KeyDescriptor<Data> dataDescriptor) {
+ myBase = base;
+ myDataDescriptor = dataDescriptor;
+ int protectedSize = 8192;
+ int probationalSize = 8192;
+
+ for(int i = 0; i < STRIPE_COUNT; ++i) {
+ myHashcodeToIdCache[i] = new SLRUMap<Integer, Integer>(protectedSize / STRIPE_COUNT, probationalSize / STRIPE_COUNT);
+ myIdToStringCache[i] = new SLRUMap<Integer, Data>(protectedSize / STRIPE_COUNT, probationalSize / STRIPE_COUNT);
+ myStripeLocks[i] = new SequenceLock();
+ }
+
+ }
+
+ public int enumerate(@Nullable Data value) throws IOException {
+ int valueHashCode =-1;
+ int stripe = -1;
+
+ if (myHashcodeToIdCache != null && value != null) {
+ valueHashCode = myDataDescriptor.getHashCode(value);
+ stripe = Math.abs(valueHashCode) & STRIPE_MASK;
+
+ Integer cachedId;
+
+ myStripeLocks[stripe].lock();
+ try {
+ cachedId = myHashcodeToIdCache[stripe].get(valueHashCode);
+ }
+ finally {
+ myStripeLocks[stripe].unlock();
+ }
+
+ if (cachedId != null) {
+ int stripe2 = idStripe(cachedId.intValue());
+ myStripeLocks[stripe2].lock();
+ try {
+ Data s = myIdToStringCache[stripe2].get(cachedId);
+ if (s != null && myDataDescriptor.isEqual(value, s)) return cachedId.intValue();
+ }
+ finally {
+ myStripeLocks[stripe2].unlock();
+ }
+ }
+ }
+
+ int enumerate = myBase.enumerate(value);
+
+ if (stripe != -1) {
+ Integer enumeratedInteger;
+
+ myStripeLocks[stripe].lock();
+ try {
+ enumeratedInteger = enumerate;
+ myHashcodeToIdCache[stripe].put(valueHashCode, enumeratedInteger);
+ } finally {
+ myStripeLocks[stripe].unlock();
+ }
+
+ int stripe2 = idStripe(enumerate);
+ myStripeLocks[stripe2].lock();
+ try {
+ myIdToStringCache[stripe2].put(enumeratedInteger, value);
+ } finally {
+ myStripeLocks[stripe2].unlock();
+ }
+ }
+
+ return enumerate;
+ }
+
+ private static int idStripe(int h) {
+ h ^= (h >>> 20) ^ (h >>> 12);
+ return Math.abs(h ^ (h >>> 7) ^ (h >>> 4)) & STRIPE_MASK;
+ }
+
+ @Nullable
+ public Data valueOf(int idx) throws IOException {
+ int stripe = -1;
+ if (myIdToStringCache != null) {
+ stripe = idStripe(idx);
+ myStripeLocks[stripe].lock();
+ try {
+ Data s = myIdToStringCache[stripe].get(idx);
+ if (s != null) return s;
+ }
+ finally {
+ myStripeLocks[stripe].unlock();
+ }
+ }
+ Data s = myBase.valueOf(idx);
+
+ if (stripe != -1 && s != null) {
+ myStripeLocks[stripe].lock();
+ try {
+ myIdToStringCache[stripe].put(idx, s);
+ }
+ finally {
+ myStripeLocks[stripe].unlock();
+ }
+ }
+ return s;
+ }
+
+ public void close() throws IOException {
+ for(int i = 0; i < myIdToStringCache.length; ++i) {
+ myStripeLocks[i].lock();
+ myIdToStringCache[i].clear();
+ myHashcodeToIdCache[i].clear();
+ myStripeLocks[i].unlock();
+ }
+ }
+}
diff --git a/platform/util/src/com/intellij/util/io/DataEnumerator.java b/platform/util/src/com/intellij/util/io/DataEnumerator.java
new file mode 100644
index 000000000000..3a7a1131b638
--- /dev/null
+++ b/platform/util/src/com/intellij/util/io/DataEnumerator.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.io;
+
+import org.jetbrains.annotations.Nullable;
+
+import java.io.IOException;
+
+/**
+ * @author peter
+ */
+public interface DataEnumerator<Data> {
+ int enumerate(@Nullable Data value) throws IOException;
+
+ @Nullable
+ Data valueOf(int idx) throws IOException;
+}
diff --git a/platform/util/src/com/intellij/util/io/EnumeratorStringDescriptor.java b/platform/util/src/com/intellij/util/io/EnumeratorStringDescriptor.java
index dce1d4990623..922701542394 100644
--- a/platform/util/src/com/intellij/util/io/EnumeratorStringDescriptor.java
+++ b/platform/util/src/com/intellij/util/io/EnumeratorStringDescriptor.java
@@ -26,6 +26,7 @@ import java.io.IOException;
* Date: Dec 18, 2007
*/
public class EnumeratorStringDescriptor implements KeyDescriptor<String> {
+ public static final EnumeratorStringDescriptor INSTANCE = new EnumeratorStringDescriptor();
@Override
public int getHashCode(final String value) {
return value.hashCode();
diff --git a/platform/util/src/com/intellij/util/io/IntToIntBtree.java b/platform/util/src/com/intellij/util/io/IntToIntBtree.java
index 8cddbcee32c8..b17fc6cc5c6c 100644
--- a/platform/util/src/com/intellij/util/io/IntToIntBtree.java
+++ b/platform/util/src/com/intellij/util/io/IntToIntBtree.java
@@ -203,7 +203,7 @@ class IntToIntBtree {
boolean canUseLastKey = myCanUseLastKey;
if (canUseLastKey) {
myCanUseLastKey = false;
- if (key == myLastGetKey && !myAccessNodeView.myHasFullPagesAlongPath) {
+ if (key == myLastGetKey && !myAccessNodeView.myHasFullPagesAlongPath && myAccessNodeView.isValid()) {
++myOptimizedInserts;
++count;
myAccessNodeView.insert(key, value);
@@ -284,6 +284,7 @@ class IntToIntBtree {
private short myChildrenCount;
protected int myAddressInBuffer;
protected ByteBuffer myBuffer;
+ protected ByteBufferWrapper myBufferWrapper;
protected boolean myHasFullPagesAlongPath;
protected boolean myIsDirty;
@@ -302,7 +303,8 @@ class IntToIntBtree {
protected void syncWithStore() {
PagedFileStorage pagedFileStorage = btree.storage.getPagedFileStorage();
myAddressInBuffer = pagedFileStorage.getOffsetInPage(address);
- myBuffer = pagedFileStorage.getByteBuffer(address, false);
+ myBufferWrapper = pagedFileStorage.getByteBuffer(address, false);
+ myBuffer = myBufferWrapper.getCachedBuffer();
myIsDirty = false; // we will mark dirty on child count change, attrs change or existing key put
doInitFlags(myBuffer.getInt(myAddressInBuffer));
}
@@ -541,6 +543,10 @@ class IntToIntBtree {
setAddress(address);
}
+ public boolean isValid() {
+ return myBufferWrapper.getCachedBuffer() == myBuffer;
+ }
+
private static class HashLeafData {
final BtreeIndexNodeView nodeView;
final int[] keys;
diff --git a/platform/util/src/com/intellij/util/io/PagedFileStorage.java b/platform/util/src/com/intellij/util/io/PagedFileStorage.java
index 1d5e9d76d04e..69315f1b3764 100644
--- a/platform/util/src/com/intellij/util/io/PagedFileStorage.java
+++ b/platform/util/src/com/intellij/util/io/PagedFileStorage.java
@@ -151,7 +151,7 @@ public class PagedFileStorage implements Forceable {
if (myValuesAreBufferAligned) {
long page = addr / myPageSize;
int page_offset = (int) (addr % myPageSize);
- return getBuffer(page, false).getInt(page_offset);
+ return getReadOnlyBuffer(page).getInt(page_offset);
} else {
get(addr, myTypedIOBuffer, 0, 4);
return Bits.getInt(myTypedIOBuffer, 0);
@@ -173,15 +173,15 @@ public class PagedFileStorage implements Forceable {
return (int)(addr % myPageSize);
}
- ByteBuffer getByteBuffer(long address, boolean modify) {
- return getBuffer(address / myPageSize, modify);
+ ByteBufferWrapper getByteBuffer(long address, boolean modify) {
+ return getBufferWrapper(address / myPageSize, modify);
}
public final short getShort(long addr) {
if (myValuesAreBufferAligned) {
long page = addr / myPageSize;
int page_offset = (int)(addr % myPageSize);
- return getBuffer(page, false).getShort(page_offset);
+ return getReadOnlyBuffer(page).getShort(page_offset);
} else {
get(addr, myTypedIOBuffer, 0, 2);
return Bits.getShort(myTypedIOBuffer, 0);
@@ -212,7 +212,7 @@ public class PagedFileStorage implements Forceable {
if (myValuesAreBufferAligned) {
long page = addr / myPageSize;
int page_offset = (int)(addr % myPageSize);
- return getBuffer(page, false).getLong(page_offset);
+ return getReadOnlyBuffer(page).getLong(page_offset);
} else {
get(addr, myTypedIOBuffer, 0, 8);
return Bits.getLong(myTypedIOBuffer, 0);
@@ -223,7 +223,7 @@ public class PagedFileStorage implements Forceable {
long page = index / myPageSize;
int offset = (int)(index % myPageSize);
- return getBuffer(page, false).get(offset);
+ return getReadOnlyBuffer(page).get(offset);
}
public void put(long index, byte value) {
@@ -243,7 +243,7 @@ public class PagedFileStorage implements Forceable {
int page_offset = (int) (i % myPageSize);
int page_len = Math.min(l, myPageSize - page_offset);
- final ByteBuffer buffer = getBuffer(page, false);
+ final ByteBuffer buffer = getReadOnlyBuffer(page);
try {
buffer.position(page_offset);
}
@@ -369,28 +369,32 @@ public class PagedFileStorage implements Forceable {
}
private ByteBuffer getBuffer(long page) {
- return getBuffer(page, true);
+ return getBufferWrapper(page, true).getCachedBuffer();
}
- private ByteBuffer getBuffer(long page, boolean modify) {
+ private ByteBuffer getReadOnlyBuffer(long page) {
+ return getBufferWrapper(page, false).getCachedBuffer();
+ }
+
+ private ByteBufferWrapper getBufferWrapper(long page, boolean modify) {
synchronized (myLastAccessedBufferCacheLock) {
if (myLastPage == page) {
ByteBuffer buf = myLastBuffer.getCachedBuffer();
if (buf != null && myLastChangeCount == myStorageLockContext.myStorageLock.myMappingChangeCount) {
if (modify) markDirty(myLastBuffer);
- return buf;
+ return myLastBuffer;
}
} else if (myLastPage2 == page) {
ByteBuffer buf = myLastBuffer2.getCachedBuffer();
if (buf != null && myLastChangeCount2 == myStorageLockContext.myStorageLock.myMappingChangeCount) {
if (modify) markDirty(myLastBuffer2);
- return buf;
+ return myLastBuffer2;
}
} else if (myLastPage3 == page) {
ByteBuffer buf = myLastBuffer3.getCachedBuffer();
if (buf != null && myLastChangeCount3 == myStorageLockContext.myStorageLock.myMappingChangeCount) {
if (modify) markDirty(myLastBuffer3);
- return buf;
+ return myLastBuffer3;
}
}
}
@@ -427,7 +431,7 @@ public class PagedFileStorage implements Forceable {
myLastChangeCount = myStorageLockContext.myStorageLock.myMappingChangeCount;
}
- return buf;
+ return byteBufferWrapper;
}
catch (IOException e) {
throw new MappingFailedException("Cannot map buffer", e);
diff --git a/platform/util/src/com/intellij/util/io/PersistentHashMap.java b/platform/util/src/com/intellij/util/io/PersistentHashMap.java
index de43fbd11b1b..dde187d804b5 100644
--- a/platform/util/src/com/intellij/util/io/PersistentHashMap.java
+++ b/platform/util/src/com/intellij/util/io/PersistentHashMap.java
@@ -80,7 +80,7 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
private final boolean myCanReEnumerate;
private int myLargeIndexWatermarkId; // starting with this id we store offset in adjacent file in long format
private boolean myIntAddressForNewRecord;
- private static final boolean doHardConsistencyChecks = true;
+ private static final boolean doHardConsistencyChecks = false;
private volatile boolean myBusyReading;
private static class AppendStream extends DataOutputStream {
diff --git a/platform/util/src/com/intellij/util/io/PersistentStringEnumerator.java b/platform/util/src/com/intellij/util/io/PersistentStringEnumerator.java
index 19755778f2ec..996798734253 100644
--- a/platform/util/src/com/intellij/util/io/PersistentStringEnumerator.java
+++ b/platform/util/src/com/intellij/util/io/PersistentStringEnumerator.java
@@ -15,22 +15,14 @@
*/
package com.intellij.util.io;
-import com.intellij.util.containers.SLRUMap;
-import jsr166e.extra.SequenceLock;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
-import java.util.concurrent.locks.Lock;
public class PersistentStringEnumerator extends PersistentEnumeratorDelegate<String> implements AbstractStringEnumerator {
- private static final int STRIPE_POWER = 4;
- private static final int STRIPE_COUNT = 1 << STRIPE_POWER;
- private static final int STRIPE_MASK = STRIPE_COUNT - 1;
- @Nullable private final SLRUMap<Integer, Integer>[] myHashcodeToIdCache;
- @Nullable private final SLRUMap<Integer, String>[] myIdToStringCache;
- @Nullable private final Lock[] myStripeLocks;
+ @Nullable private final CachingEnumerator<String> myCache;
public PersistentStringEnumerator(@NotNull final File file) throws IOException {
this(file, null);
@@ -58,129 +50,36 @@ public class PersistentStringEnumerator extends PersistentEnumeratorDelegate<Str
final int initialSize,
boolean cacheLastMappings,
@Nullable PagedFileStorage.StorageLockContext lockContext) throws IOException {
- super(file, new EnumeratorStringDescriptor(), initialSize, lockContext);
- if (cacheLastMappings) {
- myIdToStringCache = new SLRUMap[STRIPE_COUNT];
- myHashcodeToIdCache = new SLRUMap[STRIPE_COUNT];
- myStripeLocks = new Lock[STRIPE_COUNT];
- int protectedSize = 8192;
- int probationalSize = 8192;
+ super(file, EnumeratorStringDescriptor.INSTANCE, initialSize, lockContext);
+ myCache = cacheLastMappings ? new CachingEnumerator<String>(new DataEnumerator<String>() {
+ @Override
+ public int enumerate(@Nullable String value) throws IOException {
+ return PersistentStringEnumerator.super.enumerate(value);
+ }
- for(int i = 0; i < STRIPE_COUNT; ++i) {
- myHashcodeToIdCache[i] = new SLRUMap<Integer, Integer>(protectedSize / STRIPE_COUNT, probationalSize / STRIPE_COUNT);
- myIdToStringCache[i] = new SLRUMap<Integer, String>(protectedSize / STRIPE_COUNT, probationalSize / STRIPE_COUNT);
- myStripeLocks[i] = new SequenceLock();
+ @Nullable
+ @Override
+ public String valueOf(int idx) throws IOException {
+ return PersistentStringEnumerator.super.valueOf(idx);
}
- } else {
- myIdToStringCache = null;
- myHashcodeToIdCache = null;
- myStripeLocks = null;
- }
+ }, EnumeratorStringDescriptor.INSTANCE) : null;
}
@Override
public int enumerate(@Nullable String value) throws IOException {
- int valueHashCode =-1;
- int stripe = -1;
-
- if (myHashcodeToIdCache != null && value != null) {
- valueHashCode = value.hashCode();
- stripe = Math.abs(valueHashCode) & STRIPE_MASK;
-
- Integer cachedId;
-
- myStripeLocks[stripe].lock();
- try {
- cachedId = myHashcodeToIdCache[stripe].get(valueHashCode);
- }
- finally {
- myStripeLocks[stripe].unlock();
- }
-
- if (cachedId != null) {
- int stripe2 = idStripe(cachedId.intValue());
- myStripeLocks[stripe2].lock();
- try {
- String s = myIdToStringCache[stripe2].get(cachedId);
- if (s != null && value.equals(s)) return cachedId.intValue();
- }
- finally {
- myStripeLocks[stripe2].unlock();
- }
- }
- }
-
- int enumerate = super.enumerate(value);
-
- if (stripe != -1) {
- Integer enumeratedInteger;
-
- myStripeLocks[stripe].lock();
- try {
- enumeratedInteger = enumerate;
- myHashcodeToIdCache[stripe].put(valueHashCode, enumeratedInteger);
- } finally {
- myStripeLocks[stripe].unlock();
- }
-
- int stripe2 = idStripe(enumerate);
- myStripeLocks[stripe2].lock();
- try {
- myIdToStringCache[stripe2].put(enumeratedInteger, value);
- } finally {
- myStripeLocks[stripe2].unlock();
- }
- }
-
- return enumerate;
- }
-
- private int idStripe(int h) {
- h ^= (h >>> 20) ^ (h >>> 12);
- return Math.abs(h ^ (h >>> 7) ^ (h >>> 4)) & STRIPE_MASK;
+ return myCache != null ? myCache.enumerate(value) : super.enumerate(value);
}
@Nullable
@Override
public String valueOf(int idx) throws IOException {
- int stripe = -1;
- if (myIdToStringCache != null) {
- stripe = idStripe(idx);
- myStripeLocks[stripe].lock();
- try {
- String s = myIdToStringCache[stripe].get(idx);
- if (s != null) return s;
- }
- finally {
- myStripeLocks[stripe].unlock();
- }
- }
- String s = super.valueOf(idx);
-
- if (stripe != -1 && s != null) {
- myStripeLocks[stripe].lock();
- try {
- myIdToStringCache[stripe].put(idx, s);
- }
- finally {
- myStripeLocks[stripe].unlock();
- }
- }
- return s;
+ return myCache != null ? myCache.valueOf(idx) : super.valueOf(idx);
}
@Override
public void close() throws IOException {
super.close();
-
- if (myIdToStringCache != null) {
- for(int i = 0; i < myIdToStringCache.length; ++i) {
- myStripeLocks[i].lock();
- myIdToStringCache[i].clear();
- myHashcodeToIdCache[i].clear();
- myStripeLocks[i].unlock();
- }
- }
+ if (myCache != null) myCache.close();
}
@Override
diff --git a/platform/util/src/com/intellij/util/ui/ColumnInfo.java b/platform/util/src/com/intellij/util/ui/ColumnInfo.java
index 8289633b111d..2ad54e6f81b9 100644
--- a/platform/util/src/com/intellij/util/ui/ColumnInfo.java
+++ b/platform/util/src/com/intellij/util/ui/ColumnInfo.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.
@@ -23,18 +23,6 @@ import javax.swing.table.TableCellRenderer;
import java.util.Comparator;
public abstract class ColumnInfo <Item, Aspect> {
-
- public static class StringColumn extends ColumnInfo<String, String> {
- public StringColumn(final String name) {
- super(name);
- }
-
- @Override
- public String valueOf(final String item) {
- return item;
- }
- }
-
private String myName;
public static final ColumnInfo[] EMPTY_ARRAY = new ColumnInfo[0];
diff --git a/platform/util/src/com/intellij/util/ui/UIUtil.java b/platform/util/src/com/intellij/util/ui/UIUtil.java
index cc6d5a305bf5..7ed8021bd94b 100644
--- a/platform/util/src/com/intellij/util/ui/UIUtil.java
+++ b/platform/util/src/com/intellij/util/ui/UIUtil.java
@@ -48,7 +48,9 @@ import javax.swing.plaf.basic.BasicComboBoxUI;
import javax.swing.plaf.basic.BasicRadioButtonUI;
import javax.swing.plaf.basic.ComboPopup;
import javax.swing.text.DefaultEditorKit;
+import javax.swing.text.DefaultFormatterFactory;
import javax.swing.text.JTextComponent;
+import javax.swing.text.NumberFormatter;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.StyleSheet;
import javax.swing.undo.UndoManager;
@@ -70,6 +72,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
+import java.text.NumberFormat;
import java.util.*;
import java.util.List;
import java.util.concurrent.BlockingQueue;
@@ -2982,4 +2985,23 @@ public class UIUtil {
}
return new EmptyBorder(0, leftGap, 0, 0);
}
+
+ public static Color getSidePanelColor() {
+ return new JBColor(new Color(0xD2D6DD), new Color(60, 68, 71));
+ }
+
+ /**
+ * It is your responsibility to set correct horizontal align (left in case of UI Designer)
+ */
+ public static void configureNumericFormattedTextField(@NotNull JFormattedTextField textField) {
+ NumberFormat format = NumberFormat.getIntegerInstance();
+ format.setParseIntegerOnly(true);
+ format.setGroupingUsed(false);
+ NumberFormatter numberFormatter = new NumberFormatter(format);
+ numberFormatter.setMinimum(0);
+ textField.setFormatterFactory(new DefaultFormatterFactory(numberFormatter));
+ textField.setHorizontalAlignment(SwingConstants.TRAILING);
+
+ textField.setColumns(4);
+ }
}
diff --git a/platform/util/testSrc/com/intellij/util/containers/ConcurrentMapsTest.java b/platform/util/testSrc/com/intellij/util/containers/ConcurrentMapsTest.java
index 2972091e78a5..c85b8d3516a7 100644
--- a/platform/util/testSrc/com/intellij/util/containers/ConcurrentMapsTest.java
+++ b/platform/util/testSrc/com/intellij/util/containers/ConcurrentMapsTest.java
@@ -98,7 +98,7 @@ public class ConcurrentMapsTest {
List<Object> list = ContainerUtil.newArrayList();
while (reference.get() != null) {
int chunk = (int)Math.min(Runtime.getRuntime().freeMemory() / 2, Integer.MAX_VALUE);
- list.add(new SoftReference<byte[]>(new byte[chunk / 2]));
+ list.add(new SoftReference<byte[]>(new byte[chunk]));
}
}