diff options
Diffstat (limited to 'java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIndex.java')
-rw-r--r-- | java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIndex.java | 166 |
1 files changed, 100 insertions, 66 deletions
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIndex.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIndex.java index 6a4b32783c95..297b2b694c62 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIndex.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIndex.java @@ -19,31 +19,29 @@ import com.intellij.ide.highlighter.JavaClassFileType; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileWithId; import com.intellij.util.SystemProperties; import com.intellij.util.indexing.*; import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.DataInputOutputUtil; -import com.intellij.util.io.EnumeratorIntegerDescriptor; +import com.intellij.util.io.DifferentSerializableBytesImplyNonEqualityPolicy; import com.intellij.util.io.KeyDescriptor; import org.jetbrains.annotations.NotNull; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; /** * @author lambdamix */ -public class BytecodeAnalysisIndex extends FileBasedIndexExtension<Integer, Collection<IntIdEquation>> { - public static final ID<Integer, Collection<IntIdEquation>> NAME = ID.create("bytecodeAnalysis"); +public class BytecodeAnalysisIndex extends FileBasedIndexExtension<Long, IdEquation> { + public static final ID<Long, IdEquation> NAME = ID.create("bytecodeAnalysis"); private final EquationExternalizer myExternalizer = new EquationExternalizer(); - private static final DataIndexer<Integer, Collection<IntIdEquation>, FileContent> INDEXER = + private static final DataIndexer<Long, IdEquation, FileContent> INDEXER = new ClassDataIndexer(BytecodeAnalysisConverter.getInstance()); + private static final SmartLongKeyDescriptor KEY_DESCRIPTOR = new SmartLongKeyDescriptor(); - private static final int ourInternalVersion = 2; + private static final int ourInternalVersion = 3; private static boolean ourEnabled = SystemProperties.getBooleanProperty("idea.enable.bytecode.contract.inference", isEnabledByDefault()); private static boolean isEnabledByDefault() { @@ -51,31 +49,27 @@ public class BytecodeAnalysisIndex extends FileBasedIndexExtension<Integer, Coll return application.isInternal() || application.isUnitTestMode(); } - public static int indexKey(VirtualFile file, boolean parameters) { - return (file instanceof VirtualFileWithId ? ((VirtualFileWithId)file).getId() * 2 : -2) + (parameters ? 1 : 0); - } - @NotNull @Override - public ID<Integer, Collection<IntIdEquation>> getName() { + public ID<Long, IdEquation> getName() { return NAME; } @NotNull @Override - public DataIndexer<Integer, Collection<IntIdEquation>, FileContent> getIndexer() { + public DataIndexer<Long, IdEquation, FileContent> getIndexer() { return INDEXER; } @NotNull @Override - public KeyDescriptor<Integer> getKeyDescriptor() { - return EnumeratorIntegerDescriptor.INSTANCE; + public KeyDescriptor<Long> getKeyDescriptor() { + return KEY_DESCRIPTOR; } @NotNull @Override - public DataExternalizer<Collection<IntIdEquation>> getValueExternalizer() { + public DataExternalizer<IdEquation> getValueExternalizer() { return myExternalizer; } @@ -100,68 +94,108 @@ public class BytecodeAnalysisIndex extends FileBasedIndexExtension<Integer, Coll return ourInternalVersion + BytecodeAnalysisConverter.getInstance().getVersion() + (ourEnabled ? 0xFF : 0); } - public static class EquationExternalizer implements DataExternalizer<Collection<IntIdEquation>> { + public static class EquationExternalizer implements DataExternalizer<IdEquation>, DifferentSerializableBytesImplyNonEqualityPolicy { @Override - public void save(@NotNull DataOutput out, Collection<IntIdEquation> equations) throws IOException { - DataInputOutputUtil.writeINT(out, equations.size()); - - for (IntIdEquation equation : equations) { - out.writeInt(equation.id); - IntIdResult rhs = equation.rhs; - if (rhs instanceof IntIdFinal) { - IntIdFinal finalResult = (IntIdFinal)rhs; - out.writeBoolean(true); // final flag - DataInputOutputUtil.writeINT(out, finalResult.value.ordinal()); - } else { - IntIdPending pendResult = (IntIdPending)rhs; - out.writeBoolean(false); // pending flag - DataInputOutputUtil.writeINT(out, pendResult.delta.length); - - for (IntIdComponent component : pendResult.delta) { - DataInputOutputUtil.writeINT(out, component.value.ordinal()); - int[] ids = component.ids; - DataInputOutputUtil.writeINT(out, ids.length); - for (int id : ids) { - out.writeInt(id); - } + public void save(@NotNull DataOutput out, IdEquation equation) throws IOException { + long id = equation.id; + int sign = id > 0 ? 1 : -1; + id = Math.abs(id); + int primaryId = (int)(id / BytecodeAnalysisConverter.SHIFT); + int secondaryId = (int)(id % BytecodeAnalysisConverter.SHIFT); + out.writeInt(sign * primaryId); + DataInputOutputUtil.writeINT(out, secondaryId); + IdResult rhs = equation.rhs; + if (rhs instanceof IdFinal) { + IdFinal finalResult = (IdFinal)rhs; + out.writeBoolean(true); // final flag + DataInputOutputUtil.writeINT(out, finalResult.value.ordinal()); + } else { + IdPending pendResult = (IdPending)rhs; + out.writeBoolean(false); // pending flag + DataInputOutputUtil.writeINT(out, pendResult.delta.length); + + for (IntIdComponent component : pendResult.delta) { + DataInputOutputUtil.writeINT(out, component.value.ordinal()); + long[] ids = component.ids; + DataInputOutputUtil.writeINT(out, ids.length); + for (long id1 : ids) { + sign = id1 > 0 ? 1 : -1; + id = Math.abs(id1); + primaryId = (int)(id / BytecodeAnalysisConverter.SHIFT); + secondaryId = (int)(id % BytecodeAnalysisConverter.SHIFT); + out.writeInt(sign * primaryId); + DataInputOutputUtil.writeINT(out, secondaryId); } } } } @Override - public Collection<IntIdEquation> read(@NotNull DataInput in) throws IOException { - - int size = DataInputOutputUtil.readINT(in); - ArrayList<IntIdEquation> result = new ArrayList<IntIdEquation>(size); - - for (int x = 0; x < size; x++) { - int equationId = in.readInt(); - boolean isFinal = in.readBoolean(); // flag - if (isFinal) { + public IdEquation read(@NotNull DataInput in) throws IOException { + long primaryId = in.readInt(); + int sign = primaryId > 0 ? 1 : -1; + primaryId = Math.abs(primaryId); + int secondaryId = DataInputOutputUtil.readINT(in); + long equationId = sign * (primaryId * BytecodeAnalysisConverter.SHIFT + secondaryId); + boolean isFinal = in.readBoolean(); // flag + if (isFinal) { + int ordinal = DataInputOutputUtil.readINT(in); + Value value = Value.values()[ordinal]; + return new IdEquation(equationId, new IdFinal(value)); + } else { + + int sumLength = DataInputOutputUtil.readINT(in); + IntIdComponent[] components = new IntIdComponent[sumLength]; + + for (int i = 0; i < sumLength; i++) { int ordinal = DataInputOutputUtil.readINT(in); Value value = Value.values()[ordinal]; - result.add(new IntIdEquation(equationId, new IntIdFinal(value))); - } else { - - int sumLength = DataInputOutputUtil.readINT(in); - IntIdComponent[] components = new IntIdComponent[sumLength]; - - for (int i = 0; i < sumLength; i++) { - int ordinal = DataInputOutputUtil.readINT(in); - Value value = Value.values()[ordinal]; - int componentSize = DataInputOutputUtil.readINT(in); - int[] ids = new int[componentSize]; - for (int j = 0; j < componentSize; j++) { - ids[j] = in.readInt(); - } - components[i] = new IntIdComponent(value, ids); + int componentSize = DataInputOutputUtil.readINT(in); + long[] ids = new long[componentSize]; + for (int j = 0; j < componentSize; j++) { + primaryId = in.readInt(); + sign = primaryId > 0 ? 1 : -1; + primaryId = Math.abs(primaryId); + secondaryId = DataInputOutputUtil.readINT(in); + long id = sign * (primaryId * BytecodeAnalysisConverter.SHIFT + secondaryId); + ids[j] = id; } - result.add(new IntIdEquation(equationId, new IntIdPending(components))); + components[i] = new IntIdComponent(value, ids); } + return new IdEquation(equationId, new IdPending(components)); } + } + } + + private static class SmartLongKeyDescriptor implements KeyDescriptor<Long>, DifferentSerializableBytesImplyNonEqualityPolicy { + @Override + public void save(@NotNull DataOutput out, Long value) throws IOException { + long id = value.longValue(); + int sign = id > 0 ? 1 : -1; + id = Math.abs(id); + int primaryId = (int)(id / BytecodeAnalysisConverter.SHIFT); + int secondaryId = (int)(id % BytecodeAnalysisConverter.SHIFT); + out.writeInt(primaryId * sign); + DataInputOutputUtil.writeINT(out, secondaryId); + } + + @Override + public Long read(@NotNull DataInput in) throws IOException { + long primaryId = in.readInt(); + int sign = primaryId > 0 ? 1 : -1; + primaryId = Math.abs(primaryId); + int secondaryId = DataInputOutputUtil.readINT(in); + return sign * (primaryId * BytecodeAnalysisConverter.SHIFT + secondaryId); + } - return result; + @Override + public int getHashCode(Long value) { + return value.hashCode(); + } + + @Override + public boolean isEqual(Long val1, Long val2) { + return val1.longValue() == val2.longValue(); } } } |