diff --git a/platform/util/src/com/intellij/util/containers/HashSetInterner.java b/platform/util/src/com/intellij/util/containers/HashSetInterner.java index b222ca98a242..7c0f788a93cc 100644 --- a/platform/util/src/com/intellij/util/containers/HashSetInterner.java +++ b/platform/util/src/com/intellij/util/containers/HashSetInterner.java @@ -33,15 +33,7 @@ public class HashSetInterner extends Interner { @Override @NotNull public T intern(@NotNull T name) { - T interned = mySet.get(name); - if (interned != null) { - return interned; - } - - boolean added = mySet.add(name); - assert added; - - return name; + return mySet.getOrAdd(name); } @Override diff --git a/platform/util/src/com/intellij/util/containers/OpenTHashSet.java b/platform/util/src/com/intellij/util/containers/OpenTHashSet.java index b17df25425e6..c31201dc1cd4 100644 --- a/platform/util/src/com/intellij/util/containers/OpenTHashSet.java +++ b/platform/util/src/com/intellij/util/containers/OpenTHashSet.java @@ -17,6 +17,7 @@ package com.intellij.util.containers; import gnu.trove.THashSet; import gnu.trove.TObjectHashingStrategy; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -83,4 +84,22 @@ public class OpenTHashSet extends THashSet { final int index = index(obj); return index < 0 ? null : get(index); } + + /** + * Returns an element of this set equal to the given one, or adds the given one to the set and returns it. + * Can be used for interning objects to save memory. + */ + @Contract("!null -> !null") + public T getOrAdd(final T obj) { + final int index = insertionIndex(obj); + + boolean alreadyStored = index < 0; + if (alreadyStored) return get(-index - 1); + + Object old = _set[index]; + _set[index] = obj; + + postInsertHook(old == null); + return obj; + } }