From 341b7b68be475e5908b43b75a2cbc57d8f89ad22 Mon Sep 17 00:00:00 2001 From: Dmitro Batko Date: Wed, 15 Jan 2020 15:03:37 +0300 Subject: [PATCH] do not read content if composite class file builder is enabled and configuration is not changed GitOrigin-RevId: 8c3e48c6fc1285d5affc5d074afd6210ae969068 --- .../impl/compiled/ClassFileStubBuilder.java | 7 ++ .../psi/stubs/BinaryFileStubBuilder.java | 5 ++ .../psi/stubs/CompositeBinaryBuilderMap.java | 85 +++++++++++++++++++ .../intellij/psi/stubs/StubUpdatingIndex.java | 41 +++++++-- .../util/indexing/VfsAwareMapReduceIndex.java | 6 +- 5 files changed, 135 insertions(+), 9 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/psi/stubs/CompositeBinaryBuilderMap.java diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java index 6e6546881bc7..a6cc4b183aa5 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java @@ -17,6 +17,7 @@ import org.jetbrains.annotations.Nullable; import java.util.Comparator; import java.util.List; import java.util.function.Supplier; +import java.util.stream.Stream; import static com.intellij.psi.compiled.ClassFileDecompilers.Full; @@ -33,6 +34,12 @@ public class ClassFileStubBuilder implements BinaryFileStubBuilder.CompositeBina return true; } + @NotNull + @Override + public Stream getAllSubBuilders() { + return ClassFileDecompilers.EP_NAME.extensions(); + } + @Nullable @Override public ClassFileDecompilers.Decompiler getSubBuilder(@NotNull FileContent fileContent) { diff --git a/platform/core-api/src/com/intellij/psi/stubs/BinaryFileStubBuilder.java b/platform/core-api/src/com/intellij/psi/stubs/BinaryFileStubBuilder.java index cbc842c783a9..e726b6d92bac 100644 --- a/platform/core-api/src/com/intellij/psi/stubs/BinaryFileStubBuilder.java +++ b/platform/core-api/src/com/intellij/psi/stubs/BinaryFileStubBuilder.java @@ -24,6 +24,8 @@ import com.intellij.util.indexing.FileContent; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.stream.Stream; + public interface BinaryFileStubBuilder { boolean acceptsFile(@NotNull VirtualFile file); @@ -33,6 +35,9 @@ public interface BinaryFileStubBuilder { int getStubVersion(); interface CompositeBinaryFileStubBuilder extends BinaryFileStubBuilder { + @NotNull + Stream getAllSubBuilders(); + @Nullable SubBuilder getSubBuilder(@NotNull FileContent fileContent); diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/CompositeBinaryBuilderMap.java b/platform/lang-impl/src/com/intellij/psi/stubs/CompositeBinaryBuilderMap.java new file mode 100644 index 000000000000..cc025dd4c8e0 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/psi/stubs/CompositeBinaryBuilderMap.java @@ -0,0 +1,85 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.psi.stubs; + +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.newvfs.FileAttribute; +import com.intellij.openapi.vfs.newvfs.persistent.FSRecords; +import com.intellij.util.indexing.IndexInfrastructure; +import com.intellij.util.io.DataInputOutputUtil; +import com.intellij.util.io.PersistentStringEnumerator; +import gnu.trove.TObjectIntHashMap; +import org.jetbrains.annotations.NotNull; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.Map; + +class CompositeBinaryBuilderMap { + private static final FileAttribute VERSION_STAMP = new FileAttribute("stubIndex.cumulativeBinaryBuilder", 1, true); + + private final TObjectIntHashMap myCumulativeVersionMap; + + CompositeBinaryBuilderMap() throws IOException { + try (PersistentStringEnumerator cumulativeVersionEnumerator = new PersistentStringEnumerator(registeredCompositeBinaryBuilderFiles())) { + myCumulativeVersionMap = new TObjectIntHashMap<>(); + + for (Map.Entry entry : BinaryFileStubBuilders.INSTANCE.getAllRegisteredExtensions().entrySet()) { + FileType fileType = entry.getKey(); + BinaryFileStubBuilder builder = entry.getValue(); + + if (builder instanceof BinaryFileStubBuilder.CompositeBinaryFileStubBuilder) { + StringBuilder cumulativeVersion = new StringBuilder(); + + cumulativeVersion.append(fileType.getName()); + cumulativeVersion.append("->"); + + cumulativeVersion.append(builder.getClass().getName()); + cumulativeVersion.append(":"); + cumulativeVersion.append(builder.getStubVersion()); + + BinaryFileStubBuilder.CompositeBinaryFileStubBuilder compositeBuilder = (BinaryFileStubBuilder.CompositeBinaryFileStubBuilder)builder; + compositeBuilder.getAllSubBuilders().forEach(b -> { + cumulativeVersion.append(";"); + cumulativeVersion.append(compositeBuilder.getSubBuilderVersion(b)); + }); + + myCumulativeVersionMap.put(fileType, cumulativeVersionEnumerator.enumerate(cumulativeVersion.toString())); + } + } + } + } + + void persistState(int fileId, @NotNull VirtualFile file) throws IOException { + int version = getBuilderCumulativeVersion(file); + if (version == 0) return; + try (DataOutputStream stream = FSRecords.writeAttribute(fileId, VERSION_STAMP)) { + DataInputOutputUtil.writeINT(stream, version); + } + } + + boolean isUpToDateState(int fileId, @NotNull VirtualFile file) throws IOException { + DataInputStream stream = FSRecords.readAttributeWithLock(fileId, VERSION_STAMP); + int indexedVersion = stream != null ? DataInputOutputUtil.readINT(stream) : 0; + if (indexedVersion == 0) return false; + int actualVersion = getBuilderCumulativeVersion(file); + return actualVersion == indexedVersion; + } + + private int getBuilderCumulativeVersion(@NotNull VirtualFile file) { + FileType[] type = {null}; + ProgressManager.getInstance().executeNonCancelableSection(() -> { + type[0] = file.getFileType(); + }); + return myCumulativeVersionMap.get(type[0]); + } + + @NotNull + private static Path registeredCompositeBinaryBuilderFiles() { + return new File(IndexInfrastructure.getIndexRootDir(StubUpdatingIndex.INDEX_ID), ".binary_builders").toPath(); + } +} diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java index c16266c2059f..4b979db25128 100644 --- a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java +++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java @@ -16,7 +16,6 @@ import com.intellij.openapi.project.ProjectUtil; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.newvfs.FileAttribute; -import com.intellij.openapi.vfs.newvfs.NewVirtualFile; import com.intellij.psi.tree.IFileElementType; import com.intellij.psi.tree.IStubFileElementType; import com.intellij.util.BitUtil; @@ -40,7 +39,7 @@ import java.util.Map; public class StubUpdatingIndex extends SingleEntryFileBasedIndexExtension implements CustomImplementationFileBasedIndexExtension { static final Logger LOG = Logger.getInstance(StubUpdatingIndex.class); - private static final int VERSION = 43 + (PersistentHashMapValueStorage.COMPRESSION_ENABLED ? 1 : 0) + (InvertedIndex.ARE_COMPOSITE_INDEXERS_ENABLED ? 1 : 0); + private static final int VERSION = 43 + (PersistentHashMapValueStorage.COMPRESSION_ENABLED ? 1 : 0) + (InvertedIndex.ARE_COMPOSITE_INDEXERS_ENABLED ? 2 : 0); // todo remove once we don't need this for stub-ast mismatch debug info private static final FileAttribute INDEXED_STAMP = new FileAttribute("stubIndexStamp", 3, true); @@ -280,7 +279,11 @@ public class StubUpdatingIndex extends SingleEntryFileBasedIndexExtension { private StubIndexImpl myStubIndex; @Nullable - private final StubVersionMap myStubVersionMap = InvertedIndex.ARE_COMPOSITE_INDEXERS_ENABLED ? null : new StubVersionMap(); + private final StubVersionMap myStubVersionMap = + InvertedIndex.ARE_COMPOSITE_INDEXERS_ENABLED ? null : new StubVersionMap(); + @Nullable + private final CompositeBinaryBuilderMap myCompositeBinaryBuilderMap = + InvertedIndex.ARE_COMPOSITE_INDEXERS_ENABLED ? new CompositeBinaryBuilderMap() : null; MyIndex(@NotNull FileBasedIndexExtension extension, @NotNull IndexStorage storage) throws StorageException, IOException { @@ -393,11 +396,20 @@ public class StubUpdatingIndex extends SingleEntryFileBasedIndexExtension extends MapReduceIndex extends MapReduceIndex