diff --git a/jps/model/src/org/jetbrains/ether/RW.java b/jps/model/src/org/jetbrains/ether/RW.java index 5c930945dddc..6764ada467aa 100644 --- a/jps/model/src/org/jetbrains/ether/RW.java +++ b/jps/model/src/org/jetbrains/ether/RW.java @@ -1,11 +1,11 @@ package org.jetbrains.ether; import com.intellij.util.io.DataExternalizer; +import gnu.trove.TIntHashSet; +import gnu.trove.TIntProcedure; import java.io.*; import java.util.Collection; -import java.util.List; -import java.util.Map; /** * Created by IntelliJ IDEA. @@ -35,6 +35,27 @@ public class RW { } } + public static void save(final TIntHashSet x, final DataOutput out) { + try { + out.writeInt(x.size()); + x.forEach(new TIntProcedure() { + @Override + public boolean execute(int value) { + try { + out.writeInt(value); + return true; + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + }); + } + catch (IOException c) { + throw new RuntimeException(c); + } + } + public static void save(final Collection x, final DataExternalizer e, final DataOutput out) { try { out.writeInt(x.size()); @@ -76,6 +97,21 @@ public class RW { } } + public static TIntHashSet read(final TIntHashSet acc, final DataInput in) { + try { + final int size = in.readInt(); + + for (int i = 0; i Collection read(final DataExternalizer e, final Collection acc, final DataInput in) { try { final int size = in.readInt(); diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/ClassRepr.java b/jps/model/src/org/jetbrains/ether/dependencyView/ClassRepr.java index 2eaedf77c615..a4841f37872a 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/ClassRepr.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/ClassRepr.java @@ -4,13 +4,15 @@ import com.intellij.util.io.DataExternalizer; import groovyjarjarasm.asm.Opcodes; import org.jetbrains.ether.RW; -import javax.sql.rowset.Predicate; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.lang.annotation.ElementType; import java.lang.annotation.RetentionPolicy; -import java.util.*; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Set; /** * Created by IntelliJ IDEA. @@ -21,8 +23,8 @@ import java.util.*; */ public class ClassRepr extends Proto { private final DependencyContext context; - public final DependencyContext.S sourceFileName; - public final DependencyContext.S fileName; + public final int sourceFileName; + public final int fileName; public final TypeRepr.AbstractType superClass; public final Set interfaces; public final Set nestedClasses; @@ -32,7 +34,7 @@ public class ClassRepr extends Proto { public final Set fields; public final Set methods; - public final DependencyContext.S outerClassName; + public final int outerClassName; public final boolean isLocal; public String getFileName() { @@ -142,8 +144,8 @@ public class ClassRepr extends Proto { }; } - public DependencyContext.S[] getSupers() { - final DependencyContext.S[] result = new DependencyContext.S[interfaces.size() + 1]; + public int[] getSupers() { + final int[] result = new int[interfaces.size() + 1]; result[0] = ((TypeRepr.ClassType)superClass).className; @@ -171,20 +173,15 @@ public class ClassRepr extends Proto { } } - public ClassRepr(final DependencyContext context, - final int a, - final DependencyContext.S sn, - final DependencyContext.S fn, - final DependencyContext.S n, - final DependencyContext.S sig, - final DependencyContext.S sup, + public ClassRepr(final DependencyContext context, final int a, final int sn, final int fn, final int n, final int sig, + final int sup, final String[] i, final Collection ns, final Set f, final Set m, final Set targets, final RetentionPolicy policy, - final DependencyContext.S outerClassName, + final int outerClassName, final boolean localClassFlag) { super(a, sig, n); this.context = context; @@ -205,8 +202,8 @@ public class ClassRepr extends Proto { super(in); try { this.context = context; - fileName = new DependencyContext.S(in); - sourceFileName = new DependencyContext.S(in); + fileName = in.readInt(); + sourceFileName = in.readInt(); superClass = TypeRepr.externalizer(context).read(in); interfaces = (Set)RW.read(TypeRepr.externalizer(context), new HashSet(), in); nestedClasses = (Set)RW.read(TypeRepr.externalizer(context), new HashSet(), in); @@ -218,7 +215,7 @@ public class ClassRepr extends Proto { policy = s.length() == 0 ? null : RetentionPolicy.valueOf(s); - outerClassName = new DependencyContext.S(in); + outerClassName = in.readInt(); isLocal = in.readBoolean(); } catch (IOException e) { @@ -230,8 +227,8 @@ public class ClassRepr extends Proto { public void save(final DataOutput out) { try { super.save(out); - fileName.save(out); - sourceFileName.save(out); + out.writeInt(fileName); + out.writeInt(sourceFileName); superClass.save(out); RW.save(interfaces, out); RW.save(nestedClasses, out); @@ -239,7 +236,7 @@ public class ClassRepr extends Proto { RW.save(methods, out); RW.save(targets, UsageRepr.AnnotationUsage.elementTypeExternalizer, out); out.writeUTF(policy == null ? "" : policy.toString()); - outerClassName.save(out); + out.writeInt(outerClassName); out.writeBoolean(isLocal); } catch (IOException e) { @@ -258,24 +255,22 @@ public class ClassRepr extends Proto { ClassRepr classRepr = (ClassRepr)o; - if (fileName != null ? !fileName.equals(classRepr.fileName) : classRepr.fileName != null) return false; - if (name != null ? !name.equals(classRepr.name) : classRepr.name != null) return false; + if (fileName != classRepr.fileName) return false; + if (name != classRepr.name) return false; return true; } @Override public int hashCode() { - int result = fileName != null ? fileName.hashCode() : 0; - result = 31 * result + (name != null ? name.hashCode() : 0); - return result; + return 31 * fileName + name; } public UsageRepr.Usage createUsage() { return UsageRepr.createClassUsage(context, name); } - public DependencyContext.S getSourceFileName() { + public int getSourceFileName() { return sourceFileName; } @@ -283,7 +278,7 @@ public class ClassRepr extends Proto { return getPackageName(name); } - public String getPackageName(final DependencyContext.S s) { + public String getPackageName(final int s) { return getPackageName(context.getValue(s)); } @@ -298,9 +293,9 @@ public class ClassRepr extends Proto { return raw.substring(0, index); } - public FieldRepr findField(final DependencyContext.S name) { + public FieldRepr findField(final int name) { for (FieldRepr f : fields) { - if (f.name.equals(name)) { + if (f.name == name) { return f; } } diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/ClassfileAnalyzer.java b/jps/model/src/org/jetbrains/ether/dependencyView/ClassfileAnalyzer.java index 91d6bf4c2f14..524669c92961 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/ClassfileAnalyzer.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/ClassfileAnalyzer.java @@ -1,6 +1,7 @@ package org.jetbrains.ether.dependencyView; import com.intellij.openapi.util.Pair; +import gnu.trove.TIntHashSet; import org.jetbrains.asm4.*; import org.jetbrains.asm4.signature.SignatureReader; import org.jetbrains.asm4.signature.SignatureVisitor; @@ -89,13 +90,19 @@ class ClassfileAnalyzer { private final TypeRepr.ClassType type; private final ElementType target; - private final Set usedArguments = new HashSet(); + private final TIntHashSet myUsedArguments = new TIntHashSet(); private AnnotationCrawler(final TypeRepr.ClassType type, final ElementType target) { super(Opcodes.ASM4); this.type = type; this.target = target; - annotationTargets.put(type, target); + final Set targets = myAnnotationTargets.get(type); + if (targets == null) { + myAnnotationTargets.put(type, EnumSet.of(target)); + } + else { + targets.add(target); + } usages.addUsage(context.get(classNameHolder.get()), UsageRepr.createClassUsage(context, type.className)); } @@ -144,25 +151,25 @@ class ClassfileAnalyzer { } public void visit(String name, Object value) { - final DependencyContext.S residence = context.get(classNameHolder.get()); + final int residence = context.get(classNameHolder.get()); final String methodDescr = getMethodDescr(value); - final DependencyContext.S methodName = context.get(name); + final int methodName = context.get(name); usages.addUsage(residence, UsageRepr.createMethodUsage(context, methodName, type.className, methodDescr)); usages.addUsage(residence, UsageRepr.createMetaMethodUsage(context, methodName, type.className, methodDescr)); - usedArguments.add(methodName); + myUsedArguments.add(methodName); } public void visitEnum(String name, String desc, String value) { - final DependencyContext.S residence = context.get(classNameHolder.get()); - final DependencyContext.S methodName = context.get(name); + final int residence = context.get(classNameHolder.get()); + final int methodName = context.get(name); final String methodDescr = "()" + desc; usages.addUsage(residence, UsageRepr.createMethodUsage(context, methodName, type.className, methodDescr)); usages.addUsage(residence, UsageRepr.createMetaMethodUsage(context, methodName, type.className, methodDescr)); - usedArguments.add(methodName); + myUsedArguments.add(methodName); } public AnnotationVisitor visitAnnotation(String name, String desc) { @@ -170,18 +177,18 @@ class ClassfileAnalyzer { } public AnnotationVisitor visitArray(String name) { - usedArguments.add(context.get(name)); + myUsedArguments.add(context.get(name)); return this; } public void visitEnd() { - final Set s = annotationArguments.get(type); + final TIntHashSet s = myAnnotationArguments.get(type); if (s == null) { - annotationArguments.put(type, usedArguments); + myAnnotationArguments.put(type, myUsedArguments); } else { - s.retainAll(usedArguments); + s.retainAll(myUsedArguments.toArray()); } } } @@ -257,13 +264,13 @@ class ClassfileAnalyzer { Boolean takeIntoAccount = false; - final DependencyContext.S fileName; + final int fileName; int access; - DependencyContext.S name; + int name; String superClass; String[] interfaces; String signature; - DependencyContext.S sourceFile; + int sourceFile; final Holder classNameHolder = new Holder(); final Holder outerClassName = new Holder(); @@ -281,17 +288,10 @@ class ClassfileAnalyzer { final Set targets = new HashSet(); RetentionPolicy policy = null; - private TransientMultiMaplet.CollectionConstructor elementTypeSetConstructor = new TransientMultiMaplet.CollectionConstructor() { - public Set create() { - return new HashSet(); - } - }; + final Map myAnnotationArguments = new HashMap(); + final Map> myAnnotationTargets = new HashMap>(); - final Map> annotationArguments = new HashMap>(); - final TransientMultiMaplet annotationTargets = - new TransientMultiMaplet(elementTypeSetConstructor); - - public ClassCrawler(final DependencyContext.S fn) { + public ClassCrawler(final int fn) { super(Opcodes.ASM4); fileName = fn; } @@ -302,8 +302,8 @@ class ClassfileAnalyzer { public Pair>> getResult() { final ClassRepr repr = - takeIntoAccount ? new ClassRepr(context, access, sourceFile, fileName, name, context.get(signature), context.get(superClass), interfaces, nestedClasses, fields, - methods, targets, policy, context.get(outerClassName.get()), localClassFlag.get()) : null; + takeIntoAccount ? new ClassRepr( + context, access, sourceFile, fileName, name, context.get(signature), context.get(superClass), interfaces, nestedClasses, fields, methods, targets, policy, context.get(outerClassName.get()), localClassFlag.get()) : null; if (repr != null) { repr.updateClassUsages(context, usages); @@ -343,9 +343,10 @@ class ClassfileAnalyzer { @Override public void visitEnd() { - for (TypeRepr.ClassType type : annotationTargets.keyCollection()) { - final Collection targets = annotationTargets.get(type); - final Set usedArguments = annotationArguments.get(type); + for (Map.Entry> entry : myAnnotationTargets.entrySet()) { + final TypeRepr.ClassType type = entry.getKey(); + final Collection targets = entry.getValue(); + final TIntHashSet usedArguments = myAnnotationArguments.get(type); annotationUsages.add(UsageRepr.createAnnotationUsage(context, type, usedArguments, targets)); } @@ -495,9 +496,9 @@ class ClassfileAnalyzer { @Override public void visitMethodInsn(int opcode, String owner, String name, String desc) { - final DependencyContext.S residence = context.get(classNameHolder.get()); - final DependencyContext.S methodName = context.get(name); - final DependencyContext.S methodOwner = context.get(owner); + final int residence = context.get(classNameHolder.get()); + final int methodName = context.get(name); + final int methodOwner = context.get(owner); usages.addUsage(residence, UsageRepr.createMethodUsage(context, methodName, methodOwner, desc)); usages.addUsage(residence, UsageRepr.createMetaMethodUsage(context, methodName, methodOwner, desc)); @@ -524,7 +525,7 @@ class ClassfileAnalyzer { } } - public Pair>> analyze(final DependencyContext.S fileName, final ClassReader cr) { + public Pair>> analyze(final int fileName, final ClassReader cr) { final ClassCrawler visitor = new ClassCrawler(fileName); cr.accept(visitor, 0); diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/CollectionFactory.java b/jps/model/src/org/jetbrains/ether/dependencyView/CollectionFactory.java new file mode 100644 index 000000000000..dc0f4a0b8952 --- /dev/null +++ b/jps/model/src/org/jetbrains/ether/dependencyView/CollectionFactory.java @@ -0,0 +1,11 @@ +package org.jetbrains.ether.dependencyView; + +import java.util.Collection; + +/** +* @author Eugene Zhuravlev +* Date: 4/3/12 +*/ +public interface CollectionFactory { + Collection create(); +} diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/DependencyContext.java b/jps/model/src/org/jetbrains/ether/dependencyView/DependencyContext.java index 75756ad6f05e..d1f711cf58c4 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/DependencyContext.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/DependencyContext.java @@ -1,12 +1,10 @@ package org.jetbrains.ether.dependencyView; import com.intellij.openapi.util.io.FileUtil; -import com.intellij.util.io.InlineKeyDescriptor; -import com.intellij.util.io.KeyDescriptor; import com.intellij.util.io.PersistentStringEnumerator; -import org.jetbrains.ether.RW; -import java.io.*; +import java.io.File; +import java.io.IOException; import java.util.HashMap; import java.util.Map; @@ -64,92 +62,20 @@ class DependencyContext { myEnumerator = new PersistentStringEnumerator(file, true); } - static KeyDescriptor descriptorS = new InlineKeyDescriptor() { - @Override - public S fromInt(int n) { - return new S(n); - } - - @Override - public int toInt(S s) { - return s.index; - } - }; - - static class S implements Comparable, RW.Writable { - public final int index; - - S(final DataInput in){ - try{ - index = in.readInt(); - } - catch (IOException e){ - throw new RuntimeException(e); - } - } - - private S(final int i) { - index = i; - } - - public S(final BufferedReader r) { - index = RW.readInt(r); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - S s = (S)o; - - if (index != s.index) return false; - - return true; - } - - @Override - public int hashCode() { - return index; - } - - public int compareTo(S o) { - return index - o.index; - } - - public void write(BufferedWriter w) { - RW.writeln(w, Integer.toString(index)); - } - - public void save(final DataOutput out){ - try{ - out.writeInt(index); - } - catch (IOException e){ - throw new RuntimeException(e); - } - } - - @Override - public String toString() { - return Integer.toString(index); - } - } - - public String getValue(final S s) { + public String getValue(final int s) { try { - return myEnumerator.valueOf(s.index); + return myEnumerator.valueOf(s); } catch (IOException e) { throw new RuntimeException(e); } } - public S get(final String s) { + public int get(final String s) { try { final int i = s == null ? myEnumerator.enumerate("") : myEnumerator.enumerate(s); - return new S(i); + return i; } catch (IOException e) { throw new RuntimeException(e); @@ -169,10 +95,10 @@ class DependencyContext { myEnumerator.force(); } - public Logger getLogger(final com.intellij.openapi.diagnostic.Logger log) { - return new Logger() { + public Logger getLogger(final com.intellij.openapi.diagnostic.Logger log) { + return new Logger() { @Override - public void debug(String comment, S s) { + public void debug(String comment, Integer s) { if (log.isDebugEnabled()) { log.debug(comment + getValue(s)); } diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/FieldRepr.java b/jps/model/src/org/jetbrains/ether/dependencyView/FieldRepr.java index feefafffe6f1..bf3e1941b2e7 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/FieldRepr.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/FieldRepr.java @@ -1,9 +1,7 @@ package org.jetbrains.ether.dependencyView; import com.intellij.util.io.DataExternalizer; -import org.jetbrains.ether.RW; -import java.io.BufferedReader; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; @@ -16,16 +14,11 @@ import java.io.IOException; * To change this template use File | Settings | File Templates. */ class FieldRepr extends ProtoMember { - public void updateClassUsages(final DependencyContext context, final DependencyContext.S owner, final UsageRepr.Cluster s) { + public void updateClassUsages(final DependencyContext context, final int owner, final UsageRepr.Cluster s) { type.updateClassUsages(context, owner, s); } - public FieldRepr(final DependencyContext context, - final int a, - final DependencyContext.S n, - final DependencyContext.S d, - final DependencyContext.S s, - final Object v) { + public FieldRepr(final DependencyContext context, final int a, final int n, final int d, final int s, final Object v) { super(a, s, n, TypeRepr.getType(context, d), v); } @@ -40,12 +33,12 @@ class FieldRepr extends ProtoMember { final FieldRepr fieldRepr = (FieldRepr)o; - return name.equals(fieldRepr.name); + return name == fieldRepr.name; } @Override public int hashCode() { - return 31 * name.hashCode(); + return 31 * name; } public static DataExternalizer externalizer(final DependencyContext context) { @@ -62,11 +55,11 @@ class FieldRepr extends ProtoMember { }; } - public UsageRepr.Usage createUsage(final DependencyContext context, final DependencyContext.S owner) { + public UsageRepr.Usage createUsage(final DependencyContext context, final int owner) { return UsageRepr.createFieldUsage(context, name, owner, context.get(type.getDescr(context))); } - public UsageRepr.Usage createAssignUsage(final DependencyContext context, final DependencyContext.S owner) { + public UsageRepr.Usage createAssignUsage(final DependencyContext context, final int owner) { return UsageRepr.createFieldAssignUsage(context, name, owner, context.get(type.getDescr(context))); } } diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/Maplet.java b/jps/model/src/org/jetbrains/ether/dependencyView/IntIntMaplet.java similarity index 72% rename from jps/model/src/org/jetbrains/ether/dependencyView/Maplet.java rename to jps/model/src/org/jetbrains/ether/dependencyView/IntIntMaplet.java index 9901cadc9361..2a7d92054c3b 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/Maplet.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/IntIntMaplet.java @@ -15,8 +15,7 @@ */ package org.jetbrains.ether.dependencyView; -import java.util.Collection; -import java.util.Map; +import gnu.trove.TIntIntProcedure; /** * Created by IntelliJ IDEA. @@ -25,15 +24,13 @@ import java.util.Map; * Time: 23:48 * To change this template use File | Settings | File Templates. */ -interface Maplet { - boolean containsKey(final Object key); - V get(final Object key); - void put(final K key, final V value); - void putAll(Maplet m); - void remove(final Object key); +interface IntIntMaplet { + boolean containsKey(final int key); + int get(final int key); + void put(final int key, final int value); + void putAll(IntIntMaplet m); + void remove(final int key); void close(); - Collection keyCollection(); - Collection> entrySet(); - + void forEachEntry(TIntIntProcedure proc); void flush(boolean memoryCachesOnly); } diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/IntIntMultiMaplet.java b/jps/model/src/org/jetbrains/ether/dependencyView/IntIntMultiMaplet.java new file mode 100644 index 000000000000..1efb97a55f43 --- /dev/null +++ b/jps/model/src/org/jetbrains/ether/dependencyView/IntIntMultiMaplet.java @@ -0,0 +1,42 @@ +/* + * Copyright 2000-2011 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 org.jetbrains.ether.dependencyView; + +import gnu.trove.TIntHashSet; +import gnu.trove.TIntObjectProcedure; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: 03.11.11 + * Time: 21:01 + * To change this template use File | Settings | File Templates. + */ +interface IntIntMultiMaplet { + boolean containsKey(final int key); + TIntHashSet get(final int key); + void put(final int key, final int value); + void put(final int key, final TIntHashSet value); + void replace(final int key, final TIntHashSet value); + void putAll(IntIntMultiMaplet m); + void replaceAll(IntIntMultiMaplet m); + void remove(final int key); + void removeFrom(final int key, final int value); + void removeAll(final int key, final TIntHashSet values); + void close(); + void forEachEntry(TIntObjectProcedure proc); + void flush(boolean memoryCachesOnly); +} diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/PersistentMaplet.java b/jps/model/src/org/jetbrains/ether/dependencyView/IntIntPersistentMaplet.java similarity index 55% rename from jps/model/src/org/jetbrains/ether/dependencyView/PersistentMaplet.java rename to jps/model/src/org/jetbrains/ether/dependencyView/IntIntPersistentMaplet.java index e2aa19570405..b472ad772531 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/PersistentMaplet.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/IntIntPersistentMaplet.java @@ -15,17 +15,18 @@ */ package org.jetbrains.ether.dependencyView; +import com.intellij.util.Processor; import com.intellij.util.containers.SLRUCache; import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.KeyDescriptor; import com.intellij.util.io.PersistentHashMap; +import gnu.trove.TIntIntProcedure; import org.jetbrains.annotations.NotNull; +import java.io.DataInput; +import java.io.DataOutput; import java.io.File; import java.io.IOException; -import java.util.Collection; -import java.util.LinkedList; -import java.util.Map; /** * Created by IntelliJ IDEA. @@ -34,21 +35,31 @@ import java.util.Map; * Time: 0:05 * To change this template use File | Settings | File Templates. */ -public class PersistentMaplet implements Maplet { +public class IntIntPersistentMaplet implements IntIntMaplet { private static final Object NULL_OBJ = new Object(); private static final int CACHE_SIZE = 512; - private final PersistentHashMap myMap; - private final SLRUCache myCache; + private final PersistentHashMap myMap; + private final SLRUCache myCache; - public PersistentMaplet(final File file, final KeyDescriptor k, final DataExternalizer v) { + public IntIntPersistentMaplet(final File file, final KeyDescriptor k) { try { - myMap = new PersistentHashMap(file, k, v); - myCache = new SLRUCache(CACHE_SIZE, CACHE_SIZE) { + myMap = new PersistentHashMap(file, k, new DataExternalizer() { + @Override + public void save(DataOutput out, Integer value) throws IOException { + out.writeInt(value); + } + + @Override + public Integer read(DataInput in) throws IOException { + return in.readInt(); + } + }); + myCache = new SLRUCache(CACHE_SIZE, CACHE_SIZE) { @NotNull @Override - public Object createValue(K key) { + public Object createValue(Integer key) { try { - final V v1 = myMap.get(key); + final Integer v1 = myMap.get(key); return v1 == null? NULL_OBJ : v1; } catch (IOException e) { @@ -63,9 +74,9 @@ public class PersistentMaplet implements Maplet { } @Override - public boolean containsKey(final Object key) { + public boolean containsKey(final int key) { try { - return myMap.containsMapping((K)key); + return myMap.containsMapping(key); } catch (IOException e) { throw new RuntimeException(e); @@ -73,13 +84,13 @@ public class PersistentMaplet implements Maplet { } @Override - public V get(final Object key) { - final Object obj = myCache.get((K)key); - return obj == NULL_OBJ? null : (V)obj; + public int get(final int key) { + final Object obj = myCache.get(key); + return obj == NULL_OBJ? -1 : (Integer)obj; } @Override - public void put(final K key, final V value) { + public void put(final int key, final int value) { try { myCache.remove(key); myMap.put(key, value); @@ -90,18 +101,21 @@ public class PersistentMaplet implements Maplet { } @Override - public void putAll(final Maplet m) { - for (Map.Entry e : m.entrySet()) { - put(e.getKey(), e.getValue()); - } + public void putAll(final IntIntMaplet m) { + m.forEachEntry(new TIntIntProcedure() { + @Override + public boolean execute(int key, int value) { + put(key, value); + return true; + } + }); } @Override - public void remove(final Object key) { + public void remove(final int key) { try { - final K _key = (K)key; - myCache.remove(_key); - myMap.remove(_key); + myCache.remove(key); + myMap.remove(key); } catch (IOException e) { throw new RuntimeException(e); @@ -131,44 +145,20 @@ public class PersistentMaplet implements Maplet { } @Override - public Collection keyCollection() { + public void forEachEntry(final TIntIntProcedure proc) { try { - return myMap.getAllKeysWithExistingMapping(); - } - catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public Collection> entrySet() { - final Collection> result = new LinkedList>(); - - try { - for (final K key : myMap.getAllKeysWithExistingMapping()) { - final V value = get(key); - - final Map.Entry entry = new Map.Entry() { - @Override - public K getKey() { - return key; + myMap.processKeysWithExistingMapping(new Processor() { + @Override + public boolean process(Integer key) { + try { + final Integer value = myMap.get(key); + return value == null? proc.execute(key, -1) : proc.execute(key, value); } - - @Override - public V getValue() { - return value; + catch (IOException e) { + throw new RuntimeException(e); } - - @Override - public V setValue(V value) { - return null; - } - }; - - result.add(entry); - } - - return result; + } + }); } catch (IOException e) { throw new RuntimeException(e); diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/IntIntPersistentMultiMaplet.java b/jps/model/src/org/jetbrains/ether/dependencyView/IntIntPersistentMultiMaplet.java new file mode 100644 index 000000000000..da4118606813 --- /dev/null +++ b/jps/model/src/org/jetbrains/ether/dependencyView/IntIntPersistentMultiMaplet.java @@ -0,0 +1,302 @@ +/* + * Copyright 2000-2011 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 org.jetbrains.ether.dependencyView; + +import com.intellij.openapi.util.Ref; +import com.intellij.util.Processor; +import com.intellij.util.containers.SLRUCache; +import com.intellij.util.io.DataExternalizer; +import com.intellij.util.io.KeyDescriptor; +import com.intellij.util.io.PersistentHashMap; +import gnu.trove.TIntHashSet; +import gnu.trove.TIntObjectProcedure; +import gnu.trove.TIntProcedure; +import org.jetbrains.annotations.NotNull; + +import java.io.*; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: 08.03.11 + * Time: 15:38 + * To change this template use File | Settings | File Templates. + */ +class IntIntPersistentMultiMaplet implements IntIntMultiMaplet { + private static final TIntHashSet NULL_COLLECTION = new TIntHashSet(); + private static final int CACHE_SIZE = 128; + private final PersistentHashMap myMap; + private final SLRUCache myCache; + + public IntIntPersistentMultiMaplet(final File file, final KeyDescriptor keyExternalizer) throws IOException { + myMap = new PersistentHashMap(file, keyExternalizer, new IntSetExternalizer()); + myCache = new SLRUCache(CACHE_SIZE, CACHE_SIZE) { + @NotNull + @Override + public TIntHashSet createValue(Integer key) { + try { + final TIntHashSet collection = myMap.get(key); + return collection == null? NULL_COLLECTION : collection; + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + }; + } + + @Override + public boolean containsKey(final int key) { + try { + return myMap.containsMapping(key); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public TIntHashSet get(final int key) { + final TIntHashSet collection = myCache.get(key); + return collection == NULL_COLLECTION? null : collection; + } + + @Override + public void replace(int key, TIntHashSet value) { + try { + myCache.remove(key); + if (value == null) { + myMap.remove(key); + } + else { + myMap.put(key, value); + } + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public void put(final int key, final TIntHashSet value) { + try { + myCache.remove(key); + myMap.appendData(key, new PersistentHashMap.ValueDataAppender() { + public void append(final DataOutput out) throws IOException { + final Ref exRef = new Ref(); + value.forEach(new TIntProcedure() { + @Override + public boolean execute(int value) { + try { + out.writeInt(value); + } + catch (IOException e) { + exRef.set(e); + return false; + } + return true; + } + }); + final IOException exception = exRef.get(); + if (exception != null) { + throw exception; + } + } + }); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public void put(final int key, final int value) { + try { + myCache.remove(key); + myMap.appendData(key, new PersistentHashMap.ValueDataAppender() { + public void append(final DataOutput out) throws IOException { + out.writeInt(value); + } + }); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public void removeAll(int key, TIntHashSet values) { + try { + final TIntHashSet collection = myCache.get(key); + + if (collection != NULL_COLLECTION) { + final Ref isChanged = new Ref(Boolean.FALSE); + values.forEach(new TIntProcedure() { + @Override + public boolean execute(int value) { + if (collection.remove(value)) { + isChanged.set(Boolean.TRUE); + } + return true; + } + }); + if (isChanged.get()) { + myCache.remove(key); + if (collection.isEmpty()) { + myMap.remove(key); + } + else { + myMap.put(key, collection); + } + } + } + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public void removeFrom(final int key, final int value) { + try { + final TIntHashSet collection = myCache.get(key); + if (collection != NULL_COLLECTION) { + if (collection.remove(value)) { + myCache.remove(key); + if (collection.isEmpty()) { + myMap.remove(key); + } + else { + myMap.put(key, collection); + } + } + } + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public void remove(final int key) { + try { + myCache.remove(key); + myMap.remove(key); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public void putAll(IntIntMultiMaplet m) { + m.forEachEntry(new TIntObjectProcedure() { + @Override + public boolean execute(int key, TIntHashSet value) { + put(key, value); + return true; + } + }); + } + + @Override + public void replaceAll(IntIntMultiMaplet m) { + m.forEachEntry(new TIntObjectProcedure() { + @Override + public boolean execute(int key, TIntHashSet value) { + replace(key, value); + return true; + } + }); + } + + @Override + public void close() { + try { + myCache.clear(); + myMap.close(); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + + public void flush(boolean memoryCachesOnly) { + if (memoryCachesOnly) { + if (myMap.isDirty()) { + myMap.dropMemoryCaches(); + } + } + else { + myMap.force(); + } + } + + @Override + public void forEachEntry(final TIntObjectProcedure procedure) { + try { + myMap.processKeysWithExistingMapping(new Processor() { + @Override + public boolean process(Integer key) { + try { + return procedure.execute(key, myMap.get(key)); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + }); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static class IntSetExternalizer implements DataExternalizer { + + @Override + public void save(final DataOutput out, final TIntHashSet value) throws IOException { + final Ref exRef = new Ref(null); + value.forEach(new TIntProcedure() { + @Override + public boolean execute(int elem) { + try { + out.writeInt(elem); + } + catch (IOException e) { + exRef.set(e); + return false; + } + return true; + } + }); + final IOException exception = exRef.get(); + if (exception != null) { + throw exception; + } + } + + @Override + public TIntHashSet read(final DataInput in) throws IOException { + final TIntHashSet result = new TIntHashSet(); + final DataInputStream stream = (DataInputStream)in; + while (stream.available() > 0) { + result.add(in.readInt()); + } + return result; + } + } +} diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/TransientMaplet.java b/jps/model/src/org/jetbrains/ether/dependencyView/IntIntTransientMaplet.java similarity index 61% rename from jps/model/src/org/jetbrains/ether/dependencyView/TransientMaplet.java rename to jps/model/src/org/jetbrains/ether/dependencyView/IntIntTransientMaplet.java index 1521310f5a1d..bbddb9becb47 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/TransientMaplet.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/IntIntTransientMaplet.java @@ -15,10 +15,8 @@ */ package org.jetbrains.ether.dependencyView; -import com.intellij.util.containers.hash.HashMap; - -import java.util.Collection; -import java.util.Map; +import gnu.trove.TIntIntHashMap; +import gnu.trove.TIntIntProcedure; /** * Created by IntelliJ IDEA. @@ -27,33 +25,37 @@ import java.util.Map; * Time: 0:00 * To change this template use File | Settings | File Templates. */ -public class TransientMaplet implements Maplet{ - private final Map myMap = new HashMap(); +public class IntIntTransientMaplet implements IntIntMaplet { + private final TIntIntHashMap myMap = new TIntIntHashMap(); @Override - public boolean containsKey(final Object key) { + public boolean containsKey(final int key) { return myMap.containsKey(key); } @Override - public V get(final Object key) { + public int get(final int key) { return myMap.get(key); } @Override - public void put(final K key, final V value) { + public void put(final int key, final int value) { myMap.put(key, value); } @Override - public void putAll(final Maplet m) { - for (Map.Entry e : m.entrySet()) { - myMap.put(e.getKey(), e.getValue()); - } + public void putAll(final IntIntMaplet m) { + m.forEachEntry(new TIntIntProcedure() { + @Override + public boolean execute(int key, int value) { + myMap.put(key, value); + return true; + } + }); } @Override - public void remove(final Object key) { + public void remove(final int key) { myMap.remove(key); } @@ -66,12 +68,7 @@ public class TransientMaplet implements Maplet{ } @Override - public Collection keyCollection() { - return myMap.keySet(); - } - - @Override - public Collection> entrySet() { - return myMap.entrySet(); + public void forEachEntry(TIntIntProcedure proc) { + myMap.forEachEntry(proc); } } diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/IntIntTransientMultiMaplet.java b/jps/model/src/org/jetbrains/ether/dependencyView/IntIntTransientMultiMaplet.java new file mode 100644 index 000000000000..c089ca070394 --- /dev/null +++ b/jps/model/src/org/jetbrains/ether/dependencyView/IntIntTransientMultiMaplet.java @@ -0,0 +1,137 @@ +package org.jetbrains.ether.dependencyView; + +import gnu.trove.TIntHashSet; +import gnu.trove.TIntObjectHashMap; +import gnu.trove.TIntObjectProcedure; +import gnu.trove.TIntProcedure; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: 08.03.11 + * Time: 15:38 + * To change this template use File | Settings | File Templates. + */ +class IntIntTransientMultiMaplet implements IntIntMultiMaplet { + private final TIntObjectHashMap myMap = new TIntObjectHashMap(); + + + @Override + public boolean containsKey(final int key) { + return myMap.containsKey(key); + } + + @Override + public TIntHashSet get(final int key) { + return myMap.get(key); + } + + @Override + public void putAll(IntIntMultiMaplet m) { + m.forEachEntry(new TIntObjectProcedure() { + @Override + public boolean execute(int key, TIntHashSet values) { + put(key, values); + return true; + } + }); + } + + @Override + public void put(final int key, final TIntHashSet value) { + final TIntHashSet x = myMap.get(key); + if (x == null) { + myMap.put(key, value); + } + else { + value.forEach(new TIntProcedure() { + @Override + public boolean execute(int value) { + x.add(value); + return true; + } + }); + } + } + + @Override + public void replace(int key, TIntHashSet value) { + if (value == null) { + myMap.remove(key); + } + else { + myMap.put(key, value); + } + } + + @Override + public void put(final int key, final int value) { + final TIntHashSet collection = myMap.get(key); + if (collection == null) { + final TIntHashSet x = new TIntHashSet(); + x.add(value); + myMap.put(key, x); + } + else { + collection.add(value); + } + } + + @Override + public void removeFrom(final int key, final int value) { + final TIntHashSet collection = myMap.get(key); + if (collection != null) { + if (collection.remove(value)) { + if (collection.isEmpty()) { + myMap.remove(key); + } + } + } + } + + @Override + public void removeAll(int key, TIntHashSet values) { + final TIntHashSet collection = myMap.get(key); + if (collection != null) { + values.forEach(new TIntProcedure() { + @Override + public boolean execute(int value) { + collection.remove(value); + return true; + } + }); + if (collection.isEmpty()) { + myMap.remove(key); + } + } + } + + @Override + public void remove(final int key) { + myMap.remove(key); + } + + @Override + public void replaceAll(IntIntMultiMaplet m) { + m.forEachEntry(new TIntObjectProcedure() { + @Override + public boolean execute(int key, TIntHashSet value) { + replace(key, value); + return true; + } + }); + } + + @Override + public void forEachEntry(TIntObjectProcedure procedure) { + myMap.forEachEntry(procedure); + } + + @Override + public void close(){ + myMap.clear(); // free memory + } + + public void flush(boolean memoryCachesOnly) { + } +} diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/MultiMaplet.java b/jps/model/src/org/jetbrains/ether/dependencyView/IntObjectMultiMaplet.java similarity index 59% rename from jps/model/src/org/jetbrains/ether/dependencyView/MultiMaplet.java rename to jps/model/src/org/jetbrains/ether/dependencyView/IntObjectMultiMaplet.java index 15a2875086e3..dc76abcdb5ea 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/MultiMaplet.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/IntObjectMultiMaplet.java @@ -15,8 +15,9 @@ */ package org.jetbrains.ether.dependencyView; +import gnu.trove.TIntObjectProcedure; + import java.util.Collection; -import java.util.Map; /** * Created by IntelliJ IDEA. @@ -25,20 +26,19 @@ import java.util.Map; * Time: 21:01 * To change this template use File | Settings | File Templates. */ -interface MultiMaplet { - boolean containsKey(final K key); - Collection get(final K key); - void put(final K key, final V value); - void put(final K key, final Collection value); - void replace(final K key, final Collection value); - void putAll(MultiMaplet m); - void replaceAll(MultiMaplet m); - void remove(final K key); - void removeFrom(final K key, final V value); - void removeAll(final K key, final Collection value); +interface IntObjectMultiMaplet { + boolean containsKey(final int key); + Collection get(final int key); + void put(final int key, final V value); + void put(final int key, final Collection value); + void replace(final int key, final Collection value); + void putAll(IntObjectMultiMaplet m); + void replaceAll(IntObjectMultiMaplet m); + void remove(final int key); + void removeFrom(final int key, final V value); + void removeAll(final int key, final Collection value); void close(); - Collection keyCollection(); - Collection>> entrySet(); + void forEachEntry(TIntObjectProcedure> procedure); void flush(boolean memoryCachesOnly); } diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/PersistentMultiMaplet.java b/jps/model/src/org/jetbrains/ether/dependencyView/IntObjectPersistentMultiMaplet.java similarity index 65% rename from jps/model/src/org/jetbrains/ether/dependencyView/PersistentMultiMaplet.java rename to jps/model/src/org/jetbrains/ether/dependencyView/IntObjectPersistentMultiMaplet.java index d4369902c98b..31bab1fb6222 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/PersistentMultiMaplet.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/IntObjectPersistentMultiMaplet.java @@ -15,17 +15,17 @@ */ package org.jetbrains.ether.dependencyView; +import com.intellij.util.Processor; import com.intellij.util.containers.SLRUCache; import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.KeyDescriptor; import com.intellij.util.io.PersistentHashMap; +import gnu.trove.TIntObjectProcedure; import org.jetbrains.annotations.NotNull; import java.io.*; import java.util.Collection; import java.util.Collections; -import java.util.LinkedList; -import java.util.Map; /** * Created by IntelliJ IDEA. @@ -34,23 +34,23 @@ import java.util.Map; * Time: 15:38 * To change this template use File | Settings | File Templates. */ -class PersistentMultiMaplet implements MultiMaplet { +class IntObjectPersistentMultiMaplet implements IntObjectMultiMaplet { private static final Collection NULL_COLLECTION = Collections.emptySet(); private static final int CACHE_SIZE = 128; - private final PersistentHashMap> myMap; + private final PersistentHashMap> myMap; private final DataExternalizer myValueExternalizer; - private final SLRUCache myCache; + private final SLRUCache myCache; - public PersistentMultiMaplet(final File file, - final KeyDescriptor keyExternalizer, - final DataExternalizer valueExternalizer, - final TransientMultiMaplet.CollectionConstructor collectionFactory) throws IOException { + public IntObjectPersistentMultiMaplet(final File file, + final KeyDescriptor keyExternalizer, + final DataExternalizer valueExternalizer, + final CollectionFactory collectionFactory) throws IOException { myValueExternalizer = valueExternalizer; - myMap = new PersistentHashMap>(file, keyExternalizer, new CollectionDataExternalizer(valueExternalizer, collectionFactory)); - myCache = new SLRUCache(CACHE_SIZE, CACHE_SIZE) { + myMap = new PersistentHashMap>(file, keyExternalizer, new CollectionDataExternalizer(valueExternalizer, collectionFactory)); + myCache = new SLRUCache(CACHE_SIZE, CACHE_SIZE) { @NotNull @Override - public Collection createValue(K key) { + public Collection createValue(Integer key) { try { final Collection collection = myMap.get(key); return collection == null? NULL_COLLECTION : collection; @@ -64,7 +64,7 @@ class PersistentMultiMaplet implements MultiMaplet { @Override - public boolean containsKey(final K key) { + public boolean containsKey(final int key) { try { return myMap.containsMapping(key); } @@ -74,13 +74,13 @@ class PersistentMultiMaplet implements MultiMaplet { } @Override - public Collection get(final K key) { + public Collection get(final int key) { final Collection collection = myCache.get(key); return collection == NULL_COLLECTION? null : collection; } @Override - public void replace(K key, Collection value) { + public void replace(int key, Collection value) { try { myCache.remove(key); if (value == null) { @@ -96,7 +96,7 @@ class PersistentMultiMaplet implements MultiMaplet { } @Override - public void put(final K key, final Collection value) { + public void put(final int key, final Collection value) { try { myCache.remove(key); myMap.appendData(key, new PersistentHashMap.ValueDataAppender() { @@ -113,12 +113,12 @@ class PersistentMultiMaplet implements MultiMaplet { } @Override - public void put(final K key, final V value) { + public void put(final int key, final V value) { put(key, Collections.singleton(value)); } @Override - public void removeAll(K key, Collection values) { + public void removeAll(int key, Collection values) { try { final Collection collection = myCache.get(key); @@ -140,7 +140,7 @@ class PersistentMultiMaplet implements MultiMaplet { } @Override - public void removeFrom(final K key, final V value) { + public void removeFrom(final int key, final V value) { try { final Collection collection = myCache.get(key); @@ -162,7 +162,7 @@ class PersistentMultiMaplet implements MultiMaplet { } @Override - public void remove(final K key) { + public void remove(final int key) { try { myCache.remove(key); myMap.remove(key); @@ -173,26 +173,25 @@ class PersistentMultiMaplet implements MultiMaplet { } @Override - public void putAll(MultiMaplet m) { - for (Map.Entry> entry : m.entrySet()) { - put(entry.getKey(), entry.getValue()); - } + public void putAll(IntObjectMultiMaplet m) { + m.forEachEntry(new TIntObjectProcedure>() { + @Override + public boolean execute(int key, Collection value) { + put(key, value); + return true; + } + }); } @Override - public void replaceAll(MultiMaplet m) { - for (Map.Entry> entry : m.entrySet()) { - replace(entry.getKey(), entry.getValue()); - } - } - - public Collection keyCollection() { - try { - return myMap.getAllKeysWithExistingMapping(); - } - catch (IOException e) { - throw new RuntimeException(e); - } + public void replaceAll(IntObjectMultiMaplet m) { + m.forEachEntry(new TIntObjectProcedure>() { + @Override + public boolean execute(int key, Collection value) { + replace(key, value); + return true; + } + }); } @Override @@ -218,34 +217,19 @@ class PersistentMultiMaplet implements MultiMaplet { } @Override - public Collection>> entrySet() { - final Collection>> result = new LinkedList>>(); - + public void forEachEntry(final TIntObjectProcedure> procedure) { try { - for (final K key : myMap.getAllKeysWithExistingMapping()) { - final Collection value = myMap.get(key); - - final Map.Entry> entry = new Map.Entry>() { - @Override - public K getKey() { - return key; + myMap.processKeysWithExistingMapping(new Processor() { + @Override + public boolean process(Integer key) { + try { + return procedure.execute(key, myMap.get(key)); } - - @Override - public Collection getValue() { - return value; + catch (IOException e) { + throw new RuntimeException(e); } - - @Override - public Collection setValue(Collection value) { - return null; - } - }; - - result.add(entry); - } - - return result; + } + }); } catch (IOException e) { throw new RuntimeException(e); @@ -254,10 +238,10 @@ class PersistentMultiMaplet implements MultiMaplet { private static class CollectionDataExternalizer implements DataExternalizer> { private final DataExternalizer myElementExternalizer; - private final TransientMultiMaplet.CollectionConstructor myCollectionFactory; + private final CollectionFactory myCollectionFactory; public CollectionDataExternalizer(DataExternalizer elementExternalizer, - TransientMultiMaplet.CollectionConstructor collectionFactory) { + CollectionFactory collectionFactory) { myElementExternalizer = elementExternalizer; myCollectionFactory = collectionFactory; } diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/IntObjectTransientMultiMaplet.java b/jps/model/src/org/jetbrains/ether/dependencyView/IntObjectTransientMultiMaplet.java new file mode 100644 index 000000000000..a7de866bb1e5 --- /dev/null +++ b/jps/model/src/org/jetbrains/ether/dependencyView/IntObjectTransientMultiMaplet.java @@ -0,0 +1,131 @@ +package org.jetbrains.ether.dependencyView; + +import gnu.trove.TIntObjectHashMap; +import gnu.trove.TIntObjectProcedure; + +import java.util.Collection; + +/** + * Created by IntelliJ IDEA. + * User: db + * Date: 08.03.11 + * Time: 15:38 + * To change this template use File | Settings | File Templates. + */ +class IntObjectTransientMultiMaplet implements IntObjectMultiMaplet { + + private final TIntObjectHashMap> myMap = new TIntObjectHashMap>(); + private final CollectionFactory myCollectionFactory; + + public IntObjectTransientMultiMaplet(CollectionFactory collectionFactory) { + myCollectionFactory = collectionFactory; + } + + @Override + public boolean containsKey(final int key) { + return myMap.containsKey(key); + } + + @Override + public Collection get(final int key) { + return myMap.get(key); + } + + @Override + public void putAll(IntObjectMultiMaplet m) { + m.forEachEntry(new TIntObjectProcedure>() { + @Override + public boolean execute(int key, Collection value) { + put(key, value); + return true; + } + }); + } + + @Override + public void put(final int key, final Collection value) { + final Collection x = myMap.get(key); + if (x == null) { + myMap.put(key, value); + } + else { + x.addAll(value); + } + } + + @Override + public void replace(int key, Collection value) { + if (value == null) { + myMap.remove(key); + } + else { + myMap.put(key, value); + } + } + + @Override + public void put(final int key, final V value) { + final Collection collection = myMap.get(key); + if (collection == null) { + final Collection x = myCollectionFactory.create(); + x.add(value); + myMap.put(key, x); + } + else { + collection.add(value); + } + } + + @Override + public void removeFrom(final int key, final V value) { + final Collection collection = myMap.get(key); + if (collection != null) { + if (collection.remove(value)) { + if (collection.isEmpty()) { + myMap.remove(key); + } + } + } + } + + @Override + public void removeAll(int key, Collection values) { + final Collection collection = myMap.get(key); + if (collection != null) { + if (collection.removeAll(values)) { + if (collection.isEmpty()) { + myMap.remove(key); + } + } + } + } + + @Override + public void remove(final int key) { + myMap.remove(key); + } + + @Override + public void replaceAll(IntObjectMultiMaplet m) { + m.forEachEntry(new TIntObjectProcedure>() { + @Override + public boolean execute(int key, Collection value) { + replace(key, value); + return true; + } + }); + } + + @Override + public void forEachEntry(TIntObjectProcedure> procedure) { + myMap.forEachEntry(procedure); + } + + @Override + public void close(){ + myMap.clear(); // free memory + } + + public void flush(boolean memoryCachesOnly) { + } +} diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java index 8dbe8210cfc7..985ad7d5bf86 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java @@ -2,7 +2,13 @@ package org.jetbrains.ether.dependencyView; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.util.io.IntInlineKeyDescriptor; +import gnu.trove.TIntHashSet; +import gnu.trove.TIntIntProcedure; +import gnu.trove.TIntObjectProcedure; +import gnu.trove.TIntProcedure; import org.jetbrains.annotations.Nullable; import org.jetbrains.asm4.ClassReader; import org.jetbrains.asm4.Opcodes; @@ -29,20 +35,21 @@ public class Mappings { private final static String SOURCE_TO_ANNOTATIONS = "sourceToAnnotations.tab"; private final static String SOURCE_TO_USAGES = "sourceToUsages.tab"; private final static String CLASS_TO_SOURCE = "classToSource.tab"; + private static final IntInlineKeyDescriptor INT_KEY_DESCRIPTOR = new IntInlineKeyDescriptor(); private final boolean myIsDelta; private final boolean myDeltaIsTransient; private boolean myIsDifferentiated = false; - private final Set myChangedClasses; - private final Set myChangedFiles; + private final TIntHashSet myChangedClasses; + private final TIntHashSet myChangedFiles; private final Object myLock; - private void addChangedClass(final DependencyContext.S it) { + private void addChangedClass(final int it) { assert (myChangedClasses != null && myChangedFiles != null); myChangedClasses.add(it); - final DependencyContext.S file = myClassToSourceFile.get(it); + final Integer file = myClassToSourceFile.get(it); if (file != null) { myChangedFiles.add(file); @@ -51,11 +58,11 @@ public class Mappings { myIsDifferentiated = true; } - private Collection getChangedClasses() { + private TIntHashSet getChangedClasses() { return myChangedClasses; } - private Collection getChangedFiles() { + private TIntHashSet getChangedFiles() { return myChangedFiles; } @@ -65,14 +72,14 @@ public class Mappings { private final File myRootDir; private DependencyContext myContext; - private final DependencyContext.S myInitName; - private org.jetbrains.ether.dependencyView.Logger myDebugS; + private final int myInitName; + private org.jetbrains.ether.dependencyView.Logger myDebugS; private static void debug(final String s) { LOG.debug(s); } - private void debug(final String comment, final DependencyContext.S s) { + private void debug(final String comment, final int s) { myDebugS.debug(comment, s); } @@ -84,40 +91,35 @@ public class Mappings { myDebugS.debug(comment, s); } - private MultiMaplet myClassToSubclasses; - private MultiMaplet myClassToClassDependency; + private IntIntMultiMaplet myClassToSubclasses; + private IntIntMultiMaplet myClassToClassDependency; - private MultiMaplet mySourceFileToClasses; - private MultiMaplet mySourceFileToAnnotationUsages; + private IntObjectMultiMaplet mySourceFileToClasses; + private IntObjectMultiMaplet mySourceFileToAnnotationUsages; - private MultiMaplet mySourceFileToUsages; - private Maplet myClassToSourceFile; + private IntObjectMultiMaplet mySourceFileToUsages; + private IntIntMaplet myClassToSourceFile; - private static final TransientMultiMaplet.CollectionConstructor ourClassSetConstructor = - new TransientMultiMaplet.CollectionConstructor() { + private static final int DEFAULT_SET_CAPACITY = 32; + private static final float DEFAULT_SET_LOAD_FACTOR = 0.98f; + private static final CollectionFactory ourClassSetConstructor = + new CollectionFactory() { public Set create() { - return new HashSet(); + return new HashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); } }; - private static final TransientMultiMaplet.CollectionConstructor ourUsageClusterSetConstructor = - new TransientMultiMaplet.CollectionConstructor() { + private static final CollectionFactory ourUsageClusterSetConstructor = + new CollectionFactory() { public Set create() { - return new HashSet(); + return new HashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); } }; - private static final TransientMultiMaplet.CollectionConstructor ourUsageSetConstructor = - new TransientMultiMaplet.CollectionConstructor() { + private static final CollectionFactory ourUsageSetConstructor = + new CollectionFactory() { public Set create() { - return new HashSet(); - } - }; - - private static final TransientMultiMaplet.CollectionConstructor ourStringSetConstructor = - new TransientMultiMaplet.CollectionConstructor() { - public Set create() { - return new HashSet(); + return new HashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); } }; @@ -125,8 +127,8 @@ public class Mappings { myLock = base.myLock; myIsDelta = true; myPostPasses = new LinkedList(); - myChangedClasses = new HashSet(); - myChangedFiles = new HashSet(); + myChangedClasses = new TIntHashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); + myChangedFiles = new TIntHashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); myDeltaIsTransient = base.myDeltaIsTransient; myRootDir = new File(FileUtil.toSystemIndependentName(base.myRootDir.getAbsolutePath()) + File.separatorChar + "delta"); myContext = base.myContext; @@ -155,43 +157,26 @@ public class Mappings { } if (myIsDelta && myDeltaIsTransient) { - myClassToSubclasses = new TransientMultiMaplet(ourStringSetConstructor); - myClassToClassDependency = new TransientMultiMaplet(ourStringSetConstructor); - mySourceFileToClasses = new TransientMultiMaplet(ourClassSetConstructor); - mySourceFileToAnnotationUsages = new TransientMultiMaplet(ourUsageSetConstructor); - mySourceFileToUsages = new TransientMultiMaplet(ourUsageClusterSetConstructor); - myClassToSourceFile = new TransientMaplet(); + myClassToSubclasses = new IntIntTransientMultiMaplet(); + myClassToClassDependency = new IntIntTransientMultiMaplet(); + mySourceFileToClasses = new IntObjectTransientMultiMaplet(ourClassSetConstructor); + mySourceFileToAnnotationUsages = new IntObjectTransientMultiMaplet(ourUsageSetConstructor); + mySourceFileToUsages = new IntObjectTransientMultiMaplet(ourUsageClusterSetConstructor); + myClassToSourceFile = new IntIntTransientMaplet(); } else { - myClassToSubclasses = - new PersistentMultiMaplet(DependencyContext.getTableFile(myRootDir, CLASS_TO_SUBCLASSES), - DependencyContext.descriptorS, DependencyContext.descriptorS, - ourStringSetConstructor); - - myClassToClassDependency = - new PersistentMultiMaplet(DependencyContext.getTableFile(myRootDir, CLASS_TO_CLASS), - DependencyContext.descriptorS, DependencyContext.descriptorS, - ourStringSetConstructor); - - mySourceFileToClasses = - new PersistentMultiMaplet(DependencyContext.getTableFile(myRootDir, SOURCE_TO_CLASS), - DependencyContext.descriptorS, ClassRepr.externalizer(myContext), - ourClassSetConstructor); - - mySourceFileToAnnotationUsages = - new PersistentMultiMaplet(DependencyContext.getTableFile(myRootDir, SOURCE_TO_ANNOTATIONS), - DependencyContext.descriptorS, UsageRepr.externalizer(myContext), - ourUsageSetConstructor); - - mySourceFileToUsages = - new PersistentMultiMaplet(DependencyContext.getTableFile(myRootDir, SOURCE_TO_USAGES), - DependencyContext.descriptorS, - UsageRepr.Cluster.clusterExternalizer(myContext), - ourUsageClusterSetConstructor); - - myClassToSourceFile = - new PersistentMaplet(DependencyContext.getTableFile(myRootDir, CLASS_TO_SOURCE), - DependencyContext.descriptorS, DependencyContext.descriptorS); + myClassToSubclasses = new IntIntPersistentMultiMaplet(DependencyContext.getTableFile(myRootDir, CLASS_TO_SUBCLASSES), INT_KEY_DESCRIPTOR); + myClassToClassDependency = new IntIntPersistentMultiMaplet(DependencyContext.getTableFile(myRootDir, CLASS_TO_CLASS), INT_KEY_DESCRIPTOR); + mySourceFileToClasses = new IntObjectPersistentMultiMaplet( + DependencyContext.getTableFile(myRootDir, SOURCE_TO_CLASS), INT_KEY_DESCRIPTOR, ClassRepr.externalizer(myContext), ourClassSetConstructor + ); + mySourceFileToAnnotationUsages = new IntObjectPersistentMultiMaplet( + DependencyContext.getTableFile(myRootDir, SOURCE_TO_ANNOTATIONS), INT_KEY_DESCRIPTOR, UsageRepr.externalizer(myContext), ourUsageSetConstructor + ); + mySourceFileToUsages = new IntObjectPersistentMultiMaplet( + DependencyContext.getTableFile(myRootDir, SOURCE_TO_USAGES), INT_KEY_DESCRIPTOR, UsageRepr.Cluster.clusterExternalizer(myContext), ourUsageClusterSetConstructor + ); + myClassToSourceFile = new IntIntPersistentMaplet(DependencyContext.getTableFile(myRootDir, CLASS_TO_SOURCE), INT_KEY_DESCRIPTOR); } } @@ -208,23 +193,23 @@ public class Mappings { private void compensateRemovedContent(final Collection compiled) { for (File file : compiled) { - final DependencyContext.S key = myContext.get(FileUtil.toSystemIndependentName(file.getAbsolutePath())); - if (!mySourceFileToClasses.containsKey(key)) { - mySourceFileToClasses.put(key, new HashSet()); + final int fileName = myContext.get(FileUtil.toSystemIndependentName(file.getAbsolutePath())); + if (!mySourceFileToClasses.containsKey(fileName)) { + mySourceFileToClasses.put(fileName, new HashSet()); } } } @Nullable - private ClassRepr getReprByName(final DependencyContext.S name) { - final DependencyContext.S source = myClassToSourceFile.get(name); + private ClassRepr getReprByName(final int name) { + final int source = myClassToSourceFile.get(name); - if (source != null) { + if (source > 0) { final Collection reprs = mySourceFileToClasses.get(source); if (reprs != null) { for (ClassRepr repr : reprs) { - if (repr.name.equals(name)) { + if (repr.name == name) { return repr; } } @@ -308,21 +293,15 @@ public class Mappings { this.myDelta = delta; } - void appendDependents(final ClassRepr c, final Set result) { - final Collection depClasses = myDelta.myClassToClassDependency.get(c.name); + void appendDependents(final ClassRepr c, final TIntHashSet result) { + final TIntHashSet depClasses = myDelta.myClassToClassDependency.get(c.name); if (depClasses != null) { - for (DependencyContext.S className : depClasses) { - result.add(className); - } + addAll(result, depClasses); } } - void propagateMemberAccessRec(final Collection acc, - final boolean isField, - final boolean root, - final DependencyContext.S name, - final DependencyContext.S reflcass) { + void propagateMemberAccessRec(final TIntHashSet acc, final boolean isField, final boolean root, final int name, final int reflcass) { final ClassRepr repr = reprByName(reflcass); if (repr != null) { @@ -332,7 +311,7 @@ public class Mappings { for (Object o : members) { final ProtoMember m = (ProtoMember)o; - if (m.name.equals(name)) { + if (m.name == name) { return; } } @@ -340,31 +319,33 @@ public class Mappings { acc.add(reflcass); } - final Collection subclasses = myClassToSubclasses.get(reflcass); + final TIntHashSet subclasses = myClassToSubclasses.get(reflcass); if (subclasses != null) { - for (DependencyContext.S subclass : subclasses) { - propagateMemberAccessRec(acc, isField, false, name, subclass); - } + subclasses.forEach(new TIntProcedure() { + @Override + public boolean execute(int subclass) { + propagateMemberAccessRec(acc, isField, false, name, subclass); + return true; + } + }); } } } - Collection propagateMemberAccess(final boolean isField, - final DependencyContext.S name, - final DependencyContext.S className) { - final Set acc = new HashSet(); + TIntHashSet propagateMemberAccess(final boolean isField, final int name, final int className) { + final TIntHashSet acc = new TIntHashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); propagateMemberAccessRec(acc, isField, true, name, className); return acc; } - Collection propagateFieldAccess(final DependencyContext.S name, final DependencyContext.S className) { + TIntHashSet propagateFieldAccess(final int name, final int className) { return propagateMemberAccess(true, name, className); } - Collection propagateMethodAccess(final DependencyContext.S name, final DependencyContext.S className) { + TIntHashSet propagateMethodAccess(final int name, final int className) { return propagateMemberAccess(false, name, className); } @@ -372,7 +353,7 @@ public class Mappings { return new MethodRepr.Predicate() { @Override public boolean satisfy(final MethodRepr m) { - if (m.name.equals(myInitName) || !m.name.equals(than.name) || m.argumentTypes.length != than.argumentTypes.length) { + if (m.name == myInitName || m.name != than.name || m.argumentTypes.length != than.argumentTypes.length) { return false; } @@ -394,29 +375,33 @@ public class Mappings { new Object() { public void run(final ClassRepr c) { - final Collection subClasses = myClassToSubclasses.get(c.name); + final TIntHashSet subClasses = myClassToSubclasses.get(c.name); if (subClasses != null) { - for (DependencyContext.S subClassName : subClasses) { - final ClassRepr r = reprByName(subClassName); + subClasses.forEach(new TIntProcedure() { + @Override + public boolean execute(int subClassName) { + final ClassRepr r = reprByName(subClassName); - if (r != null) { - boolean cont = true; + if (r != null) { + boolean cont = true; - final Collection methods = r.findMethods(predicate); + final Collection methods = r.findMethods(predicate); - for (MethodRepr mm : methods) { - if (isVisibleIn(c, m, r)) { - result.add(new Pair(mm, r)); - cont = false; + for (MethodRepr mm : methods) { + if (isVisibleIn(c, m, r)) { + result.add(new Pair(mm, r)); + cont = false; + } + } + + if (cont) { + run(r); } } - - if (cont) { - run(r); - } + return true; } - } + }); } } }.run(c); @@ -434,9 +419,9 @@ public class Mappings { new Object() { public void run(final ClassRepr c) { - final DependencyContext.S[] supers = c.getSupers(); + final int[] supers = c.getSupers(); - for (DependencyContext.S succName : supers) { + for (int succName : supers) { final ClassRepr r = reprByName(succName); if (r != null) { @@ -478,9 +463,9 @@ public class Mappings { new Object() { public void run(final ClassRepr c) { - final DependencyContext.S[] supers = c.getSupers(); + final int[] supers = c.getSupers(); - for (DependencyContext.S succName : supers) { + for (int succName : supers) { final ClassRepr r = reprByName(succName); if (r != null) { @@ -508,7 +493,7 @@ public class Mappings { return result; } - ClassRepr reprByName(final DependencyContext.S name) { + ClassRepr reprByName(final int name) { if (myDelta != null) { final ClassRepr r = myDelta.getReprByName(name); @@ -520,15 +505,15 @@ public class Mappings { return getReprByName(name); } - Option isInheritorOf(final DependencyContext.S who, final DependencyContext.S whom) { - if (who.equals(whom)) { + Option isInheritorOf(final int who, final int whom) { + if (who == whom) { return new Option(true); } final ClassRepr repr = reprByName(who); if (repr != null) { - for (DependencyContext.S s : repr.getSupers()) { + for (int s : repr.getSupers()) { final Option inheritorOf = isInheritorOf(s, whom); if (inheritorOf.isValue() && inheritorOf.value()) { return inheritorOf; @@ -569,7 +554,7 @@ public class Mappings { return new Option(false); } - boolean methodVisible(final DependencyContext.S className, final MethodRepr m) { + boolean methodVisible(final int className, final MethodRepr m) { final ClassRepr r = reprByName(className); if (r != null) { @@ -583,7 +568,7 @@ public class Mappings { return false; } - boolean fieldVisible(final DependencyContext.S className, final FieldRepr field) { + boolean fieldVisible(final int className, final FieldRepr field) { final ClassRepr r = reprByName(className); if (r != null) { @@ -597,16 +582,16 @@ public class Mappings { return true; } - void affectSubclasses(final DependencyContext.S className, + void affectSubclasses(final int className, final Collection affectedFiles, final Collection affectedUsages, - final Collection dependants, + final TIntHashSet dependants, final boolean usages) { debug("Affecting subclasses of class: ", className); - final DependencyContext.S fileName = myClassToSourceFile.get(className); + final int fileName = myClassToSourceFile.get(className); - if (fileName == null) { + if (fileName < 0) { debug("No source file detected for class ", className); debug("End of affectSubclasses"); return; @@ -625,83 +610,100 @@ public class Mappings { } } - final Collection depClasses = myClassToClassDependency.get(className); + final TIntHashSet depClasses = myClassToClassDependency.get(className); if (depClasses != null) { - dependants.addAll(depClasses); + addAll(dependants, depClasses); } affectedFiles.add(new File(myContext.getValue(fileName))); - final Collection directSubclasses = myClassToSubclasses.get(className); + final TIntHashSet directSubclasses = myClassToSubclasses.get(className); if (directSubclasses != null) { - for (DependencyContext.S subClass : directSubclasses) { - affectSubclasses(subClass, affectedFiles, affectedUsages, dependants, usages); - } + directSubclasses.forEach(new TIntProcedure() { + @Override + public boolean execute(int subClass) { + affectSubclasses(subClass, affectedFiles, affectedUsages, dependants, usages); + return true; + } + }); } } void affectFieldUsages(final FieldRepr field, - final Collection subclasses, + final TIntHashSet subclasses, final UsageRepr.Usage rootUsage, final Set affectedUsages, - final Set dependents) { + final TIntHashSet dependents) { affectedUsages.add(rootUsage); - for (DependencyContext.S p : subclasses) { - final Collection deps = myClassToClassDependency.get(p); + subclasses.forEach(new TIntProcedure() { + @Override + public boolean execute(int p) { + final TIntHashSet deps = myClassToClassDependency.get(p); - if (deps != null) { - dependents.addAll(deps); + if (deps != null) { + addAll(dependents, deps); + } + + debug("Affect field usage referenced of class ", p); + affectedUsages + .add(rootUsage instanceof UsageRepr.FieldAssignUsage ? field.createAssignUsage(myContext, p) : field.createUsage(myContext, p)); + return true; } - - debug("Affect field usage referenced of class ", p); - affectedUsages - .add(rootUsage instanceof UsageRepr.FieldAssignUsage ? field.createAssignUsage(myContext, p) : field.createUsage(myContext, p)); - } + }); } void affectMethodUsages(final MethodRepr method, - final Collection subclasses, + final TIntHashSet subclasses, final UsageRepr.Usage rootUsage, final Set affectedUsages, - final Set dependents) { + final TIntHashSet dependents) { affectedUsages.add(rootUsage); if (subclasses != null) { - for (DependencyContext.S p : subclasses) { - final Collection deps = myClassToClassDependency.get(p); + subclasses.forEach(new TIntProcedure() { + @Override + public boolean execute(int p) { + final TIntHashSet deps = myClassToClassDependency.get(p); - if (deps != null) { - dependents.addAll(deps); + if (deps != null) { + addAll(dependents, deps); + } + + debug("Affect method usage referenced of class ", p); + + final UsageRepr.Usage usage = rootUsage instanceof UsageRepr.MetaMethodUsage ? method.createMetaUsage(myContext, p) : method.createUsage(myContext, p); + affectedUsages.add(usage); + return true; } - - debug("Affect method usage referenced of class ", p); - - affectedUsages - .add(rootUsage instanceof UsageRepr.MetaMethodUsage ? method.createMetaUsage(myContext, p) : method.createUsage(myContext, p)); - } + }); } } - void affectAll(final DependencyContext.S className, final Collection affectedFiles) { - final Set dependants = (Set)myClassToClassDependency.get(className); - final DependencyContext.S sourceFile = myClassToSourceFile.get(className); + void affectAll(final int className, final Collection affectedFiles) { + final TIntHashSet dependants = myClassToClassDependency.get(className); if (dependants != null) { - for (DependencyContext.S depClass : dependants) { - final DependencyContext.S depFile = myClassToSourceFile.get(depClass); - - if (depFile != null && sourceFile != null && !depFile.equals(sourceFile)) { - affectedFiles.add(new File(myContext.getValue(depFile))); - } + final int sourceFile = myClassToSourceFile.get(className); + if (sourceFile > 0) { + dependants.forEach(new TIntProcedure() { + @Override + public boolean execute(int depClass) { + final int depFile = myClassToSourceFile.get(depClass); + if (depFile > 0 && depFile != sourceFile) { + affectedFiles.add(new File(myContext.getValue(depFile))); + } + return true; + } + }); } } } public abstract class UsageConstraint { - public abstract boolean checkResidence(final DependencyContext.S residence); + public abstract boolean checkResidence(final int residence); } public class PackageConstraint extends UsageConstraint { @@ -712,21 +714,21 @@ public class Mappings { } @Override - public boolean checkResidence(final DependencyContext.S residence) { + public boolean checkResidence(final int residence) { return !ClassRepr.getPackageName(myContext.getValue(residence)).equals(packageName); } } public class InheritanceConstraint extends PackageConstraint { - public final DependencyContext.S rootClass; + public final int rootClass; - public InheritanceConstraint(final DependencyContext.S rootClass) { + public InheritanceConstraint(final int rootClass) { super(ClassRepr.getPackageName(myContext.getValue(rootClass))); this.rootClass = rootClass; } @Override - public boolean checkResidence(final DependencyContext.S residence) { + public boolean checkResidence(final int residence) { final Option inheritorOf = isInheritorOf(residence, rootClass); return inheritorOf.isNone() || !inheritorOf.value() || super.checkResidence(residence); } @@ -740,7 +742,7 @@ public class Mappings { } @Override - public boolean checkResidence(final DependencyContext.S residence) { + public boolean checkResidence(final int residence) { return !x.checkResidence(residence); } } @@ -755,7 +757,7 @@ public class Mappings { } @Override - public boolean checkResidence(final DependencyContext.S residence) { + public boolean checkResidence(final int residence) { return x.checkResidence(residence) && y.checkResidence(residence); } } @@ -772,44 +774,46 @@ public class Mappings { } private static boolean isVisibleIn(final ClassRepr c, final ProtoMember m, final ClassRepr scope) { - final boolean privacy = ((m.access & Opcodes.ACC_PRIVATE) > 0) && !c.name.equals(scope.name); + final boolean privacy = ((m.access & Opcodes.ACC_PRIVATE) > 0) && c.name != scope.name; final boolean packageLocality = isPackageLocal(m.access) && !c.getPackageName().equals(scope.getPackageName()); return !privacy && !packageLocality; } - private boolean empty(final DependencyContext.S s) { - return s.equals(myContext.get("")); + private boolean empty(final int s) { + return s == myContext.get(""); } - private Collection getAllSubclasses(final DependencyContext.S root) { - final Collection result = new HashSet(); + private TIntHashSet getAllSubclasses(final int root) { + final TIntHashSet result = new TIntHashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); addAllSubclasses(root, result); return result; } - private void addAllSubclasses(final DependencyContext.S root, final Collection acc) { - final Collection directSubclasses = myClassToSubclasses.get(root); + private void addAllSubclasses(final int root, final TIntHashSet acc) { + final TIntHashSet directSubclasses = myClassToSubclasses.get(root); acc.add(root); if (directSubclasses != null) { - for (final DependencyContext.S s : directSubclasses) { - if (acc.contains(s)) { - continue; + directSubclasses.forEach(new TIntProcedure() { + @Override + public boolean execute(int s) { + if (!acc.contains(s)) { + addAllSubclasses(s, acc); + } + return true; } - - addAllSubclasses(s, acc); - } + }); } } - private boolean incrementalDecision(final DependencyContext.S owner, + private boolean incrementalDecision(final int owner, final Proto member, final Collection affectedFiles, - DependentFilesFilter filter) { + final DependentFilesFilter filter) { final boolean isField = member instanceof FieldRepr; final Util self = new Util(this); @@ -824,13 +828,17 @@ public class Mappings { debug("Protected access, softening non-incremental decision: adding all relevant subclasses for a recompilation"); debug("Root class: ", owner); - final Collection propagated = self.propagateFieldAccess(isField ? member.name : myContext.get(""), owner); + final TIntHashSet propagated = self.propagateFieldAccess(isField ? member.name : myContext.get(""), owner); - for (DependencyContext.S className : propagated) { - final String fileName = myContext.getValue(myClassToSourceFile.get(className)); - debug("Adding ", fileName); - affectedFiles.add(new File(fileName)); - } + propagated.forEach(new TIntProcedure() { + @Override + public boolean execute(int className) { + final String fileName = myContext.getValue(myClassToSourceFile.get(className)); + debug("Adding ", fileName); + affectedFiles.add(new File(fileName)); + return true; + } + }); } final String packageName = ClassRepr.getPackageName(myContext.getValue(isField ? owner : member.name)); @@ -838,20 +846,21 @@ public class Mappings { debug("Softening non-incremental decision: adding all package classes for a recompilation"); debug("Package name: ", packageName); - // Package-local branch - for (Map.Entry e : myClassToSourceFile.entrySet()) { - final DependencyContext.S className = e.getKey(); - final DependencyContext.S fileName = e.getValue(); - - if (ClassRepr.getPackageName(myContext.getValue(className)).equals(packageName)) { - final String f = myContext.getValue(fileName); - final File file = new File(f); - if (filter.accept(file)) { - debug("Adding: ", f); - affectedFiles.add(file); + // Package-local branch + myClassToSourceFile.forEachEntry(new TIntIntProcedure() { + @Override + public boolean execute(int className, int fileName) { + if (ClassRepr.getPackageName(myContext.getValue(className)).equals(packageName)) { + final String f = myContext.getValue(fileName); + final File file = new File(f); + if (filter.accept(file)) { + debug("Adding: ", f); + affectedFiles.add(file); + } } + return true; } - } + }); return true; } @@ -867,11 +876,7 @@ public class Mappings { boolean accept(File file); } - public boolean differentiate(final Mappings delta, - final Collection removed, - final Collection filesToCompile, - final Collection compiledFiles, - final Collection affectedFiles, DependentFilesFilter filter) { + public boolean differentiate(final Mappings delta, final Collection removed, final Collection filesToCompile, final Collection compiledFiles, final Collection affectedFiles, DependentFilesFilter filter) { synchronized (myLock) { debug("Begin of Differentiate:"); @@ -894,10 +899,30 @@ public class Mappings { } } - for (DependencyContext.S fileName : delta.mySourceFileToClasses.keyCollection()) { - final Set classes = (Set)delta.mySourceFileToClasses.get(fileName); + class FileClasses { + final int fileName; + final Set fileClasses; + + FileClasses(int fileName, Collection fileClasses) { + this.fileName = fileName; + this.fileClasses = new HashSet(fileClasses); + } + } + + final List newClasses = new ArrayList(); + delta.mySourceFileToClasses.forEachEntry(new TIntObjectProcedure>() { + @Override + public boolean execute(int fileName, Collection classes) { + newClasses.add(new FileClasses(fileName, classes)); + return true; + } + }); + + for (FileClasses compiledFile : newClasses) { + final int fileName = compiledFile.fileName; + final Set classes = compiledFile.fileClasses; final Set pastClasses = (Set)mySourceFileToClasses.get(fileName); - final Set dependants = new HashSet(); + final TIntHashSet dependants = new TIntHashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); final Set affectedUsages = new HashSet(); final Set annotationQuery = new HashSet(); @@ -1012,7 +1037,7 @@ public class Mappings { } debug("Processing added methods: "); - for (MethodRepr m : diff.methods().added()) { + for (final MethodRepr m : diff.methods().added()) { debug("Method: ", m.name); if (it.isAnnotation()) { @@ -1027,9 +1052,9 @@ public class Mappings { u.affectSubclasses(it.name, affectedFiles, affectedUsages, dependants, false); } - Collection propagated = null; + TIntHashSet propagated = null; - if ((m.access & Opcodes.ACC_PRIVATE) == 0 && !m.name.equals(myInitName)) { + if ((m.access & Opcodes.ACC_PRIVATE) == 0 && m.name != myInitName) { final ClassRepr oldIt = getReprByName(it.name); if (oldIt != null && self.findOverridenMethods(m, oldIt).size() > 0) { @@ -1087,9 +1112,9 @@ public class Mappings { !m.exceptions.equals(mm.exceptions) || (subtypeOf.isNone() || !subtypeOf.value()) || !empty(mm.signature) || !empty(m.signature)) { - final DependencyContext.S file = myClassToSourceFile.get(cc.name); + final int file = myClassToSourceFile.get(cc.name); - if (file != null) { + if (file > 0) { final String f = myContext.getValue(file); debug("Complex condition is satisfied, affecting file ", f); affectedFiles.add(new File(f)); @@ -1099,13 +1124,13 @@ public class Mappings { else { debug("Current method does not override that found"); - final Collection yetPropagated = self.propagateMethodAccess(mm.name, it.name); + final TIntHashSet yetPropagated = self.propagateMethodAccess(mm.name, it.name); if (inheritorOf.isValue() && inheritorOf.value()) { - final Collection deps = myClassToClassDependency.get(cc.name); + final TIntHashSet deps = myClassToClassDependency.get(cc.name); if (deps != null) { - dependants.addAll(deps); + addAll(dependants, deps); } u.affectMethodUsages(mm, yetPropagated, mm.createUsage(myContext, cc.name), affectedUsages, dependants); @@ -1117,34 +1142,38 @@ public class Mappings { } } - final Collection subClasses = getAllSubclasses(it.name); + final TIntHashSet subClasses = getAllSubclasses(it.name); if (subClasses != null) { - for (final DependencyContext.S subClass : subClasses) { - final ClassRepr r = u.reprByName(subClass); - final DependencyContext.S sourceFileName = myClassToSourceFile.get(subClass); + subClasses.forEach(new TIntProcedure() { + @Override + public boolean execute(int subClass) { + final ClassRepr r = u.reprByName(subClass); + final int sourceFileName = myClassToSourceFile.get(subClass); - if (r != null && sourceFileName != null) { - final DependencyContext.S outerClass = r.outerClassName; + if (r != null && sourceFileName > 0) { + final int outerClass = r.outerClassName; - if (u.methodVisible(outerClass, m)) { - final String f = myContext.getValue(sourceFileName); - debug("Affecting file due to local overriding: ", f); - affectedFiles.add(new File(f)); + if (u.methodVisible(outerClass, m)) { + final String f = myContext.getValue(sourceFileName); + debug("Affecting file due to local overriding: ", f); + affectedFiles.add(new File(f)); + } } + return true; } - } + }); } } } debug("End of added methods processing"); debug("Processing removed methods:"); - for (MethodRepr m : diff.methods().removed()) { + for (final MethodRepr m : diff.methods().removed()) { debug("Method ", m.name); final Collection> overridenMethods = u.findOverridenMethods(m, it); - final Collection propagated = u.propagateMethodAccess(m.name, it.name); + final TIntHashSet propagated = u.propagateMethodAccess(m.name, it.name); if (overridenMethods.size() == 0) { debug("No overridden methods found, affecting method usages"); @@ -1171,58 +1200,60 @@ public class Mappings { final Collection> overriding = u.findOverridingMethods(m, it, false); for (final Pair p : overriding) { - final DependencyContext.S fName = myClassToSourceFile.get(p.second.name); + final int fName = myClassToSourceFile.get(p.second.name); affectedFiles.add(new File(myContext.getValue(fName))); } if ((m.access & Opcodes.ACC_ABSTRACT) == 0) { - for (DependencyContext.S p : propagated) { - if (!p.equals(it.name)) { - final ClassRepr s = u.reprByName(p); + propagated.forEach(new TIntProcedure() { + @Override + public boolean execute(int p) { + if (p != it.name) { + final ClassRepr s = u.reprByName(p); - if (s != null) { - final Collection> overridenInS = u.findOverridenMethods(m, s); + if (s != null) { + final Collection> overridenInS = u.findOverridenMethods(m, s); - overridenInS.addAll(overridenMethods); + overridenInS.addAll(overridenMethods); - boolean allAbstract = true; - boolean visited = false; + boolean allAbstract = true; + boolean visited = false; - for (Pair pp : overridenInS) { - final ClassRepr cc = pp.second; + for (Pair pp : overridenInS) { + final ClassRepr cc = pp.second; + + if (cc == myMockClass) { + visited = true; + continue; + } + + if (cc.name == it.name) { + continue; + } - if (cc == myMockClass) { visited = true; - continue; + allAbstract = ((pp.first.access & Opcodes.ACC_ABSTRACT) > 0) || ((cc.access & Opcodes.ACC_INTERFACE) > 0); + + if (!allAbstract) { + break; + } } - if (cc.name.equals(it.name)) { - continue; - } + if (allAbstract && visited) { + final int source = myClassToSourceFile.get(p); - visited = true; - allAbstract = ((pp.first.access & Opcodes.ACC_ABSTRACT) > 0) || ((cc.access & Opcodes.ACC_INTERFACE) > 0); - - if (!allAbstract) { - break; - } - } - - if (allAbstract && visited) { - final DependencyContext.S source = myClassToSourceFile.get(p); - - if (source != null) { - final String f = myContext.getValue(source); - debug( - "Removed method is not abstract & overrides some abstract method which is not then over-overriden in subclass ", - p); - debug("Affecting subclass source file ", f); - affectedFiles.add(new File(f)); + if (source > 0) { + final String f = myContext.getValue(source); + debug( "Removed method is not abstract & overrides some abstract method which is not then over-overriden in subclass ", p); + debug("Affecting subclass source file ", f); + affectedFiles.add(new File(f)); + } } } } + return true; } - } + }); } } debug("End of removed methods processing"); @@ -1238,14 +1269,13 @@ public class Mappings { if (it.isAnnotation()) { if (d.defaultRemoved()) { debug("Class is annotation, default value is removed => adding annotation query"); - final List l = new LinkedList(); + final TIntHashSet l = new TIntHashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); l.add(m.name); - annotationQuery.add((UsageRepr.AnnotationUsage)UsageRepr - .createAnnotationUsage(myContext, TypeRepr.createClassType(myContext, it.name), l, null)); + annotationQuery.add((UsageRepr.AnnotationUsage)UsageRepr.createAnnotationUsage(myContext, TypeRepr.createClassType( myContext, it.name), l, null)); } } else if (d.base() != Difference.NONE || throwsChanged) { - final Collection propagated = u.propagateMethodAccess(m.name, it.name); + final TIntHashSet propagated = u.propagateMethodAccess(m.name, it.name); boolean affected = false; boolean constrained = false; @@ -1317,7 +1347,7 @@ public class Mappings { final int mask = Opcodes.ACC_STATIC | Opcodes.ACC_FINAL; debug("Processing added fields"); - for (FieldRepr f : diff.fields().added()) { + for (final FieldRepr f : diff.fields().added()) { debug("Field: ", f.name); final boolean fPrivate = (f.access & Opcodes.ACC_PRIVATE) > 0; @@ -1326,39 +1356,42 @@ public class Mappings { final boolean fPLocal = !fPrivate && !fProtected && !fPublic; if (!fPrivate) { - final Collection subClasses = getAllSubclasses(it.name); + final TIntHashSet subClasses = getAllSubclasses(it.name); + subClasses.forEach(new TIntProcedure() { + @Override + public boolean execute(int subClass) { + final ClassRepr r = u.reprByName(subClass); + final int sourceFileName = myClassToSourceFile.get(subClass); - for (final DependencyContext.S subClass : subClasses) { - final ClassRepr r = u.reprByName(subClass); - final DependencyContext.S sourceFileName = myClassToSourceFile.get(subClass); - - if (r != null && sourceFileName != null) { - if (r.isLocal) { - debug( - "Affecting local subclass (introduced field can potentially hide surrounding method parameters/local variables): ", - sourceFileName); - affectedFiles.add(new File(myContext.getValue(sourceFileName))); - } - else { - final DependencyContext.S outerClass = r.outerClassName; - - if (!empty(outerClass) && u.fieldVisible(outerClass, f)) { - debug("Affecting inner subclass (introduced field can potentially hide surrounding class fields): ", sourceFileName); + if (r != null && sourceFileName > 0) { + if (r.isLocal) { + debug( + "Affecting local subclass (introduced field can potentially hide surrounding method parameters/local variables): ", + sourceFileName); affectedFiles.add(new File(myContext.getValue(sourceFileName))); } + else { + final int outerClass = r.outerClassName; + + if (!empty(outerClass) && u.fieldVisible(outerClass, f)) { + debug("Affecting inner subclass (introduced field can potentially hide surrounding class fields): ", sourceFileName); + affectedFiles.add(new File(myContext.getValue(sourceFileName))); + } + } } + + debug("Affecting field usages referenced from subclass ", subClass); + final TIntHashSet propagated = u.propagateFieldAccess(f.name, subClass); + u.affectFieldUsages(f, propagated, f.createUsage(myContext, subClass), affectedUsages, dependants); + + final TIntHashSet deps = myClassToClassDependency.get(subClass); + + if (deps != null) { + addAll(dependants, deps); + } + return true; } - - debug("Affecting field usages referenced from subclass ", subClass); - final Collection propagated = u.propagateFieldAccess(f.name, subClass); - u.affectFieldUsages(f, propagated, f.createUsage(myContext, subClass), affectedUsages, dependants); - - final Collection deps = myClassToClassDependency.get(subClass); - - if (deps != null) { - dependants.addAll(deps); - } - } + }); } final Collection> overridden = u.findOverridenFields(f, it); @@ -1373,7 +1406,7 @@ public class Mappings { final boolean ffPLocal = isPackageLocal(ff.access); if (!ffPrivate) { - final Collection propagated = o.propagateFieldAccess(ff.name, cc.name); + final TIntHashSet propagated = o.propagateFieldAccess(ff.name, cc.name); final Set localUsages = new HashSet(); debug("Affecting usages of overridden field in class ", cc.name); @@ -1419,7 +1452,7 @@ public class Mappings { } } - final Collection propagated = u.propagateFieldAccess(f.name, it.name); + final TIntHashSet propagated = u.propagateFieldAccess(f.name, it.name); u.affectFieldUsages(f, propagated, f.createUsage(myContext, it.name), affectedUsages, dependants); } debug("End of removed fields processing"); @@ -1442,7 +1475,7 @@ public class Mappings { } if (d.base() != Difference.NONE) { - final Collection propagated = u.propagateFieldAccess(field.name, it.name); + final TIntHashSet propagated = u.propagateFieldAccess(field.name, it.name); if ((d.base() & Difference.TYPE) > 0 || (d.base() & Difference.SIGNATURE) > 0) { debug("Type or signature changed --- affecting field usages"); @@ -1504,35 +1537,43 @@ public class Mappings { for (ClassRepr c : classDiff.added()) { delta.addChangedClass(c.name); - final Collection depClasses = myClassToClassDependency.get(c.name); + final TIntHashSet depClasses = myClassToClassDependency.get(c.name); if (depClasses != null) { - for (DependencyContext.S depClass : depClasses) { - final DependencyContext.S fName = myClassToSourceFile.get(depClass); + depClasses.forEach(new TIntProcedure() { + @Override + public boolean execute(int depClass) { + final int fName = myClassToSourceFile.get(depClass); - if (fName != null) { - final String f = myContext.getValue(fName); - debug("Adding dependent file ", f); - affectedFiles.add(new File(f)); + if (fName > 0) { + final String f = myContext.getValue(fName); + debug("Adding dependent file ", f); + affectedFiles.add(new File(f)); + } + return true; } - } + }); } } debug("End of added classes processing."); debug("Checking dependent files:"); - final Set dependentFiles = new HashSet(); + final TIntHashSet dependentFiles = new TIntHashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); - for (DependencyContext.S depClass : dependants) { - final DependencyContext.S file = myClassToSourceFile.get(depClass); - - if (file != null) { - dependentFiles.add(file); + dependants.forEach(new TIntProcedure() { + @Override + public boolean execute(int depClass) { + final int file = myClassToSourceFile.get(depClass); + if (file > 0) { + dependentFiles.add(file); + } + return true; } - } + }); + filewise: - for (DependencyContext.S depFile : dependentFiles) { + for (int depFile : dependentFiles.toArray()) { // todo: avoid toArray()? final File theFile = new File(myContext.getValue(depFile)); if (affectedFiles.contains(theFile) || compiledFiles.contains(theFile)) { @@ -1561,8 +1602,8 @@ public class Mappings { continue filewise; } else { - final Set residenceClasses = depCluster.getResidence(usage); - for (DependencyContext.S residentName : residenceClasses) { + final TIntHashSet residenceClasses = depCluster.getResidence(usage); + for (int residentName : residenceClasses.toArray()) { if (constraint.checkResidence(residentName)) { debug("Added file with satisfied constraint"); affectedFiles.add(theFile); @@ -1609,7 +1650,7 @@ public class Mappings { if (removed != null) { for (String file : removed) { - final DependencyContext.S key = myContext.get(file); + final int key = myContext.get(file); final Set classes = (Set)mySourceFileToClasses.get(key); final Collection clusters = mySourceFileToUsages.get(key); @@ -1619,7 +1660,7 @@ public class Mappings { myClassToSourceFile.remove(cr.name); myClassToClassDependency.remove(cr.name); - for (DependencyContext.S superSomething : cr.getSupers()) { + for (int superSomething : cr.getSupers()) { myClassToSubclasses.removeFrom(superSomething, cr.name); } @@ -1629,7 +1670,7 @@ public class Mappings { if (usages != null) { for (UsageRepr.Usage u : usages) { if (u instanceof UsageRepr.ClassUsage) { - final Set residents = cluster.getResidence(u); + final TIntHashSet residents = cluster.getResidence(u); if (residents != null && residents.contains(cr.name)) { myClassToClassDependency.removeFrom(((UsageRepr.ClassUsage)u).className, cr.name); @@ -1649,49 +1690,57 @@ public class Mappings { } if (delta.isDifferentiated()) { - for (DependencyContext.S c : delta.getChangedClasses()) { - final Collection subClasses = delta.myClassToSubclasses.get(c); - if (subClasses != null) { - myClassToSubclasses.replace(c, subClasses); - } - else { - myClassToSubclasses.remove(c); - } + delta.getChangedClasses().forEach(new TIntProcedure() { + @Override + public boolean execute(int c) { + final TIntHashSet subClasses = delta.myClassToSubclasses.get(c); + if (subClasses != null) { + myClassToSubclasses.replace(c, subClasses); + } + else { + myClassToSubclasses.remove(c); + } - final DependencyContext.S sourceFile = delta.myClassToSourceFile.get(c); - if (sourceFile != null) { - myClassToSourceFile.put(c, sourceFile); + final int sourceFile = delta.myClassToSourceFile.get(c); + if (sourceFile > 0) { + myClassToSourceFile.put(c, sourceFile); + } + else { + myClassToSourceFile.remove(c); + } + return true; } - else { - myClassToSourceFile.remove(c); - } - } + }); - for (DependencyContext.S f : delta.getChangedFiles()) { - final Collection classes = delta.mySourceFileToClasses.get(f); - if (classes != null) { - mySourceFileToClasses.replace(f, classes); - } - else { - mySourceFileToClasses.remove(f); - } + delta.getChangedFiles().forEach(new TIntProcedure() { + @Override + public boolean execute(int f) { + final Collection classes = delta.mySourceFileToClasses.get(f); + if (classes != null) { + mySourceFileToClasses.replace(f, classes); + } + else { + mySourceFileToClasses.remove(f); + } - final Collection clusters = delta.mySourceFileToUsages.get(f); - if (clusters != null) { - mySourceFileToUsages.replace(f, clusters); - } - else { - mySourceFileToUsages.remove(f); - } + final Collection clusters = delta.mySourceFileToUsages.get(f); + if (clusters != null) { + mySourceFileToUsages.replace(f, clusters); + } + else { + mySourceFileToUsages.remove(f); + } - final Collection usages = delta.mySourceFileToAnnotationUsages.get(f); - if (usages != null) { - mySourceFileToAnnotationUsages.replace(f, usages); + final Collection usages = delta.mySourceFileToAnnotationUsages.get(f); + if (usages != null) { + mySourceFileToAnnotationUsages.replace(f, usages); + } + else { + mySourceFileToAnnotationUsages.remove(f); + } + return true; } - else { - mySourceFileToAnnotationUsages.remove(f); - } - } + }); } else { myClassToSubclasses.putAll(delta.myClassToSubclasses); @@ -1702,42 +1751,41 @@ public class Mappings { mySourceFileToAnnotationUsages.replaceAll(delta.mySourceFileToAnnotationUsages); } - final Collection compiledSet = new HashSet(compiled.size()); + final int[] compiledClasses = getClassNames(compiled); + final int[] changedClassesArray = delta.getChangedClasses().toArray(); - for (File c : compiled) { - compiledSet.add(myContext.get(FileUtil.toSystemIndependentName(c.getAbsolutePath()))); - } + delta.myClassToClassDependency.forEachEntry(new TIntObjectProcedure() { + @Override + public boolean execute(int aClass, TIntHashSet now) { + if (delta.isDifferentiated()) { + final boolean classChanged = delta.getChangedClasses().contains(aClass); + final TIntHashSet depClasses = new TIntHashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); + addAll(depClasses, now); - final Collection changedClasses = delta.getChangedClasses(); + depClasses.retainAll(changedClassesArray); - for (DependencyContext.S aClass : delta.myClassToClassDependency.keyCollection()) { - final Collection now = delta.myClassToClassDependency.get(aClass); - - if (delta.isDifferentiated()) { - final boolean classChanged = changedClasses.contains(aClass); - final HashSet depClasses = new HashSet(now); - - depClasses.retainAll(changedClasses); - - if (!classChanged && depClasses.isEmpty()) { - continue; + if (!classChanged && depClasses.isEmpty()) { + return true; + } } - } - final Collection past = myClassToClassDependency.get(aClass); + final TIntHashSet past = myClassToClassDependency.get(aClass); - if (past == null) { - myClassToClassDependency.put(aClass, now); - } - else { - boolean changed = past.removeAll(compiledSet); - changed |= past.addAll(now); - - if (changed) { - myClassToClassDependency.replace(aClass, past); + if (past == null) { + myClassToClassDependency.put(aClass, now); } + else { + boolean changed = past.removeAll(compiledClasses); + changed |= addAll(past, now); + + if (changed) { + myClassToClassDependency.replace(aClass, past); + } + } + + return true; } - } + }); } finally { delta.close(); @@ -1745,15 +1793,33 @@ public class Mappings { } } + private int[] getClassNames(Collection compiled) { + final TIntHashSet classnames = new TIntHashSet(compiled.size()); + for (File c : compiled) { + final int fileName = myContext.get(FileUtil.toSystemIndependentName(c.getAbsolutePath())); + final Collection reprs = mySourceFileToClasses.get(fileName); + if (reprs != null) { + for (ClassRepr repr : reprs) { + classnames.add(repr.name); + } + } + } + return classnames.toArray(); + } + public Callbacks.Backend getCallback() { return new Callbacks.Backend() { public Collection getClassFiles() { - final HashSet result = new HashSet(); + final Set result = new HashSet(); synchronized (myLock) { - for (DependencyContext.S s : myClassToSourceFile.keyCollection()) { - result.add(myContext.getValue(s)); - } + myClassToSourceFile.forEachEntry(new TIntIntProcedure() { + @Override + public boolean execute(int s, int b) { + result.add(myContext.getValue(s)); + return true; + } + }); } return result; @@ -1761,7 +1827,7 @@ public class Mappings { public void associate(final String classFileName, final Callbacks.SourceFileNameLookup sourceFileName, final ClassReader cr) { synchronized (myLock) { - final DependencyContext.S classFileNameS = myContext.get(classFileName); + final int classFileNameS = myContext.get(classFileName); final Pair>> result = new ClassfileAnalyzer(myContext).analyze(classFileNameS, cr); final ClassRepr repr = result.first; @@ -1769,27 +1835,27 @@ public class Mappings { final Set localAnnotationUsages = result.second.second; final String srcFileName = sourceFileName.get(repr == null ? null : myContext.getValue(repr.getSourceFileName())); - final DependencyContext.S sourceFileNameS = myContext.get(srcFileName); + final int sourceFileNameS = myContext.get(srcFileName); if (repr != null) { - final DependencyContext.S className = repr.name; + final int className = repr.name; myClassToSourceFile.put(repr.name, sourceFileNameS); mySourceFileToClasses.put(sourceFileNameS, repr); - for (DependencyContext.S s : repr.getSupers()) { + for (int s : repr.getSupers()) { myClassToSubclasses.put(s, repr.name); } for (UsageRepr.Usage u : localUsages.getUsages()) { - final DependencyContext.S owner = u.getOwner(); + final int owner = u.getOwner(); - if (!owner.equals(className)) { - final DependencyContext.S sourceFile = repr.getSourceFileName(); - final DependencyContext.S ownerSourceFile = myClassToSourceFile.get(owner); + if (owner != className) { + final int sourceFile = repr.getSourceFileName(); + final int ownerSourceFile = myClassToSourceFile.get(owner); - if (ownerSourceFile != null) { - if (!ownerSourceFile.equals(sourceFile)) { + if (ownerSourceFile > 0) { + if (ownerSourceFile != sourceFile) { myClassToClassDependency.put(owner, className); } } @@ -1825,18 +1891,18 @@ public class Mappings { addPostPass(new PostPass() { public void perform() { - final DependencyContext.S rootClassName = myContext.get(className.replace(".", "/")); - final DependencyContext.S fileName = myClassToSourceFile.get(rootClassName); + final int rootClassName = myContext.get(className.replace(".", "/")); + final int fileName = myClassToSourceFile.get(rootClassName); for (final String i : imports) { if (i.endsWith("*")) { continue; // filter out wildcard imports } - final DependencyContext.S iname = myContext.get(i.replace(".", "/")); + final int iname = myContext.get(i.replace(".", "/")); myClassToClassDependency.put(iname, rootClassName); - if (fileName != null) { + if (fileName > 0) { final UsageRepr.Cluster cluster = new UsageRepr.Cluster(); cluster.addUsage(rootClassName, UsageRepr.createClassUsage(myContext, iname)); mySourceFileToUsages.put(fileName, cluster); @@ -1899,4 +1965,23 @@ public class Mappings { } } } + + private static boolean addAll(final TIntHashSet whereToAdd, TIntHashSet whatToAdd) { + if (whatToAdd.isEmpty()) { + return false; + } + final Ref changed = new Ref(Boolean.FALSE); + whatToAdd.forEach(new TIntProcedure() { + @Override + public boolean execute(int value) { + if (whereToAdd.add(value)) { + changed.set(Boolean.TRUE); + } + return true; + } + }); + return changed.get(); + } + + } diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/MethodRepr.java b/jps/model/src/org/jetbrains/ether/dependencyView/MethodRepr.java index 46e4d2cc6ba3..97d8fcf38fcc 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/MethodRepr.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/MethodRepr.java @@ -88,7 +88,7 @@ class MethodRepr extends ProtoMember { }; } - public void updateClassUsages(final DependencyContext context, final DependencyContext.S owner, final UsageRepr.Cluster s) { + public void updateClassUsages(final DependencyContext context, final int owner, final UsageRepr.Cluster s) { type.updateClassUsages(context, owner, s); for (int i = 0; i < argumentTypes.length; i++) { @@ -102,13 +102,7 @@ class MethodRepr extends ProtoMember { } } - public MethodRepr(final DependencyContext context, - final int a, - final DependencyContext.S n, - final DependencyContext.S s, - final String d, - final String[] e, - final Object value) { + public MethodRepr(final DependencyContext context, final int a, final int n, final int s, final String d, final String[] e, final Object value) { super(a, s, n, TypeRepr.getType(context, Type.getReturnType(d)), value); exceptions = (Set)TypeRepr.createClassType(context, e, new HashSet()); argumentTypes = TypeRepr.getType(context, Type.getArgumentTypes(d)); @@ -152,7 +146,7 @@ class MethodRepr extends ProtoMember { @Override public boolean satisfy(MethodRepr that) { if (me == that) return true; - return me.name.equals(that.name) && Arrays.equals(me.argumentTypes, that.argumentTypes); + return me.name == that.name && Arrays.equals(me.argumentTypes, that.argumentTypes); } }; } @@ -164,12 +158,12 @@ class MethodRepr extends ProtoMember { final MethodRepr that = (MethodRepr)o; - return name.equals(that.name) && type.equals(that.type) && Arrays.equals(argumentTypes, that.argumentTypes); + return name == that.name && type.equals(that.type) && Arrays.equals(argumentTypes, that.argumentTypes); } @Override public int hashCode() { - return 31 * (31 * Arrays.hashCode(argumentTypes) + type.hashCode()) + name.hashCode(); + return 31 * (31 * Arrays.hashCode(argumentTypes) + type.hashCode()) + name; } private String getDescr(final DependencyContext context) { @@ -187,11 +181,11 @@ class MethodRepr extends ProtoMember { return buf.toString(); } - public UsageRepr.Usage createUsage(final DependencyContext context, final DependencyContext.S owner) { + public UsageRepr.Usage createUsage(final DependencyContext context, final int owner) { return UsageRepr.createMethodUsage(context, name, owner, getDescr(context)); } - public UsageRepr.Usage createMetaUsage(final DependencyContext context, final DependencyContext.S owner) { + public UsageRepr.Usage createMetaUsage(final DependencyContext context, final int owner) { return UsageRepr.createMetaMethodUsage(context, name, owner, getDescr(context)); } } diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/Proto.java b/jps/model/src/org/jetbrains/ether/dependencyView/Proto.java index fd2badf35b42..0c4dbf18e50a 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/Proto.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/Proto.java @@ -3,7 +3,9 @@ package org.jetbrains.ether.dependencyView; import groovyjarjarasm.asm.Opcodes; import org.jetbrains.ether.RW; -import java.io.*; +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; /** * Created by IntelliJ IDEA. @@ -14,10 +16,10 @@ import java.io.*; */ class Proto implements RW.Savable { public final int access; - public final DependencyContext.S signature; - public final DependencyContext.S name; + public final int signature; + public final int name; - protected Proto(final int access, final DependencyContext.S signature, final DependencyContext.S name) { + protected Proto(final int access, final int signature, final int name) { this.access = access; this.signature = signature; this.name = name; @@ -26,8 +28,8 @@ class Proto implements RW.Savable { protected Proto(final DataInput in) { try { access = in.readInt(); - signature = new DependencyContext.S(in); - name = new DependencyContext.S(in); + signature = in.readInt(); + name = in.readInt(); } catch (IOException e) { throw new RuntimeException(e); @@ -38,8 +40,8 @@ class Proto implements RW.Savable { public void save(final DataOutput out) { try { out.writeInt(access); - signature.save(out); - name.save(out); + out.writeInt(signature); + out.writeInt(name); } catch (IOException e) { throw new RuntimeException(e); @@ -53,7 +55,7 @@ class Proto implements RW.Savable { diff |= Difference.ACCESS; } - if (!past.signature.equals(signature)) { + if (past.signature != signature) { diff |= Difference.SIGNATURE; } diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/ProtoMember.java b/jps/model/src/org/jetbrains/ether/dependencyView/ProtoMember.java index 103c5d14a16f..867837dbe912 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/ProtoMember.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/ProtoMember.java @@ -29,11 +29,7 @@ abstract class ProtoMember extends Proto { return value != null; } - protected ProtoMember(final int access, - final DependencyContext.S signature, - final DependencyContext.S name, - final TypeRepr.AbstractType t, - final Object value) { + protected ProtoMember(final int access, final int signature, final int name, final TypeRepr.AbstractType t, final Object value) { super(access, signature, name); this.type = t; this.value = value; diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/TransientMultiMaplet.java b/jps/model/src/org/jetbrains/ether/dependencyView/TransientMultiMaplet.java deleted file mode 100644 index 71aafd8696c8..000000000000 --- a/jps/model/src/org/jetbrains/ether/dependencyView/TransientMultiMaplet.java +++ /dev/null @@ -1,145 +0,0 @@ -package org.jetbrains.ether.dependencyView; - -import org.jetbrains.ether.RW; - -import java.io.BufferedReader; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -/** - * Created by IntelliJ IDEA. - * User: db - * Date: 08.03.11 - * Time: 15:38 - * To change this template use File | Settings | File Templates. - */ -class TransientMultiMaplet implements MultiMaplet { - public static TransientMultiMaplet read(final BufferedReader r, - final RW.Reader xr, - final RW.Reader yr, - final CollectionConstructor cc) { - final TransientMultiMaplet result = new TransientMultiMaplet(cc); - - final int size = RW.readInt(r); - - for (int i = 0; i < size; i++) { - final X key = xr.read(r); - result.put(key, (Set)RW.readMany(r, yr, cc.create())); - } - - return result; - } - - public interface CollectionConstructor { - Collection create(); - } - - private final Map> myMap = new HashMap>(); - - private final CollectionConstructor constr; - - public TransientMultiMaplet(final CollectionConstructor c) { - constr = c; - } - - @Override - public boolean containsKey(final K key) { - return myMap.containsKey(key); - } - - @Override - public Collection get(final K key) { - return myMap.get(key); - } - - @Override - public void putAll(final MultiMaplet m) { - for (Map.Entry> e : m.entrySet()) { - put(e.getKey(), e.getValue()); - } - } - - @Override - public void put(final K key, final Collection value) { - final Collection x = myMap.get(key); - if (x == null) { - myMap.put(key, value); - } - else { - x.addAll(value); - } - } - - @Override - public void replace(K key, Collection value) { - if (value == null) { - myMap.remove(key); - } - else { - myMap.put(key, value); - } - } - - @Override - public void put(final K key, final V value) { - final Collection x = constr.create(); - x.add(value); - put(key, x); - } - - @Override - public void removeFrom(final K key, final V value) { - final Collection collection = myMap.get(key); - if (collection != null) { - if (collection.remove(value)) { - if (collection.isEmpty()) { - myMap.remove(key); - } - } - } - } - - @Override - public void removeAll(K key, Collection values) { - final Collection collection = myMap.get(key); - if (collection != null) { - if (collection.removeAll(values)) { - if (collection.isEmpty()) { - myMap.remove(key); - } - } - } - } - - @Override - public void remove(final K key) { - myMap.remove(key); - } - - @Override - public void replaceAll(MultiMaplet m) { - for (Map.Entry> e : m.entrySet()) { - replace(e.getKey(), e.getValue()); - } - } - - @Override - public Collection keyCollection() { - return myMap.keySet(); - } - - @Override - public Set>> entrySet() { - return myMap.entrySet(); - } - - @Override - public void close(){ - myMap.clear(); // free memory - } - - public void flush(boolean memoryCachesOnly) { - } -} diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/TypeRepr.java b/jps/model/src/org/jetbrains/ether/dependencyView/TypeRepr.java index 2b317e13ce4a..df21f87da060 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/TypeRepr.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/TypeRepr.java @@ -28,21 +28,21 @@ class TypeRepr { } interface AbstractType extends RW.Savable { - void updateClassUsages(DependencyContext context, DependencyContext.S owner, UsageRepr.Cluster s); + void updateClassUsages(DependencyContext context, int owner, UsageRepr.Cluster s); String getDescr(DependencyContext context); void save(DataOutput out); } public static class PrimitiveType implements AbstractType { - public final DependencyContext.S type; + public final int myType; @Override public String getDescr(final DependencyContext context) { - return context.getValue(type); + return context.getValue(myType); } @Override - public void updateClassUsages(final DependencyContext context, final DependencyContext.S owner, final UsageRepr.Cluster s) { + public void updateClassUsages(final DependencyContext context, final int owner, final UsageRepr.Cluster s) { } @@ -50,19 +50,24 @@ class TypeRepr { public void save(final DataOutput out) { try { out.writeInt(PRIMITIVE_TYPE); - type.save(out); + out.writeInt(myType); } catch (IOException e) { throw new RuntimeException(e); } } - PrimitiveType(final DependencyContext.S type) { - this.type = type; + PrimitiveType(final int type) { + this.myType = type; } PrimitiveType(final DataInput in) { - type = new DependencyContext.S(in); + try { + myType = in.readInt(); + } + catch (IOException e) { + throw new RuntimeException(e); + } } @Override @@ -72,12 +77,12 @@ class TypeRepr { final PrimitiveType that = (PrimitiveType)o; - return type.equals(that.type); + return myType == that.myType; } @Override public int hashCode() { - return type.hashCode(); + return myType; } } @@ -100,7 +105,7 @@ class TypeRepr { } @Override - public void updateClassUsages(final DependencyContext context, final DependencyContext.S owner, final UsageRepr.Cluster s) { + public void updateClassUsages(final DependencyContext context, final int owner, final UsageRepr.Cluster s) { elementType.updateClassUsages(context, owner, s); } @@ -136,7 +141,7 @@ class TypeRepr { } public static class ClassType implements AbstractType { - public final DependencyContext.S className; + public final int className; public final AbstractType[] typeArgs; @Override @@ -145,18 +150,18 @@ class TypeRepr { } @Override - public void updateClassUsages(final DependencyContext context, final DependencyContext.S owner, final UsageRepr.Cluster s) { + public void updateClassUsages(final DependencyContext context, final int owner, final UsageRepr.Cluster s) { s.addUsage(owner, UsageRepr.createClassUsage(context, className)); } - ClassType(final DependencyContext.S className) { + ClassType(final int className) { this.className = className; typeArgs = new AbstractType[0]; } ClassType(final DependencyContext context, final DataInput in) { try { - className = new DependencyContext.S(in); + className = in.readInt(); final int size = in.readInt(); typeArgs = new AbstractType[size]; @@ -178,7 +183,7 @@ class TypeRepr { final ClassType classType = (ClassType)o; - if (className != null ? !className.equals(classType.className) : classType.className != null) return false; + if (className != classType.className) return false; if (!Arrays.equals(typeArgs, classType.typeArgs)) return false; return true; @@ -186,7 +191,7 @@ class TypeRepr { @Override public int hashCode() { - int result = className != null ? className.hashCode() : 0; + int result = className; result = 31 * result + (typeArgs != null ? Arrays.hashCode(typeArgs) : 0); return result; } @@ -195,7 +200,7 @@ class TypeRepr { public void save(final DataOutput out) { try { out.writeInt(CLASS_TYPE); - className.save(out); + out.writeInt(className); out.writeInt(typeArgs.length); for (AbstractType t : typeArgs) { t.save(out); @@ -231,11 +236,11 @@ class TypeRepr { return acc; } - public static ClassType createClassType(final DependencyContext context, final DependencyContext.S s) { + public static ClassType createClassType(final DependencyContext context, final int s) { return (ClassType)context.getType(new ClassType(s)); } - public static AbstractType getType(final DependencyContext context, final DependencyContext.S descr) { + public static AbstractType getType(final DependencyContext context, final int descr) { final Type t = Type.getType(context.getValue(descr)); switch (t.getSort()) { diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/UsageRepr.java b/jps/model/src/org/jetbrains/ether/dependencyView/UsageRepr.java index 4c16f0a5504b..aae8d37647c5 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/UsageRepr.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/UsageRepr.java @@ -1,6 +1,7 @@ package org.jetbrains.ether.dependencyView; import com.intellij.util.io.DataExternalizer; +import gnu.trove.TIntHashSet; import org.jetbrains.asm4.Type; import org.jetbrains.ether.RW; @@ -26,13 +27,15 @@ class UsageRepr { private final static int CLASS_NEW_USAGE = 5; private final static int ANNOTATION_USAGE = 6; private final static int METAMETHOD_USAGE = 7; + private static final int DEFAULT_SET_CAPACITY = 32; + private static final float DEFAULT_SET_LOAD_FACTOR = 0.98f; private UsageRepr() { } public static class Cluster implements RW.Savable { - private final Map> myUsageToDependenciesMap = new HashMap>(); + private final Map myUsageToDependenciesMap = new HashMap(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); public Cluster() { } @@ -43,7 +46,7 @@ class UsageRepr { for (int i = 0; i < size; i++) { final Usage u = externalizer(context).read(in); - final Set s = (Set)RW.read(DependencyContext.descriptorS, new HashSet(), in); + final TIntHashSet s = RW.read(new TIntHashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR), in); myUsageToDependenciesMap.put(u, s); } } @@ -56,11 +59,11 @@ class UsageRepr { public void save(final DataOutput out) { try { out.writeInt(myUsageToDependenciesMap.size()); - for (Map.Entry> entry : myUsageToDependenciesMap.entrySet()) { + for (Map.Entry entry : myUsageToDependenciesMap.entrySet()) { final Usage u = entry.getKey(); u.save(out); - final Set deps = entry.getValue(); - RW.save(deps, DependencyContext.descriptorS, out); + final TIntHashSet deps = entry.getValue(); + RW.save(deps, out); } } catch (IOException e) { @@ -68,11 +71,11 @@ class UsageRepr { } } - public void addUsage(final DependencyContext.S residence, final Usage usage) { - Set s = myUsageToDependenciesMap.get(usage); + public void addUsage(final int residence, final Usage usage) { + TIntHashSet s = myUsageToDependenciesMap.get(usage); if (s == null) { - s = new HashSet(); + s = new TIntHashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); myUsageToDependenciesMap.put(usage, s); } @@ -83,7 +86,7 @@ class UsageRepr { return Collections.unmodifiableSet(myUsageToDependenciesMap.keySet()); } - public Set getResidence(final Usage usage) { + public TIntHashSet getResidence(final Usage usage) { return myUsageToDependenciesMap.get(usage); } @@ -124,33 +127,38 @@ class UsageRepr { } public static abstract class Usage implements RW.Savable { - public abstract DependencyContext.S getOwner(); + public abstract int getOwner(); } public static abstract class FMUsage extends Usage { - public final DependencyContext.S name; - public final DependencyContext.S owner; + public final int name; + public final int owner; @Override - public DependencyContext.S getOwner() { + public int getOwner() { return owner; } - private FMUsage(final DependencyContext.S n, final DependencyContext.S o) { + private FMUsage(final int n, final int o) { name = n; owner = o; } private FMUsage(final DataInput in) { - name = new DependencyContext.S(in); - owner = new DependencyContext.S(in); + try { + name = in.readInt(); + owner = in.readInt(); + } + catch (IOException e) { + throw new RuntimeException(e); + } } protected void save(final int tag, final DataOutput out) { try { out.writeInt(tag); - name.save(out); - owner.save(out); + out.writeInt(name); + out.writeInt(owner); } catch (IOException e) { throw new RuntimeException(e); @@ -164,27 +172,22 @@ class UsageRepr { FMUsage fmUsage = (FMUsage)o; - if (!name.equals(fmUsage.name)) return false; - if (!owner.equals(fmUsage.owner)) return false; + if (name != fmUsage.name) return false; + if (owner != fmUsage.owner) return false; return true; } @Override public int hashCode() { - int result = name.hashCode(); - result = 31 * result + owner.hashCode(); - return result; + return 31 * name + owner; } } public static class FieldUsage extends FMUsage { public final TypeRepr.AbstractType type; - private FieldUsage(final DependencyContext context, - final DependencyContext.S n, - final DependencyContext.S o, - final DependencyContext.S d) { + private FieldUsage(final DependencyContext context, final int n, final int o, final int d) { super(n, o); type = TypeRepr.getType(context, d); } @@ -212,20 +215,17 @@ class UsageRepr { final FieldUsage that = (FieldUsage)o; - return type.equals(that.type) && name.equals(that.name) && owner.equals(that.owner); + return type.equals(that.type) && name == that.name && owner == that.owner; } @Override public int hashCode() { - return 31 * (31 * type.hashCode() + (name.hashCode())) + owner.hashCode(); + return 31 * (31 * type.hashCode() + name) + owner; } } public static class FieldAssignUsage extends FieldUsage { - private FieldAssignUsage(final DependencyContext context, - final DependencyContext.S n, - final DependencyContext.S o, - final DependencyContext.S d) { + private FieldAssignUsage(final DependencyContext context, final int n, final int o, final int d) { super(context, n, o, d); } @@ -246,7 +246,7 @@ class UsageRepr { final FieldAssignUsage that = (FieldAssignUsage)o; - return type.equals(that.type) && name.equals(that.name) && owner.equals(that.owner); + return type.equals(that.type) && name == that.name && owner == that.owner; } @Override @@ -259,7 +259,7 @@ class UsageRepr { public final TypeRepr.AbstractType[] argumentTypes; public final TypeRepr.AbstractType returnType; - private MethodUsage(final DependencyContext context, final DependencyContext.S n, final DependencyContext.S o, final String d) { + private MethodUsage(final DependencyContext context, final int n, final int o, final String d) { super(n, o); argumentTypes = TypeRepr.getType(context, Type.getArgumentTypes(d)); returnType = TypeRepr.getType(context, Type.getReturnType(d)); @@ -293,25 +293,25 @@ class UsageRepr { if (!Arrays.equals(argumentTypes, that.argumentTypes)) return false; if (returnType != null ? !returnType.equals(that.returnType) : that.returnType != null) return false; - if (name != null ? !name.equals(that.name) : that.name != null) return false; - if (owner != null ? !owner.equals(that.owner) : that.owner != null) return false; + if (name != that.name) return false; + if (owner != that.owner) return false; return Arrays.equals(argumentTypes, that.argumentTypes) && returnType.equals(that.returnType) && - name.equals(that.name) && - owner.equals(that.owner); + name == that.name && + owner == that.owner; } @Override public int hashCode() { - return ((31 * Arrays.hashCode(argumentTypes) + (returnType.hashCode())) * 31 + (name.hashCode())) * 31 + (owner.hashCode()); + return ((31 * Arrays.hashCode(argumentTypes) + (returnType.hashCode())) * 31 + (name)) * 31 + (owner); } } public static class MetaMethodUsage extends FMUsage { private int myArity; - public MetaMethodUsage(final DependencyContext context, final DependencyContext.S n, final DependencyContext.S o, final String descr) { + public MetaMethodUsage(final DependencyContext context, final int n, final int o, final String descr) { super(n, o); myArity = TypeRepr.getType(context, Type.getArgumentTypes(descr)).length; } @@ -359,26 +359,31 @@ class UsageRepr { } public static class ClassUsage extends Usage { - final DependencyContext.S className; + final int className; @Override - public DependencyContext.S getOwner() { + public int getOwner() { return className; } - private ClassUsage(final DependencyContext.S n) { + private ClassUsage(final int n) { className = n; } private ClassUsage(final DataInput in) { - className = new DependencyContext.S(in); + try { + className = in.readInt(); + } + catch (IOException e) { + throw new RuntimeException(e); + } } @Override public void save(final DataOutput out) { try { out.writeInt(CLASS_USAGE); - className.save(out); + out.writeInt(className); } catch (IOException e) { throw new RuntimeException(e); @@ -392,36 +397,41 @@ class UsageRepr { final ClassUsage that = (ClassUsage)o; - return className.equals(that.className); + return className == that.className; } @Override public int hashCode() { - return className.hashCode(); + return className; } } public static class ClassExtendsUsage extends Usage { - protected final DependencyContext.S className; + protected final int className; @Override - public DependencyContext.S getOwner() { + public int getOwner() { return className; } - private ClassExtendsUsage(final DependencyContext.S n) { + private ClassExtendsUsage(final int n) { className = n; } private ClassExtendsUsage(final DataInput in) { - className = new DependencyContext.S(in); + try { + className = in.readInt(); + } + catch (IOException e) { + throw new RuntimeException(e); + } } @Override public void save(final DataOutput out) { try { out.writeInt(CLASS_EXTENDS_USAGE); - className.save(out); + out.writeInt(className); } catch (IOException e) { throw new RuntimeException(e); @@ -430,7 +440,7 @@ class UsageRepr { @Override public int hashCode() { - return className.hashCode() + 1; + return className + 1; } @Override @@ -440,14 +450,14 @@ class UsageRepr { ClassExtendsUsage that = (ClassExtendsUsage)o; - if (!className.equals(that.className)) return false; + if (className != that.className) return false; return true; } } public static class ClassNewUsage extends ClassExtendsUsage { - public ClassNewUsage(DependencyContext.S n) { + public ClassNewUsage(int n) { super(n); } @@ -459,7 +469,7 @@ class UsageRepr { public void save(final DataOutput out) { try { out.writeInt(CLASS_NEW_USAGE); - className.save(out); + out.writeInt(className); } catch (IOException e) { throw new RuntimeException(e); @@ -468,7 +478,7 @@ class UsageRepr { @Override public int hashCode() { - return className.hashCode() + 2; + return className + 2; } } @@ -487,7 +497,7 @@ class UsageRepr { }; final TypeRepr.ClassType type; - final Collection usedArguments; + final TIntHashSet usedArguments; final Collection usedTargets; public boolean satisfies(final Usage usage) { @@ -501,9 +511,9 @@ class UsageRepr { boolean argumentsSatisfy = false; if (usedArguments != null) { - final Collection arguments = new HashSet(usedArguments); + final TIntHashSet arguments = new TIntHashSet(usedArguments.toArray()); - arguments.removeAll(annotationUsage.usedArguments); + arguments.removeAll(annotationUsage.usedArguments.toArray()); argumentsSatisfy = !arguments.isEmpty(); } @@ -525,7 +535,7 @@ class UsageRepr { } private AnnotationUsage(final TypeRepr.ClassType type, - final Collection usedArguments, + final TIntHashSet usedArguments, final Collection targets) { this.type = type; this.usedArguments = usedArguments; @@ -537,7 +547,7 @@ class UsageRepr { try { type = (TypeRepr.ClassType)externalizer.read(in); - usedArguments = RW.read(DependencyContext.descriptorS, new HashSet(), in); + usedArguments = RW.read(new TIntHashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR), in); usedTargets = RW.read(elementTypeExternalizer, new HashSet(), in); } catch (IOException e) { @@ -550,7 +560,7 @@ class UsageRepr { try { out.writeInt(ANNOTATION_USAGE); type.save(out); - RW.save(usedArguments, DependencyContext.descriptorS, out); + RW.save(usedArguments, out); RW.save(usedTargets, elementTypeExternalizer, out); } catch (IOException e) { @@ -559,7 +569,7 @@ class UsageRepr { } @Override - public DependencyContext.S getOwner() { + public int getOwner() { return type.className; } @@ -587,50 +597,44 @@ class UsageRepr { } public static Usage createFieldUsage(final DependencyContext context, - final DependencyContext.S name, - final DependencyContext.S owner, - final DependencyContext.S descr) { + final int name, + final int owner, + final int descr) { return context.getUsage(new FieldUsage(context, name, owner, descr)); } public static Usage createFieldAssignUsage(final DependencyContext context, - final DependencyContext.S name, - final DependencyContext.S owner, - final DependencyContext.S descr) { + final int name, + final int owner, + final int descr) { return context.getUsage(new FieldAssignUsage(context, name, owner, descr)); } public static Usage createMethodUsage(final DependencyContext context, - final DependencyContext.S name, - final DependencyContext.S owner, + final int name, + final int owner, final String descr) { return context.getUsage(new MethodUsage(context, name, owner, descr)); } - public static Usage createMetaMethodUsage(final DependencyContext context, - final DependencyContext.S name, - final DependencyContext.S owner, - final String descr) { + public static Usage createMetaMethodUsage(final DependencyContext context, final int name, final int owner, final String descr) { return context.getUsage(new MetaMethodUsage(context, name, owner, descr)); } - public static Usage createClassUsage(final DependencyContext context, final DependencyContext.S name) { + public static Usage createClassUsage(final DependencyContext context, final int name) { return context.getUsage(new ClassUsage(name)); } - public static Usage createClassExtendsUsage(final DependencyContext context, final DependencyContext.S name) { + public static Usage createClassExtendsUsage(final DependencyContext context, final int name) { return context.getUsage(new ClassExtendsUsage(name)); } - public static Usage createClassNewUsage(final DependencyContext context, final DependencyContext.S name) { + public static Usage createClassNewUsage(final DependencyContext context, final int name) { return context.getUsage(new ClassNewUsage(name)); } - public static Usage createAnnotationUsage(final DependencyContext context, - final TypeRepr.ClassType type, - final Collection usedArguments, - final Collection targets) { + public static Usage createAnnotationUsage(final DependencyContext context, final TypeRepr.ClassType type, final TIntHashSet usedArguments, final Collection targets) { return context.getUsage(new AnnotationUsage(type, usedArguments, targets)); }