diff --git a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/Imports.java b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/Imports.java index 8aa45819e61a..639a8ea07db8 100644 --- a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/Imports.java +++ b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/Imports.java @@ -103,11 +103,11 @@ class Imports { } class Import { - @QNameId final int qualifier; + @QNameHash final int qualifier; @ShortName final int importedName; // 0 for on-demand final boolean isStatic; - Import(@QNameId int qualifier, @ShortName int importedName, boolean isStatic) { + Import(@QNameHash int qualifier, @ShortName int importedName, boolean isStatic) { this.qualifier = qualifier; this.importedName = importedName; this.isStatic = isStatic; @@ -126,10 +126,10 @@ class Import { class AliasedImport extends Import { private final @ShortName int alias; - public AliasedImport(@QNameId int qualifier, - @ShortName int importedName, - boolean isStatic, - @ShortName int alias) { + AliasedImport(@QNameHash int qualifier, + @ShortName int importedName, + boolean isStatic, + @ShortName int alias) { super(qualifier, importedName, isStatic); this.alias = alias; } diff --git a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/NameEnvironment.java b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/NameEnvironment.java index c2108467c649..ab943317b08d 100644 --- a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/NameEnvironment.java +++ b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/NameEnvironment.java @@ -19,7 +19,6 @@ import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.psi.CommonClassNames; import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree; import com.intellij.util.io.DataInputOutputUtil; -import gnu.trove.TLongIntHashMap; import java.io.DataInput; import java.io.DataOutput; @@ -28,31 +27,19 @@ import java.io.IOException; class NameEnvironment extends UserDataHolderBase { public static final int OBJECT_NAME = IndexTree.hashIdentifier("Object"); public static final int NO_NAME = 0; - @QNameId public final int java_lang; + @QNameHash final int java_lang; public final QualifiedName java_lang_Enum; public final QualifiedName java_lang_annotation_Annotation; - private final TLongIntHashMap myConcatenations = new TLongIntHashMap(); - NameEnvironment() { java_lang = fromString("java.lang"); java_lang_Enum = new QualifiedName.Interned(fromString(CommonClassNames.JAVA_LANG_ENUM)); java_lang_annotation_Annotation = new QualifiedName.Interned(fromString(CommonClassNames.JAVA_LANG_ANNOTATION_ANNOTATION)); } - @QNameId - int fromString(String s) { - return internQualifiedName(IndexTree.hashQualifiedName(s)); - } - - @QNameId int findExistingName(@QNameId int stemId, @ShortName int suffix) { - int existing = myConcatenations.get(pack(stemId, suffix)); - return existing > 0 ? existing : -1; - } - - @QNameId int internQualifiedName(@ShortName int[] qname) { + @QNameHash int fromString(String s) { int id = 0; - for (int shortName : qname) { + for (int shortName : IndexTree.hashQualifiedName(s)) { id = qualifiedName(id, shortName); } return id; @@ -61,7 +48,7 @@ class NameEnvironment extends UserDataHolderBase { /** * @see SerializedUnit#writeQualifiedName(DataOutput, int[]) */ - @QNameId int readQualifiedName(DataInput in) throws IOException { + @QNameHash int readQualifiedName(DataInput in) throws IOException { int id = 0; int len = DataInputOutputUtil.readINT(in); for (int i = 0; i < len; i++) { @@ -70,22 +57,13 @@ class NameEnvironment extends UserDataHolderBase { return id; } - int memberQualifiedName(@QNameId int ownerName, @ShortName int name) { - return name == NO_NAME || ownerName < 0 ? -1 : qualifiedName(ownerName, name); + int memberQualifiedName(@QNameHash int ownerName, @ShortName int name) { + return name == NO_NAME || ownerName == 0 ? 0 : qualifiedName(ownerName, name); } - @QNameId int qualifiedName(@QNameId int prefix, @ShortName int shortName) { - int existing = findExistingName(prefix, shortName); - return existing >= 0 ? existing : addName(prefix, shortName); + @QNameHash int qualifiedName(@QNameHash int prefix, @ShortName int shortName) { + int hash = prefix * 31 + shortName; + return hash == 0 ? 1 : hash; } - private int addName(@QNameId int stemId, @ShortName int suffix) { - int newId = myConcatenations.size(); - myConcatenations.put(pack(stemId, suffix), newId); - return newId; - } - - private static long pack(@QNameId int stemId, @ShortName int suffix) { - return ((long)suffix << 32) + stemId; - } } diff --git a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/SerializedUnit.java b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/SerializedUnit.java index b35dcdd106b8..db9a6353f8b9 100644 --- a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/SerializedUnit.java +++ b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/SerializedUnit.java @@ -69,7 +69,7 @@ class SerializedUnit { /** * @see NameEnvironment#readQualifiedName(DataInput) */ - static void writeQualifiedName(DataOutput out, @QNameId int[] array) throws IOException { + static void writeQualifiedName(DataOutput out, @QNameHash int[] array) throws IOException { DataInputOutputUtil.writeINT(out, array.length); for (int i : array) { out.writeInt(i); @@ -124,13 +124,13 @@ class SerializedUnit { writeMembers(out, value.myDecls); } - private static ClassSymbol readClassDecl(UnitInputStream in, UnitInfo info, Symbol owner, @QNameId int ownerName) throws IOException { + private static ClassSymbol readClassDecl(UnitInputStream in, UnitInfo info, Symbol owner, @QNameHash int ownerName) throws IOException { int stubId = DataInputOutputUtil.readINT(in); int mods = DataInputOutputUtil.readINT(in); @ShortName int name = in.readInt(); @CompactArray(QualifiedName.class) Object superNames = readSupers(in, info.isCompiled()); - @QNameId int qname = in.names.memberQualifiedName(ownerName, name); + @QNameHash int qname = in.names.memberQualifiedName(ownerName, name); ClassSymbol symbol = in.stubEnter.classEnter(info, owner, stubId, mods, name, superNames, qname, in.fileId); readMembers(in, info, qname, symbol); @@ -173,7 +173,7 @@ class SerializedUnit { private static void readMembers(UnitInputStream in, UnitInfo info, - @QNameId int ownerName, + @QNameHash int ownerName, MemberSymbol symbol) throws IOException { int memberCount = DataInputOutputUtil.readINT(in); if (memberCount == 0) return; @@ -197,7 +197,7 @@ class SerializedUnit { } } - private static ClassSymbol readDecl(UnitInputStream in, UnitInfo info, Symbol owner, @QNameId int ownerName) throws IOException { + private static ClassSymbol readDecl(UnitInputStream in, UnitInfo info, Symbol owner, @QNameHash int ownerName) throws IOException { if (in.readBoolean()) { return readClassDecl(in, info, owner, ownerName); } diff --git a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubEnter.java b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubEnter.java index 3f04a62e199e..cc4cc55a2d7c 100644 --- a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubEnter.java +++ b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubEnter.java @@ -60,7 +60,7 @@ public class StubEnter { int mods, @ShortName int name, @CompactArray(QualifiedName.class) Object superNames, - @QNameId int qname, int fileId) throws IOException { + @QNameHash int qname, int fileId) throws IOException { int flags = checkFlags(mods, info.isCompiled()); @CompactArray(QualifiedName.class) Object supers = handleSpecialSupers(mods, superNames); diff --git a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubResolver.java b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubResolver.java index 692733680b32..9e3c7520d032 100644 --- a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubResolver.java +++ b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubResolver.java @@ -69,9 +69,7 @@ public class StubResolver { findGlobalType(info, name, result); if (processPackages) { - @QNameId int nameId = myNameEnvironment.findExistingName(0, name); - Symbol.PackageSymbol pkg = nameId < 0 ? null : mySymbols.getPackage(nameId); - ContainerUtil.addIfNotNull(result, pkg); + ContainerUtil.addIfNotNull(result, mySymbols.getPackage(name)); } return result; } @@ -93,10 +91,7 @@ public class StubResolver { } private void findIdentInPackage(Symbol.PackageSymbol pck, @ShortName int name, boolean processPackages, Set symbols) { - @QNameId int fullname = mySymbols.myNameEnvironment.findExistingName(pck.myQualifiedName, name); - if (fullname < 0) { - return; - } + @QNameHash int fullname = mySymbols.myNameEnvironment.qualifiedName(pck.myQualifiedName, name); if (processPackages) { ContainerUtil.addIfNotNull(symbols, mySymbols.getPackage(fullname)); } @@ -132,8 +127,8 @@ public class StubResolver { } } - public Symbol.ClassSymbol[] findGlobalType(@QNameId int nameId) { - return mySymbols.loadClass(nameId); + public Symbol.ClassSymbol[] findGlobalType(@QNameHash int nameId) { + return mySymbols.getClassSymbols(nameId); } private void findGlobalType(UnitInfo info, @ShortName int name, Set symbols) throws IncompleteHierarchyException { @@ -168,11 +163,8 @@ public class StubResolver { } // handling of `import prefix.*` - private void importAll(@QNameId int prefix, @ShortName int suffix, final Set symbols) { - @QNameId int fullname = myNameEnvironment.findExistingName(prefix, suffix); - if (fullname >= 0) { - Collections.addAll(symbols, findGlobalType(fullname)); - } + private void importAll(@QNameHash int prefix, @ShortName int suffix, final Set symbols) { + Collections.addAll(symbols, findGlobalType(myNameEnvironment.qualifiedName(prefix, suffix))); } // handling of import static `tsym.name` as diff --git a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/Symbol.java b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/Symbol.java index 4334fbc84145..eb86ee6ea70b 100644 --- a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/Symbol.java +++ b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/Symbol.java @@ -68,9 +68,9 @@ abstract class Symbol { } public static class PackageSymbol extends Symbol { - @QNameId final int myQualifiedName; + @QNameHash final int myQualifiedName; - public PackageSymbol(Symbol owner, @QNameId int fullname, int name) { + public PackageSymbol(Symbol owner, @QNameHash int fullname, int name) { super(IndexTree.PACKAGE, owner, name); myQualifiedName = fullname; } diff --git a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/Symbols.java b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/Symbols.java index a066a50ec7e8..f74d19c06a14 100644 --- a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/Symbols.java +++ b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/Symbols.java @@ -2,6 +2,7 @@ package com.intellij.psi.stubsHierarchy.impl; import com.intellij.psi.stubsHierarchy.impl.Symbol.ClassSymbol; import com.intellij.psi.stubsHierarchy.impl.Symbol.PackageSymbol; +import com.intellij.util.ArrayUtil; import gnu.trove.TIntObjectHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -10,7 +11,7 @@ import java.util.ArrayList; import java.util.List; public class Symbols { - public final PackageSymbol myRootPackage; + public final PackageSymbol myRootPackage = new PackageSymbol(null, 0, NameEnvironment.NO_NAME); protected final NameEnvironment myNameEnvironment = new NameEnvironment(); private final AnchorRepository myClassAnchors = new AnchorRepository(); @@ -18,14 +19,13 @@ public class Symbols { // fullName -> PackageSymbol private final TIntObjectHashMap myPackages = new TIntObjectHashMap<>(); // nameId -> ClassSymbols (used by global resolve) - private Object[] myClassSymbolsByNameId = new Object[0x8000]; + private TIntObjectHashMap myClassSymbolsByNameId = new TIntObjectHashMap<>(); protected Symbols() { - myRootPackage = new PackageSymbol(null, 0, NameEnvironment.NO_NAME); myPackages.put(0, myRootPackage); } - PackageSymbol enterPackage(@QNameId int qualifiedName, @ShortName int shortName, PackageSymbol owner) { + PackageSymbol enterPackage(@QNameHash int qualifiedName, @ShortName int shortName, PackageSymbol owner) { PackageSymbol p = myPackages.get(qualifiedName); if (p == null) { p = new PackageSymbol(owner, qualifiedName, shortName); @@ -35,17 +35,13 @@ public class Symbols { } @Nullable - PackageSymbol getPackage(@QNameId int qualifiedName) { + PackageSymbol getPackage(@QNameHash int qualifiedName) { return myPackages.get(qualifiedName); } @NotNull - ClassSymbol[] loadClass(@QNameId int name) { - return name >= myClassSymbolsByNameId.length ? ClassSymbol.EMPTY_ARRAY : getClassSymbols(name); - } - - private ClassSymbol[] getClassSymbols(int id) { - Object cs = myClassSymbolsByNameId[id]; + ClassSymbol[] getClassSymbols(@QNameHash int name) { + Object cs = myClassSymbolsByNameId.get(name); if (cs == null) { return ClassSymbol.EMPTY_ARRAY; } @@ -62,49 +58,27 @@ public class Symbols { Symbol owner, UnitInfo info, @CompactArray(QualifiedName.class) Object supers, - @QNameId int qualifiedName) { + @QNameHash int qualifiedName) { int anchorId = myClassAnchors.registerClass(fileId, stubId); ClassSymbol c = new ClassSymbol(anchorId, flags, owner, shortName, info, supers); myClassSymbols.add(c); - if (qualifiedName >= 0) { + if (qualifiedName != 0) { putClassByName(c, qualifiedName); } return c; } - private void putClassByName(ClassSymbol classSymbol, int nameId) { - ensureByNameCapacity(nameId); - Object cs = myClassSymbolsByNameId[nameId]; + private void putClassByName(ClassSymbol classSymbol, @QNameHash int nameId) { + Object cs = myClassSymbolsByNameId.get(nameId); if (cs == null) { - myClassSymbolsByNameId[nameId] = classSymbol; + myClassSymbolsByNameId.put(nameId, classSymbol); + } else if (cs instanceof ClassSymbol) { + myClassSymbolsByNameId.put(nameId, new ClassSymbol[]{(ClassSymbol)cs, classSymbol}); } else { - if (cs instanceof ClassSymbol) { - ClassSymbol c = (ClassSymbol)cs; - myClassSymbolsByNameId[nameId] = new ClassSymbol[]{c, classSymbol}; - } else { - ClassSymbol[] css = (ClassSymbol[])cs; - ClassSymbol[] newCss = new ClassSymbol[css.length + 1]; - System.arraycopy(css, 0, newCss, 0, css.length); - newCss[css.length] = classSymbol; - myClassSymbolsByNameId[nameId] = newCss; - } + myClassSymbolsByNameId.put(nameId, ArrayUtil.append((ClassSymbol[])cs, classSymbol)); } } - private void ensureByNameCapacity(int maxIndex) { - if (maxIndex >= myClassSymbolsByNameId.length) { - int newLength = calculateNewLength(myClassSymbolsByNameId.length, maxIndex); - Object[] result = new Object[newLength]; - System.arraycopy(myClassSymbolsByNameId, 0, result, 0, myClassSymbolsByNameId.length); - myClassSymbolsByNameId = result; - } - } - - private static int calculateNewLength(int currentLength, int maxIndex) { - while (currentLength < maxIndex + 1) currentLength *= 2; - return currentLength; - } - SingleClassHierarchy createHierarchy() { ClassSymbol[] array = myClassSymbols.toArray(ClassSymbol.EMPTY_ARRAY); myClassSymbols = null; diff --git a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/annotations.java b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/annotations.java index 0b7b09f32c50..9727110a2411 100644 --- a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/annotations.java +++ b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/annotations.java @@ -36,11 +36,11 @@ import java.lang.annotation.Target; } /** - * int id of a qualified name in a {@link NameEnvironment} + * int hash of a qualified name by {@link NameEnvironment} */ @Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE_USE) -@interface QNameId { } +@interface QNameHash { } /** * int hash of a qualified name part, produced by {@link IndexTree#hashIdentifier(String)}