diff --git a/java/java-tests/testSrc/com/intellij/util/indexing/impl/perFileVersion/PersistentSubIndexerVersionEnumeratorTest.java b/java/java-tests/testSrc/com/intellij/util/indexing/impl/perFileVersion/PersistentSubIndexerVersionEnumeratorTest.java index 755b0313bfc5..ea40e777f93c 100644 --- a/java/java-tests/testSrc/com/intellij/util/indexing/impl/perFileVersion/PersistentSubIndexerVersionEnumeratorTest.java +++ b/java/java-tests/testSrc/com/intellij/util/indexing/impl/perFileVersion/PersistentSubIndexerVersionEnumeratorTest.java @@ -8,9 +8,10 @@ import com.intellij.openapi.vfs.VirtualFileWithId; import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase; import com.intellij.testFramework.fixtures.TempDirTestFixture; import com.intellij.testFramework.fixtures.impl.TempDirTestFixtureImpl; -import com.intellij.util.containers.ContainerUtil; import com.intellij.util.indexing.CompositeDataIndexer; import com.intellij.util.indexing.FileContent; +import com.intellij.util.indexing.IndexedFile; +import com.intellij.util.indexing.IndexedFileImpl; import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.KeyDescriptor; import org.jetbrains.annotations.NotNull; @@ -18,9 +19,7 @@ import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; -import java.util.Collection; import java.util.Map; -import java.util.Set; public class PersistentSubIndexerVersionEnumeratorTest extends LightJavaCodeInsightFixtureTestCase { private TempDirTestFixture myDirTestFixture; @@ -103,13 +102,8 @@ public class PersistentSubIndexerVersionEnumeratorTest extends LightJavaCodeInsi private static class MyPerFileIndexExtension implements CompositeDataIndexer { @Nullable @Override - public MyIndexFileAttribute calculateSubIndexer(@NotNull VirtualFile content) { - return content.getUserData(ATTRIBUTE_KEY); - } - - @Override - public boolean requiresContentForSubIndexerEvaluation(@NotNull VirtualFile content) { - return false; + public MyIndexFileAttribute calculateSubIndexer(@NotNull IndexedFile file) { + return file.getFile().getUserData(ATTRIBUTE_KEY); } @NotNull @@ -161,7 +155,7 @@ public class PersistentSubIndexerVersionEnumeratorTest extends LightJavaCodeInsi VirtualFile file = file(attribute); file.putUserData(ATTRIBUTE_KEY, attribute); try { - myMap.persistIndexedState(((VirtualFileWithId)file).getId(), file); + myMap.setIndexedState(((VirtualFileWithId) file).getId(), new IndexedFileImpl(file)); } catch (IOException e) { LOG.error(e); @@ -175,7 +169,7 @@ public class PersistentSubIndexerVersionEnumeratorTest extends LightJavaCodeInsi VirtualFile file = file(attribute); file.putUserData(ATTRIBUTE_KEY, attribute); try { - return myMap.isIndexed(((VirtualFileWithId)file).getId(), file); + return myMap.isIndexed(((VirtualFileWithId)file).getId(), new IndexedFileImpl(file)); } catch (IOException e) { LOG.error(e); diff --git a/platform/core-impl/src/com/intellij/util/indexing/IndexedFileImpl.java b/platform/core-impl/src/com/intellij/util/indexing/IndexedFileImpl.java index 6ebe0240b092..9cbb66af4ee8 100644 --- a/platform/core-impl/src/com/intellij/util/indexing/IndexedFileImpl.java +++ b/platform/core-impl/src/com/intellij/util/indexing/IndexedFileImpl.java @@ -12,6 +12,10 @@ public class IndexedFileImpl extends UserDataHolderBase implements IndexedFile { protected final String myFileName; protected final FileType myFileType; + public IndexedFileImpl(@NotNull VirtualFile file) { + this(file, file.getFileType()); + } + public IndexedFileImpl(@NotNull VirtualFile file, @NotNull FileType type) { myFile = file; myFileName = file.getName(); diff --git a/platform/indexing-api/src/com/intellij/util/indexing/CompositeDataIndexer.java b/platform/indexing-api/src/com/intellij/util/indexing/CompositeDataIndexer.java index d5b8226dd01e..716e4fd25244 100644 --- a/platform/indexing-api/src/com/intellij/util/indexing/CompositeDataIndexer.java +++ b/platform/indexing-api/src/com/intellij/util/indexing/CompositeDataIndexer.java @@ -1,24 +1,25 @@ // Copyright 2000-2019 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.util.indexing; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.io.KeyDescriptor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Collection; import java.util.Collections; import java.util.Map; public interface CompositeDataIndexer extends DataIndexer { + /** + * @return null if file is not acceptable for indexing + */ @Nullable - SubIndexerType calculateSubIndexer(@NotNull VirtualFile content); + SubIndexerType calculateSubIndexer(@NotNull IndexedFile file); /** * determine should we load content to provide sub-indexer */ - default boolean requiresContentForSubIndexerEvaluation(@NotNull VirtualFile content) { + default boolean requiresContentForSubIndexerEvaluation(@NotNull IndexedFile file) { return false; } @@ -29,13 +30,16 @@ public interface CompositeDataIndexer e @NotNull SubIndexerVersion getSubIndexerVersion(@NotNull SubIndexerType subIndexerType); + /** + * SubIndexerVersion descriptor must depend only on corresponding index version, should be read even SubIndexerType is not available anymore + */ @NotNull KeyDescriptor getSubIndexerVersionDescriptor(); @NotNull @Override default Map map(@NotNull FileContent inputData) { - SubIndexerType subIndexerType = calculateSubIndexer(inputData.getFile()); + SubIndexerType subIndexerType = calculateSubIndexer(inputData); if (subIndexerType == null) return Collections.emptyMap(); return map(inputData, subIndexerType); } diff --git a/platform/indexing-impl/src/com/intellij/util/indexing/SingleEntryCompositeIndexer.java b/platform/indexing-impl/src/com/intellij/util/indexing/SingleEntryCompositeIndexer.java new file mode 100644 index 000000000000..b1a76ced36c2 --- /dev/null +++ b/platform/indexing-impl/src/com/intellij/util/indexing/SingleEntryCompositeIndexer.java @@ -0,0 +1,28 @@ +// Copyright 2000-2019 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.util.indexing; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; + +public abstract class SingleEntryCompositeIndexer extends SingleEntryIndexer implements CompositeDataIndexer { + protected SingleEntryCompositeIndexer(boolean acceptNullValues) { + super(acceptNullValues); + } + + @NotNull + @Override + public final Map map(@NotNull FileContent inputData, @NotNull SubIndexerType indexerType) { + throw new AssertionError(); + } + + @Nullable + @Override + protected V computeValue(@NotNull FileContent inputData) { + return computeValue(inputData, calculateSubIndexer(inputData)); + } + + @Nullable + protected abstract V computeValue(@NotNull FileContent inputData, @NotNull SubIndexerType indexerType); +} diff --git a/platform/lang-impl/src/com/intellij/util/indexing/impl/perFileVersion/PersistentSubIndexerRetriever.java b/platform/lang-impl/src/com/intellij/util/indexing/impl/perFileVersion/PersistentSubIndexerRetriever.java index d94419f71b77..4fb5a92d5160 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/impl/perFileVersion/PersistentSubIndexerRetriever.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/impl/perFileVersion/PersistentSubIndexerRetriever.java @@ -1,13 +1,9 @@ // Copyright 2000-2019 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.util.indexing.impl.perFileVersion; -import com.intellij.concurrency.ConcurrentCollectionFactory; import com.intellij.openapi.util.Pair; -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.containers.ConcurrentFactoryMap; -import com.intellij.util.containers.ContainerUtil; import com.intellij.util.indexing.*; import com.intellij.util.io.DataInputOutputUtil; import gnu.trove.THashMap; @@ -22,11 +18,9 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.Map; -class PersistentSubIndexerRetriever { +public class PersistentSubIndexerRetriever { private static final String INDEXED_VERSIONS = "indexed_versions"; - @NotNull - private final Map myVersionOwnerMap; @NotNull private final PersistentSubIndexerVersionEnumerator myPersistentVersionEnumerator; @NotNull @@ -34,7 +28,7 @@ class PersistentSubIndexerRetriever { @NotNull private final CompositeDataIndexer myIndexer; - PersistentSubIndexerRetriever(@NotNull ID id, + public PersistentSubIndexerRetriever(@NotNull ID id, int indexVersion, @NotNull CompositeDataIndexer indexer) throws IOException { this(IndexInfrastructure.getIndexRootDir(id), id.getName(), indexVersion, indexer); @@ -48,23 +42,20 @@ class PersistentSubIndexerRetriever { Path versionMapRoot = root.toPath().resolve(versionMapRoot()); myFileAttribute = getFileAttribute(indexName, indexVersion); myIndexer = indexer; - myVersionOwnerMap = ConcurrentFactoryMap.create(indexer::getSubIndexerVersion, - () -> ConcurrentCollectionFactory.createMap(ContainerUtil.identityStrategy())); - myPersistentVersionEnumerator = new PersistentSubIndexerVersionEnumerator<>( versionMapRoot.resolve(INDEXED_VERSIONS).toFile(), indexer.getSubIndexerVersionDescriptor()); } - void clear() throws IOException { + public void clear() throws IOException { myPersistentVersionEnumerator.clear(); } - void close() throws IOException { + public void close() throws IOException { myPersistentVersionEnumerator.close(); } - void flush() throws IOException { + public void flush() throws IOException { myPersistentVersionEnumerator.flush(); } @@ -72,13 +63,13 @@ class PersistentSubIndexerRetriever { return Paths.get(".perFileVersion", INDEXED_VERSIONS); } - public void persistIndexedState(int fileId, @NotNull VirtualFile file) throws IOException { + public void setIndexedState(int fileId, @NotNull IndexedFile file) throws IOException { try (DataOutputStream stream = FSRecords.writeAttribute(fileId, myFileAttribute)) { DataInputOutputUtil.writeINT(stream, getFileIndexerId(file)); } } - public boolean isIndexed(int fileId, @NotNull VirtualFile file) throws IOException { + public boolean isIndexed(int fileId, @NotNull IndexedFile file) throws IOException { DataInputStream stream = FSRecords.readAttributeWithLock(fileId, myFileAttribute); int currentIndexedVersion; if (stream != null) { @@ -89,9 +80,10 @@ class PersistentSubIndexerRetriever { return false; } - private int getFileIndexerId(@NotNull VirtualFile file) throws IOException { - SubIndexerVersion version = myVersionOwnerMap.get(myIndexer.calculateSubIndexer(file)); - if (version == null) return -1; + private int getFileIndexerId(@NotNull IndexedFile file) throws IOException { + SubIndexerType type = myIndexer.calculateSubIndexer(file); + if (type == null) return -1; + SubIndexerVersion version = myIndexer.getSubIndexerVersion(type); return myPersistentVersionEnumerator.enumerate(version); }