diff options
Diffstat (limited to 'platform/util/src/com/intellij')
21 files changed, 321 insertions, 192 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); + } } |