refactor MapReduceIndex to have simple constructor arguments and all index implementation inside

This commit is contained in:
Maxim.Mossienko
2016-03-05 22:33:07 +01:00
parent b9b9c6c8f6
commit 72125c450f
9 changed files with 240 additions and 198 deletions
@@ -24,7 +24,6 @@ import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.fileEditor.FileEditor
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.fileTypes.PlainTextFileType
import com.intellij.openapi.util.Factory
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.openapi.vfs.VirtualFile
@@ -71,7 +70,7 @@ public class IndexTest extends JavaCodeInsightFixtureTestCase {
}
public void testUpdate() throws StorageException, IOException {
StringIndex index = createIndex(new EnumeratorStringDescriptor())
StringIndex index = createIndex(getTestName(false), new EnumeratorStringDescriptor())
try {
// build index
@@ -118,7 +117,7 @@ public class IndexTest extends JavaCodeInsightFixtureTestCase {
}
public void testUpdateWithCustomEqualityPolicy() {
def index = createIndex(new CaseInsensitiveEnumeratorStringDescriptor())
def index = createIndex(getTestName(false), new CaseInsensitiveEnumeratorStringDescriptor())
try {
index.update("a.java", "x", null)
assertDataEquals(index.getFilesByWord("x"), "a.java")
@@ -136,21 +135,12 @@ public class IndexTest extends JavaCodeInsightFixtureTestCase {
}
}
private static StringIndex createIndex(EnumeratorStringDescriptor keyDescriptor) {
private static StringIndex createIndex(String testName, EnumeratorStringDescriptor keyDescriptor) {
final File storageFile = FileUtil.createTempFile("index_test", "storage");
final File metaIndexFile = FileUtil.createTempFile("index_test_inputs", "storage");
PersistentHashMap<Integer, Collection<String>> index = createMetaIndex(metaIndexFile);
final MapIndexStorage indexStorage = new MapIndexStorage(storageFile, keyDescriptor, new EnumeratorStringDescriptor(), 16 * 1024);
return new StringIndex(indexStorage, new Factory<PersistentHashMap<Integer, Collection<String>>>() {
@Override
public PersistentHashMap<Integer, Collection<String>> create() {
try {
return createMetaIndex(metaIndexFile);
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
});
return new StringIndex(testName, indexStorage, index);
}
private static PersistentHashMap<Integer, Collection<String>> createMetaIndex(File metaIndexFile) throws IOException {
@@ -15,11 +15,10 @@
*/
package com.intellij.index;
import com.intellij.openapi.util.Factory;
import com.intellij.util.indexing.DataIndexer;
import com.intellij.util.indexing.IndexStorage;
import com.intellij.util.indexing.MapReduceIndex;
import com.intellij.util.indexing.StorageException;
import com.intellij.util.indexing.*;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.EnumeratorStringDescriptor;
import com.intellij.util.io.KeyDescriptor;
import com.intellij.util.io.PersistentHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -37,12 +36,44 @@ import java.util.Map;
public class StringIndex {
private final MapReduceIndex<String, String, PathContentPair> myIndex;
public StringIndex(final IndexStorage<String, String> storage, final Factory<PersistentHashMap<Integer, Collection<String>>> factory)
public StringIndex(String testName, final IndexStorage<String, String> storage, final PersistentHashMap<Integer, Collection<String>> inputIndex)
throws IOException {
myIndex = new MapReduceIndex<String, String, PathContentPair>(null, new Indexer(), storage);
myIndex.setInputIdToDataKeysIndex(factory);
myIndex = new MapReduceIndex<String, String, PathContentPair>(new IndexExtension<String, String, PathContentPair>() {
@NotNull
@Override
public ID<String, String> getName() {
return new ID<String, String>(testName + "string_index") {};
}
@NotNull
@Override
public DataIndexer<String, String, PathContentPair> getIndexer() {
return new Indexer();
}
@NotNull
@Override
public KeyDescriptor<String> getKeyDescriptor() {
return new EnumeratorStringDescriptor();
}
@NotNull
@Override
public DataExternalizer<String> getValueExternalizer() {
return new EnumeratorStringDescriptor();
}
@Override
public int getVersion() {
return 0;
}
}, storage) {
protected PersistentHashMap<Integer, Collection<String>> createInputsIndex() throws IOException {
return inputIndex;
}
};
}
public List<String> getFilesByWord(@NotNull String word) throws StorageException {
return myIndex.getData(word).toValueList();
}
@@ -18,8 +18,6 @@ package com.intellij.util.indexing;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.KeyDescriptor;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
@@ -30,22 +28,10 @@ import java.util.Collections;
* Date: Dec 26, 2007
* V class MUST have equals / hashcode properly defined!!!
*/
public abstract class FileBasedIndexExtension<K, V> {
public abstract class FileBasedIndexExtension<K, V> extends IndexExtension<K, V, FileContent>{
public static final ExtensionPointName<FileBasedIndexExtension> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.fileBasedIndex");
public static final int DEFAULT_CACHE_SIZE = 1024;
@NotNull
public abstract ID<K, V> getName();
@NotNull
public abstract DataIndexer<K, V, FileContent> getIndexer();
@NotNull
public abstract KeyDescriptor<K> getKeyDescriptor();
@NotNull
public abstract DataExternalizer<V> getValueExternalizer();
@NotNull
public abstract FileBasedIndex.InputFilter getInputFilter();
@@ -55,8 +41,6 @@ public abstract class FileBasedIndexExtension<K, V> {
return false;
}
public abstract int getVersion();
/**
* @see FileBasedIndexExtension#DEFAULT_CACHE_SIZE
*/
@@ -0,0 +1,42 @@
/*
* Copyright 2000-2016 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 com.intellij.util.indexing;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.KeyDescriptor;
import org.jetbrains.annotations.NotNull;
/**
* @author Eugene Zhuravlev
* Date: Dec 26, 2007
* V class MUST have equals / hashcode properly defined!!!
*/
public abstract class IndexExtension<K, V, I> {
@NotNull
public abstract ID<K, V> getName();
@NotNull
public abstract DataIndexer<K, V, I> getIndexer();
@NotNull
public abstract KeyDescriptor<K> getKeyDescriptor();
@NotNull
public abstract DataExternalizer<V> getValueExternalizer();
public abstract int getVersion();
}
@@ -51,6 +51,7 @@ import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.indexing.*;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.DataInputOutputUtil;
import com.intellij.util.io.KeyDescriptor;
import gnu.trove.THashMap;
import gnu.trove.TIntArrayList;
import gnu.trove.TObjectIntHashMap;
@@ -112,17 +113,47 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
for (int attempt = 0; attempt < 2; attempt++) {
try {
StubIdExternalizer externalizer = new StubIdExternalizer();
final MapIndexStorage<K, StubIdList> storage = new MapIndexStorage<K, StubIdList>(
IndexInfrastructure.getStorageFile(indexKey),
extension.getKeyDescriptor(),
new StubIdExternalizer(),
externalizer,
extension.getCacheSize(),
false,
extension instanceof StringStubIndexExtension && ((StringStubIndexExtension)extension).traceKeyHashToVirtualFileMapping()
);
final MemoryIndexStorage<K, StubIdList> memStorage = new MemoryIndexStorage<K, StubIdList>(storage);
myIndices.put(indexKey, new MyIndex<K>(memStorage));
myIndices.put(indexKey, new MyIndex<K>(new IndexExtension<K, StubIdList, Void>() {
@NotNull
@Override
public ID<K, StubIdList> getName() {
return (ID<K, StubIdList>)indexKey;
}
@NotNull
@Override
public DataIndexer<K, StubIdList, Void> getIndexer() {
return inputData -> Collections.emptyMap();
}
@NotNull
@Override
public KeyDescriptor<K> getKeyDescriptor() {
return extension.getKeyDescriptor();
}
@NotNull
@Override
public DataExternalizer<StubIdList> getValueExternalizer() {
return externalizer;
}
@Override
public int getVersion() {
return extension.getVersion();
}
}, memStorage));
break;
}
catch (IOException e) {
@@ -512,8 +543,8 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
}
private static class MyIndex<K> extends MapReduceIndex<K, StubIdList, Void> {
public MyIndex(final IndexStorage<K, StubIdList> storage) throws IOException {
super(null, null, storage);
public MyIndex(IndexExtension<K, StubIdList, Void> extension, IndexStorage<K, StubIdList> storage) throws IOException {
super(extension, storage);
}
@Override
@@ -230,7 +230,8 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi
@NotNull
@Override
public UpdatableIndex<Integer, SerializedStubTree, FileContent> createIndexImplementation(@NotNull final ID<Integer, SerializedStubTree> indexId, @NotNull final FileBasedIndex owner, @NotNull IndexStorage<Integer, SerializedStubTree> storage)
public UpdatableIndex<Integer, SerializedStubTree, FileContent> createIndexImplementation(@NotNull final FileBasedIndexExtension<Integer, SerializedStubTree> extension,
@NotNull IndexStorage<Integer, SerializedStubTree> storage)
throws StorageException, IOException {
if (storage instanceof MemoryIndexStorage) {
final MemoryIndexStorage<Integer, SerializedStubTree> memStorage = (MemoryIndexStorage<Integer, SerializedStubTree>)storage;
@@ -246,7 +247,7 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi
}
});
}
return new MyIndex(indexId, storage, getIndexer());
return new MyIndex(extension, storage);
}
private static void updateStubIndices(@NotNull final Collection<StubIndexKey> indexKeys,
@@ -277,9 +278,9 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi
private static class MyIndex extends MapReduceIndex<Integer, SerializedStubTree, FileContent> {
private StubIndexImpl myStubIndex;
public MyIndex(final ID<Integer, SerializedStubTree> indexId, final IndexStorage<Integer, SerializedStubTree> storage, final DataIndexer<Integer, SerializedStubTree, FileContent> indexer)
public MyIndex(FileBasedIndexExtension<Integer, SerializedStubTree> extension, IndexStorage<Integer, SerializedStubTree> storage)
throws StorageException, IOException {
super(indexId, indexer, storage);
super(extension, storage);
checkNameStorage();
}
@@ -25,6 +25,7 @@ import java.io.IOException;
public abstract class CustomImplementationFileBasedIndexExtension<K, V, I> extends FileBasedIndexExtension<K, V> {
@NotNull
public abstract UpdatableIndex<K, V, I> createIndexImplementation(@NotNull ID<K, V> indexId, @NotNull FileBasedIndex owner, @NotNull IndexStorage<K, V> storage)
public abstract UpdatableIndex<K, V, I> createIndexImplementation(@NotNull FileBasedIndexExtension<K, V> extension,
@NotNull IndexStorage<K, V> storage)
throws StorageException, IOException;
}
@@ -73,8 +73,8 @@ import com.intellij.psi.stubs.SerializationManagerEx;
import com.intellij.util.*;
import com.intellij.util.containers.ConcurrentIntObjectMap;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.io.*;
import com.intellij.util.io.DataOutputStream;
import com.intellij.util.io.IOUtil;
import com.intellij.util.io.storage.HeavyProcessLatch;
import com.intellij.util.messages.MessageBus;
import com.intellij.util.messages.MessageBusConnection;
@@ -536,124 +536,26 @@ public class FileBasedIndexImpl extends FileBasedIndex {
}
@NotNull
private <K, V> UpdatableIndex<K, V, FileContent> createIndex(@NotNull final ID<K, V> indexId,
private static <K, V> UpdatableIndex<K, V, FileContent> createIndex(@NotNull final ID<K, V> indexId,
@NotNull final FileBasedIndexExtension<K, V> extension,
@NotNull final MemoryIndexStorage<K, V> storage)
throws StorageException, IOException {
final MapReduceIndex<K, V, FileContent> index;
if (extension instanceof CustomImplementationFileBasedIndexExtension) {
final UpdatableIndex<K, V, FileContent> custom =
((CustomImplementationFileBasedIndexExtension<K, V, FileContent>)extension).createIndexImplementation(indexId, this, storage);
((CustomImplementationFileBasedIndexExtension<K, V, FileContent>)extension).createIndexImplementation(extension, storage);
if (!(custom instanceof MapReduceIndex)) {
return custom;
}
index = (MapReduceIndex<K, V, FileContent>)custom;
}
else {
DataExternalizer<Collection<K>> externalizer =
extension.hasSnapshotMapping() && IdIndex.ourSnapshotMappingsEnabled
? createInputsIndexExternalizer(extension, indexId, extension.getKeyDescriptor())
: null;
index = new MapReduceIndex<K, V, FileContent>(
indexId, extension.getIndexer(), storage, externalizer, extension.getValueExternalizer(), extension instanceof PsiDependentIndex);
index = new MapReduceIndex<K, V, FileContent>(extension, storage);
}
index.setInputIdToDataKeysIndex(new Factory<PersistentHashMap<Integer, Collection<K>>>() {
@Override
public PersistentHashMap<Integer, Collection<K>> create() {
try {
return createIdToDataKeysIndex(extension, storage);
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
});
return index;
}
@NotNull
public static <K> PersistentHashMap<Integer, Collection<K>> createIdToDataKeysIndex(@NotNull FileBasedIndexExtension <K, ?> extension,
@NotNull MemoryIndexStorage<K, ?> storage)
throws IOException {
ID<K, ?> indexId = extension.getName();
KeyDescriptor<K> keyDescriptor = extension.getKeyDescriptor();
final File indexStorageFile = IndexInfrastructure.getInputIndexStorageFile(indexId);
final AtomicBoolean isBufferingMode = new AtomicBoolean();
final TIntObjectHashMap<Collection<K>> tempMap = new TIntObjectHashMap<Collection<K>>();
// Important! Update IdToDataKeysIndex depending on the sate of "buffering" flag from the MemoryStorage.
// If buffering is on, all changes should be done in memory (similar to the way it is done in memory storage).
// Otherwise data in IdToDataKeysIndex will not be in sync with the 'main' data in the index on disk and index updates will be based on the
// wrong sets of keys for the given file. This will lead to unpredictable results in main index because it will not be
// cleared properly before updating (removed data will still be present on disk). See IDEA-52223 for illustration of possible effects.
final PersistentHashMap<Integer, Collection<K>> map = new PersistentHashMap<Integer, Collection<K>>(
indexStorageFile, EnumeratorIntegerDescriptor.INSTANCE, createInputsIndexExternalizer(extension, indexId, keyDescriptor)
) {
@Override
protected Collection<K> doGet(Integer integer) throws IOException {
if (isBufferingMode.get()) {
final Collection<K> collection = tempMap.get(integer);
if (collection != null) {
return collection;
}
}
return super.doGet(integer);
}
@Override
protected void doPut(Integer integer, @Nullable Collection<K> ks) throws IOException {
if (isBufferingMode.get()) {
tempMap.put(integer, ks == null ? Collections.<K>emptySet() : ks);
}
else {
super.doPut(integer, ks);
}
}
@Override
protected void doRemove(Integer integer) throws IOException {
if (isBufferingMode.get()) {
tempMap.put(integer, Collections.<K>emptySet());
}
else {
super.doRemove(integer);
}
}
};
storage.addBufferingStateListener(new MemoryIndexStorage.BufferingStateListener() {
@Override
public void bufferingStateChanged(boolean newState) {
synchronized (map) {
isBufferingMode.set(newState);
}
}
@Override
public void memoryStorageCleared() {
synchronized (map) {
tempMap.clear();
}
}
});
return map;
}
private static <K> DataExternalizer<Collection<K>> createInputsIndexExternalizer(FileBasedIndexExtension<K, ?> extension,
ID<K, ?> indexId,
KeyDescriptor<K> keyDescriptor) {
DataExternalizer<Collection<K>> externalizer;
if (extension instanceof CustomInputsIndexFileBasedIndexExtension) {
externalizer = ((CustomInputsIndexFileBasedIndexExtension<K>)extension).createExternalizer();
} else {
externalizer = new InputIndexDataExternalizer<K>(keyDescriptor, indexId);
}
return externalizer;
}
@Override
public void disposeComponent() {
performShutdown();
@@ -26,17 +26,20 @@ import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream;
import com.intellij.openapi.util.io.ByteSequence;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.cache.impl.id.IdIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.*;
import com.intellij.util.io.*;
import com.intellij.util.io.DataOutputStream;
import gnu.trove.THashMap;
import gnu.trove.TIntObjectHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.*;
import java.nio.charset.Charset;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -55,6 +58,7 @@ public class MapReduceIndex<Key, Value, Input> implements UpdatableIndex<Key,Val
private final DataExternalizer<Value> myValueExternalizer;
private final DataExternalizer<Collection<Key>> mySnapshotIndexExternalizer;
private final boolean myIsPsiBackedIndex;
private final IndexExtension<Key, Value, Input> myExtension;
private PersistentHashMap<Integer, Collection<Key>> myInputsIndex;
private PersistentHashMap<Integer, ByteSequence> myContents;
@@ -63,8 +67,6 @@ public class MapReduceIndex<Key, Value, Input> implements UpdatableIndex<Key,Val
private final ReentrantReadWriteLock myLock = new ReentrantReadWriteLock();
private Factory<PersistentHashMap<Integer, Collection<Key>>> myInputsIndexFactory;
private final LowMemoryWatcher myLowMemoryFlusher = LowMemoryWatcher.register(new Runnable() {
@Override
public void run() {
@@ -77,28 +79,110 @@ public class MapReduceIndex<Key, Value, Input> implements UpdatableIndex<Key,Val
}
});
public MapReduceIndex(@Nullable final ID<Key, Value> indexId,
DataIndexer<Key, Value, Input> indexer,
public MapReduceIndex(IndexExtension<Key, Value, Input> extension,
@NotNull IndexStorage<Key, Value> storage) throws IOException {
this(indexId, indexer, storage, null, null, false);
myIndexId = extension.getName();
myExtension = extension;
myIndexer = extension.getIndexer();
myStorage = storage;
myHasSnapshotMapping = extension instanceof FileBasedIndexExtension &&
((FileBasedIndexExtension<Key, Value>)extension).hasSnapshotMapping() &&
IdIndex.ourSnapshotMappingsEnabled;
mySnapshotIndexExternalizer = createInputsIndexExternalizer(extension, myIndexId, extension.getKeyDescriptor());
myValueExternalizer = extension.getValueExternalizer();
myContents = createContentsIndex();
myIsPsiBackedIndex = extension instanceof PsiDependentIndex;
if (myHasSnapshotMapping) {
myInputsSnapshotMapping = createInputSnapshotMapping();
}
myInputsIndex = createInputsIndex();
if (DebugAssertions.EXTRA_SANITY_CHECKS && myHasSnapshotMapping && myIndexId != null) {
myIndexingTrace = createIndexingTrace();
}
}
public MapReduceIndex(@Nullable final ID<Key, Value> indexId,
DataIndexer<Key, Value, Input> indexer,
@NotNull IndexStorage<Key, Value> storage,
DataExternalizer<Collection<Key>> snapshotIndexExternalizer,
DataExternalizer<Value> valueDataExternalizer,
boolean psiBasedIndex
) throws IOException {
myIndexId = indexId;
myIndexer = indexer;
myStorage = storage;
myHasSnapshotMapping = snapshotIndexExternalizer != null;
private static <K> DataExternalizer<Collection<K>> createInputsIndexExternalizer(IndexExtension<K, ?, ?> extension,
ID<K, ?> indexId,
KeyDescriptor<K> keyDescriptor) {
DataExternalizer<Collection<K>> externalizer;
if (extension instanceof CustomInputsIndexFileBasedIndexExtension) {
externalizer = ((CustomInputsIndexFileBasedIndexExtension<K>)extension).createExternalizer();
} else {
externalizer = new InputIndexDataExternalizer<K>(keyDescriptor, indexId);
}
return externalizer;
}
mySnapshotIndexExternalizer = snapshotIndexExternalizer;
myValueExternalizer = valueDataExternalizer;
myContents = createContentsIndex();
myIsPsiBackedIndex = psiBasedIndex;
@NotNull
private static <K> PersistentHashMap<Integer, Collection<K>> createIdToDataKeysIndex(@NotNull IndexExtension <K, ?, ?> extension,
@NotNull MemoryIndexStorage<K, ?> storage)
throws IOException {
ID<K, ?> indexId = extension.getName();
KeyDescriptor<K> keyDescriptor = extension.getKeyDescriptor();
final File indexStorageFile = IndexInfrastructure.getInputIndexStorageFile(indexId);
final AtomicBoolean isBufferingMode = new AtomicBoolean();
final TIntObjectHashMap<Collection<K>> tempMap = new TIntObjectHashMap<Collection<K>>();
// Important! Update IdToDataKeysIndex depending on the sate of "buffering" flag from the MemoryStorage.
// If buffering is on, all changes should be done in memory (similar to the way it is done in memory storage).
// Otherwise data in IdToDataKeysIndex will not be in sync with the 'main' data in the index on disk and index updates will be based on the
// wrong sets of keys for the given file. This will lead to unpredictable results in main index because it will not be
// cleared properly before updating (removed data will still be present on disk). See IDEA-52223 for illustration of possible effects.
final PersistentHashMap<Integer, Collection<K>> map = new PersistentHashMap<Integer, Collection<K>>(
indexStorageFile, EnumeratorIntegerDescriptor.INSTANCE, createInputsIndexExternalizer(extension, indexId, keyDescriptor)
) {
@Override
protected Collection<K> doGet(Integer integer) throws IOException {
if (isBufferingMode.get()) {
final Collection<K> collection = tempMap.get(integer);
if (collection != null) {
return collection;
}
}
return super.doGet(integer);
}
@Override
protected void doPut(Integer integer, @Nullable Collection<K> ks) throws IOException {
if (isBufferingMode.get()) {
tempMap.put(integer, ks == null ? Collections.<K>emptySet() : ks);
}
else {
super.doPut(integer, ks);
}
}
@Override
protected void doRemove(Integer integer) throws IOException {
if (isBufferingMode.get()) {
tempMap.put(integer, Collections.<K>emptySet());
}
else {
super.doRemove(integer);
}
}
};
storage.addBufferingStateListener(new MemoryIndexStorage.BufferingStateListener() {
@Override
public void bufferingStateChanged(boolean newState) {
synchronized (map) {
isBufferingMode.set(newState);
}
}
@Override
public void memoryStorageCleared() {
synchronized (map) {
tempMap.clear();
}
}
});
return map;
}
private PersistentHashMap<Integer, ByteSequence> createContentsIndex() throws IOException {
@@ -315,32 +399,8 @@ public class MapReduceIndex<Key, Value, Input> implements UpdatableIndex<Key,Val
}
}
public void setInputIdToDataKeysIndex(Factory<PersistentHashMap<Integer, Collection<Key>>> factory) throws IOException {
myInputsIndexFactory = factory;
if (myHasSnapshotMapping) {
myInputsSnapshotMapping = createInputSnapshotMapping();
}
myInputsIndex = createInputsIndex();
if (DebugAssertions.EXTRA_SANITY_CHECKS && myHasSnapshotMapping && myIndexId != null) {
myIndexingTrace = createIndexingTrace();
}
}
@Nullable
private PersistentHashMap<Integer, Collection<Key>> createInputsIndex() throws IOException {
Factory<PersistentHashMap<Integer, Collection<Key>>> factory = myInputsIndexFactory;
if (factory != null) {
try {
return factory.create();
}
catch (RuntimeException e) {
if (e.getCause() instanceof IOException) {
throw (IOException)e.getCause();
}
throw e;
}
}
return null;
protected PersistentHashMap<Integer, Collection<Key>> createInputsIndex() throws IOException {
return createIdToDataKeysIndex(myExtension, (MemoryIndexStorage<Key, ?>)myStorage);
}
private static final boolean doReadSavedPersistentData = SystemProperties.getBooleanProperty("idea.read.saved.persistent.index", true);